Merge
authorduke
Wed, 05 Jul 2017 21:37:42 +0200
changeset 37624 83e9163184a4
parent 37623 973b1c28c6d2 (current diff)
parent 37622 a522902d465a (diff)
child 37629 69f2ab5bd7a7
Merge
hotspot/src/share/vm/utilities/top.hpp
hotspot/test/stress/gc/TestGCOld.java
hotspot/test/stress/gc/TestMultiThreadStressRSet.java
hotspot/test/stress/gc/TestStressIHOPMultiThread.java
hotspot/test/stress/gc/TestStressRSetCoarsening.java
jdk/src/jdk.jlink/share/classes/jdk/tools/jimage/ExtractedImage.java
jdk/src/jdk.unsupported/share/classes/sun/misc/ManagedLocalsThread.java
jdk/test/java/util/ServiceLoader/modules/BasicTest.java
--- a/.hgtags-top-repo	Thu Apr 21 12:57:17 2016 -0700
+++ b/.hgtags-top-repo	Wed Jul 05 21:37:42 2017 +0200
@@ -357,3 +357,4 @@
 03543a758cd5890f2266e4b9678378a925dde22a jdk-9+112
 55b6d550828d1223b364e6ead4a56e56411c56df jdk-9+113
 1d992540870ff33fe6cc550443388588df9b9e4f jdk-9+114
+09617ce980b99d49abfd54dacfed353c47e2a115 jdk-9+115
--- a/common/autoconf/basics.m4	Thu Apr 21 12:57:17 2016 -0700
+++ b/common/autoconf/basics.m4	Wed Jul 05 21:37:42 2017 +0200
@@ -749,8 +749,8 @@
   BASIC_PREPEND_TO_PATH([PATH],$EXTRA_PATH)
 
   if test "x$OPENJDK_BUILD_OS" = "xsolaris"; then
-    # Add extra search paths on solaris for utilities like ar and as etc...
-    PATH="$PATH:/usr/ccs/bin:/usr/sfw/bin:/opt/csw/bin"
+    # 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])
@@ -777,7 +777,7 @@
     # Create a default ./build/target-variant-debuglevel output root.
     if test "x${CONF_NAME}" = x; then
       AC_MSG_RESULT([in default location])
-      CONF_NAME="${OPENJDK_TARGET_OS}-${OPENJDK_TARGET_CPU}-${JDK_VARIANT}-${ANDED_JVM_VARIANTS}-${DEBUG_LEVEL}"
+      CONF_NAME="${OPENJDK_TARGET_OS}-${OPENJDK_TARGET_CPU}-${JDK_VARIANT}-${JVM_VARIANTS_WITH_AND}-${DEBUG_LEVEL}"
     else
       AC_MSG_RESULT([in build directory with custom name])
     fi
@@ -1037,6 +1037,7 @@
   BASIC_PATH_PROGS(HG, hg)
   BASIC_PATH_PROGS(STAT, stat)
   BASIC_PATH_PROGS(TIME, time)
+  BASIC_PATH_PROGS(DTRACE, dtrace)
   BASIC_PATH_PROGS(PATCH, [gpatch patch])
   # Check if it's GNU time
   IS_GNU_TIME=`$TIME --version 2>&1 | $GREP 'GNU time'`
--- a/common/autoconf/build-performance.m4	Thu Apr 21 12:57:17 2016 -0700
+++ b/common/autoconf/build-performance.m4	Wed Jul 05 21:37:42 2017 +0200
@@ -364,6 +364,9 @@
   elif test "x$ICECC" != "x"; then
     AC_MSG_RESULT([no, does not work effectively with icecc])
     USE_PRECOMPILED_HEADER=0
+  elif test "x$TOOLCHAIN_TYPE" = xsolstudio; then
+    AC_MSG_RESULT([no, does not work with Solaris Studio])
+    USE_PRECOMPILED_HEADER=0
   else
     AC_MSG_RESULT([yes])
   fi
--- a/common/autoconf/buildjdk-spec.gmk.in	Thu Apr 21 12:57:17 2016 -0700
+++ b/common/autoconf/buildjdk-spec.gmk.in	Wed Jul 05 21:37:42 2017 +0200
@@ -57,6 +57,12 @@
 OPENJDK_TARGET_CPU_ENDIAN := @OPENJDK_BUILD_CPU_ENDIAN@
 OPENJDK_TARGET_CPU_LEGACY := @OPENJDK_BUILD_CPU_LEGACY@
 
+HOTSPOT_TARGET_OS := @HOTSPOT_BUILD_OS@
+HOTSPOT_TARGET_OS_TYPE := @HOTSPOT_BUILD_OS_TYPE@
+HOTSPOT_TARGET_CPU := @HOTSPOT_BUILD_CPU@
+HOTSPOT_TARGET_CPU_ARCH := @HOTSPOT_BUILD_CPU_ARCH@
+HOTSPOT_TARGET_CPU_DEFINE := @HOTSPOT_BUILD_CPU_DEFINE@
+
 CFLAGS_JDKLIB := @OPENJDK_BUILD_CFLAGS_JDKLIB@
 CXXFLAGS_JDKLIB := @OPENJDK_BUILD_CXXFLAGS_JDKLIB@
 LDFLAGS_JDKLIB := @OPENJDK_BUILD_LDFLAGS_JDKLIB@
@@ -65,6 +71,11 @@
 LDFLAGS_JDKEXE := @OPENJDK_BUILD_LDFLAGS_JDKEXE@
 OPENJDK_TARGET_CPU_JLI_CFLAGS := @OPENJDK_BUILD_CPU_JLI_CFLAGS@
 
+JVM_CFLAGS := @OPENJDK_BUILD_JVM_CFLAGS@
+JVM_LDFLAGS := @OPENJDK_BUILD_JVM_LDFLAGS@
+JVM_ASFLAGS := @OPENJDK_BUILD_JVM_ASFLAGS@
+JVM_LIBS := @OPENJDK_BUILD_JVM_LIBS@
+
 # The compiler for the build platform is likely not warning compatible with the official
 # compiler.
 WARNINGS_AS_ERRORS := false
--- a/common/autoconf/compare.sh.in	Thu Apr 21 12:57:17 2016 -0700
+++ b/common/autoconf/compare.sh.in	Wed Jul 05 21:37:42 2017 +0200
@@ -31,7 +31,7 @@
 
 export LEGACY_BUILD_DIR=@OPENJDK_TARGET_OS@-@OPENJDK_TARGET_CPU_LEGACY@
 
-export OPENJDK_TARGET_OS="@OPENJDK_TARGET_OS@"
+sexport OPENJDK_TARGET_OS="@OPENJDK_TARGET_OS@"
 export OPENJDK_TARGET_CPU="@OPENJDK_TARGET_CPU@"
 export OPENJDK_TARGET_CPU_LIBDIR="@OPENJDK_TARGET_CPU_LIBDIR@"
 export DEBUG_LEVEL="@DEBUG_LEVEL@"
--- a/common/autoconf/configure	Thu Apr 21 12:57:17 2016 -0700
+++ b/common/autoconf/configure	Wed Jul 05 21:37:42 2017 +0200
@@ -283,7 +283,7 @@
 
 EOT
 
-    # Print additional help, e.g. a list of toolchains.
+    # Print additional help, e.g. a list of toolchains and JVM features.
     # This must be done by the autoconf script.
     ( CONFIGURE_PRINT_ADDITIONAL_HELP=true . $conf_script_to_run PRINTF=printf )
 
--- a/common/autoconf/configure.ac	Thu Apr 21 12:57:17 2016 -0700
+++ b/common/autoconf/configure.ac	Wed Jul 05 21:37:42 2017 +0200
@@ -95,10 +95,8 @@
 
 # These are needed to be able to create a configuration name (and thus the output directory)
 JDKOPT_SETUP_JDK_VARIANT
-HOTSPOT_SETUP_JVM_INTERPRETER
+JDKOPT_SETUP_DEBUG_LEVEL
 HOTSPOT_SETUP_JVM_VARIANTS
-JDKOPT_SETUP_DEBUG_LEVEL
-HOTSPOT_SETUP_DEBUG_LEVEL
 
 # With basic setup done, call the custom early hook.
 CUSTOM_EARLY_HOOK
@@ -135,7 +133,6 @@
 # We need build & target for this.
 JDKOPT_SETUP_JDK_OPTIONS
 JDKOPT_SETUP_JLINK_OPTIONS
-HOTSPOT_SETUP_HOTSPOT_OPTIONS
 JDKVER_SETUP_JDK_VERSION_NUMBERS
 
 ###############################################################################
@@ -207,6 +204,10 @@
 JDKOPT_SETUP_DEBUG_SYMBOLS
 JDKOPT_SETUP_CODE_COVERAGE
 
+# Need toolchain to setup dtrace
+HOTSPOT_SETUP_DTRACE
+HOTSPOT_SETUP_JVM_FEATURES
+
 ###############################################################################
 #
 # Check dependencies for external and internal libraries.
@@ -225,7 +226,7 @@
 #
 ###############################################################################
 
-HOTSPOT_SETUP_BUILD_TWEAKS
+HOTSPOT_SETUP_LEGACY_BUILD
 JDKOPT_DETECT_INTREE_EC
 JDKOPT_ENABLE_DISABLE_FAILURE_HANDLER
 
@@ -268,6 +269,9 @@
 # At the end, call the custom hook. (Dummy macro if no custom sources available)
 CUSTOM_LATE_HOOK
 
+# This needs to be done after CUSTOM_LATE_HOOK since we can setup custom features.
+HOTSPOT_VALIDATE_JVM_FEATURES
+
 # We're messing a bit with internal autoconf variables to put the config.status
 # in the output directory instead of the current directory.
 CONFIG_STATUS="$CONFIGURESUPPORT_OUTPUTDIR/config.status"
--- a/common/autoconf/flags.m4	Thu Apr 21 12:57:17 2016 -0700
+++ b/common/autoconf/flags.m4	Wed Jul 05 21:37:42 2017 +0200
@@ -61,6 +61,10 @@
   AC_SUBST(LEGACY_EXTRA_CXXFLAGS)
   AC_SUBST(LEGACY_EXTRA_LDFLAGS)
 
+  AC_SUBST(EXTRA_CFLAGS)
+  AC_SUBST(EXTRA_CXXFLAGS)
+  AC_SUBST(EXTRA_LDFLAGS)
+
   # The global CFLAGS and LDLAGS variables are used by configure tests and
   # should include the extra parameters
   CFLAGS="$EXTRA_CFLAGS"
@@ -211,8 +215,10 @@
   # On Windows, we need to set RC flags.
   if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
     RC_FLAGS="-nologo -l0x409"
+    JVM_RCFLAGS="-nologo"
     if test "x$DEBUG_LEVEL" = xrelease; then
       RC_FLAGS="$RC_FLAGS -DNDEBUG"
+      JVM_RCFLAGS="$JVM_RCFLAGS -DNDEBUG"
     fi
 
     # The version variables used to create RC_FLAGS may be overridden
@@ -228,8 +234,19 @@
         -D\"JDK_COPYRIGHT=Copyright \xA9 $COPYRIGHT_YEAR\" \
         -D\"JDK_NAME=\$(PRODUCT_NAME) \$(JDK_RC_PLATFORM_NAME) \$(VERSION_MAJOR)\" \
         -D\"JDK_FVER=\$(subst .,\$(COMMA),\$(VERSION_NUMBER_FOUR_POSITIONS))\""
+
+    JVM_RCFLAGS="$JVM_RCFLAGS \
+        -D\"HS_BUILD_ID=\$(VERSION_STRING)\" \
+        -D\"HS_COMPANY=\$(COMPANY_NAME)\" \
+        -D\"JDK_DOTVER=\$(VERSION_NUMBER_FOUR_POSITIONS)\" \
+        -D\"HS_COPYRIGHT=Copyright $COPYRIGHT_YEAR\" \
+        -D\"HS_NAME=\$(PRODUCT_NAME) \$(VERSION_SHORT)\" \
+        -D\"JDK_VER=\$(subst .,\$(COMMA),\$(VERSION_NUMBER_FOUR_POSITIONS))\" \
+        -D\"HS_FNAME=jvm.dll\" \
+        -D\"HS_INTERNAL_NAME=jvm\""
   fi
   AC_SUBST(RC_FLAGS)
+  AC_SUBST(JVM_RCFLAGS)
 
   if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
     # silence copyright notice and other headers.
@@ -237,7 +254,7 @@
   fi
 ])
 
-AC_DEFUN_ONCE([FLAGS_SETUP_COMPILER_FLAGS_FOR_LIBS],
+AC_DEFUN([FLAGS_SETUP_COMPILER_FLAGS_FOR_LIBS],
 [
   ###############################################################################
   #
@@ -255,6 +272,7 @@
         SHARED_LIBRARY_FLAGS ='-undefined dynamic_lookup'
       else
         SHARED_LIBRARY_FLAGS="-dynamiclib -compatibility_version 1.0.0 -current_version 1.0.0 $PICFLAG"
+        JVM_CFLAGS="$JVM_CFLAGS $PICFLAG"
       fi
       SET_EXECUTABLE_ORIGIN='-Wl,-rpath,@loader_path/.'
       SET_SHARED_LIBRARY_ORIGIN="$SET_EXECUTABLE_ORIGIN"
@@ -280,6 +298,10 @@
       SET_SHARED_LIBRARY_ORIGIN="$SET_EXECUTABLE_ORIGIN"
       SET_SHARED_LIBRARY_NAME='-Wl,-install_name,@rpath/[$]1'
       SET_SHARED_LIBRARY_MAPFILE='-Wl,-exported_symbols_list,[$]1'
+
+      if test "x$STATIC_BUILD" = xfalse; then
+        JVM_CFLAGS="$JVM_CFLAGS -fPIC"
+      fi
     else
       # Default works for linux, might work on other platforms as well.
       PICFLAG='-fPIC'
@@ -339,11 +361,6 @@
   AC_SUBST(SET_SHARED_LIBRARY_MAPFILE)
   AC_SUBST(SHARED_LIBRARY_FLAGS)
 
-  if test "x$OPENJDK_TARGET_OS" = xsolaris; then
-    CFLAGS_JDK="${CFLAGS_JDK} -D__solaris__"
-    CXXFLAGS_JDK="${CXXFLAGS_JDK} -D__solaris__"
-    CFLAGS_JDKLIB_EXTRA='-xstrconst'
-  fi
   # The (cross) compiler is now configured, we can now test capabilities
   # of the target platform.
 ])
@@ -434,6 +451,22 @@
   AC_SUBST(CFLAGS_DEBUG_SYMBOLS)
   AC_SUBST(CXXFLAGS_DEBUG_SYMBOLS)
 
+  # Debug symbols for JVM_CFLAGS
+  if test "x$TOOLCHAIN_TYPE" = xsolstudio; then
+    JVM_CFLAGS_SYMBOLS="$JVM_CFLAGS_SYMBOLS -xs"
+    if test "x$DEBUG_LEVEL" = xslowdebug; then
+      JVM_CFLAGS_SYMBOLS="$JVM_CFLAGS_SYMBOLS -g"
+    else
+      # -g0 does not disable inlining, which -g does.
+      JVM_CFLAGS_SYMBOLS="$JVM_CFLAGS_SYMBOLS -g0"
+    fi
+  elif test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
+    JVM_CFLAGS_SYMBOLS="$JVM_CFLAGS_SYMBOLS -Z7 -d2Zi+"
+  else
+    JVM_CFLAGS_SYMBOLS="$JVM_CFLAGS_SYMBOLS -g"
+  fi
+  AC_SUBST(JVM_CFLAGS_SYMBOLS)
+
   # bounds, memory and behavior checking options
   if test "x$TOOLCHAIN_TYPE" = xgcc; then
     case $DEBUG_LEVEL in
@@ -444,7 +477,7 @@
       # no adjustment
       ;;
     slowdebug )
-      # FIXME: By adding this to C(XX)FLAGS_DEBUG_OPTIONS it
+      # FIXME: By adding this to C(XX)FLAGS_DEBUG_OPTIONS/JVM_CFLAGS_SYMBOLS it
       # get's added conditionally on whether we produce debug symbols or not.
       # This is most likely not really correct.
 
@@ -455,40 +488,59 @@
 
       CFLAGS_DEBUG_OPTIONS="$STACK_PROTECTOR_CFLAG --param ssp-buffer-size=1"
       CXXFLAGS_DEBUG_OPTIONS="$STACK_PROTECTOR_CFLAG --param ssp-buffer-size=1"
+      if test "x$STACK_PROTECTOR_CFLAG" != x; then
+        JVM_CFLAGS_SYMBOLS="$JVM_CFLAGS_SYMBOLS $STACK_PROTECTOR_CFLAG --param ssp-buffer-size=1"
+      fi
       ;;
     esac
   fi
 
+  if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
+    if test "x$DEBUG_LEVEL" != xrelease; then
+      if test "x$OPENJDK_TARGET_CPU" = xx86_64; then
+        JVM_CFLAGS="$JVM_CFLAGS -homeparams"
+      fi
+    fi
+  fi
+
   # Optimization levels
   if test "x$TOOLCHAIN_TYPE" = xsolstudio; then
     CC_HIGHEST="$CC_HIGHEST -fns -fsimple -fsingle -xbuiltin=%all -xdepend -xrestrict -xlibmil"
 
     if test "x$OPENJDK_TARGET_CPU_ARCH" = "xx86"; then
       # FIXME: seems we always set -xregs=no%frameptr; put it elsewhere more global?
+      C_O_FLAG_HIGHEST_JVM="-xO4"
       C_O_FLAG_HIGHEST="-xO4 -Wu,-O4~yz $CC_HIGHEST -xalias_level=basic -xregs=no%frameptr"
       C_O_FLAG_HI="-xO4 -Wu,-O4~yz -xregs=no%frameptr"
       C_O_FLAG_NORM="-xO2 -Wu,-O2~yz -xregs=no%frameptr"
       C_O_FLAG_DEBUG="-xregs=no%frameptr"
+      C_O_FLAG_DEBUG_JVM=""
       C_O_FLAG_NONE="-xregs=no%frameptr"
+      CXX_O_FLAG_HIGHEST_JVM="-xO4"
       CXX_O_FLAG_HIGHEST="-xO4 -Qoption ube -O4~yz $CC_HIGHEST -xregs=no%frameptr"
       CXX_O_FLAG_HI="-xO4 -Qoption ube -O4~yz -xregs=no%frameptr"
       CXX_O_FLAG_NORM="-xO2 -Qoption ube -O2~yz -xregs=no%frameptr"
       CXX_O_FLAG_DEBUG="-xregs=no%frameptr"
+      CXX_O_FLAG_DEBUG_JVM=""
       CXX_O_FLAG_NONE="-xregs=no%frameptr"
       if test "x$OPENJDK_TARGET_CPU_BITS" = "x32"; then
         C_O_FLAG_HIGHEST="$C_O_FLAG_HIGHEST -xchip=pentium"
         CXX_O_FLAG_HIGHEST="$CXX_O_FLAG_HIGHEST -xchip=pentium"
       fi
     elif test "x$OPENJDK_TARGET_CPU_ARCH" = "xsparc"; then
+      C_O_FLAG_HIGHEST_JVM="-xO4"
       C_O_FLAG_HIGHEST="-xO4 -Wc,-Qrm-s -Wc,-Qiselect-T0 $CC_HIGHEST -xalias_level=basic -xprefetch=auto,explicit -xchip=ultra"
       C_O_FLAG_HI="-xO4 -Wc,-Qrm-s -Wc,-Qiselect-T0"
       C_O_FLAG_NORM="-xO2 -Wc,-Qrm-s -Wc,-Qiselect-T0"
       C_O_FLAG_DEBUG=""
+      C_O_FLAG_DEBUG_JVM=""
       C_O_FLAG_NONE=""
+      CXX_O_FLAG_HIGHEST_JVM="-xO4"
       CXX_O_FLAG_HIGHEST="-xO4 -Qoption cg -Qrm-s -Qoption cg -Qiselect-T0 $CC_HIGHEST -xprefetch=auto,explicit -xchip=ultra"
       CXX_O_FLAG_HI="-xO4 -Qoption cg -Qrm-s -Qoption cg -Qiselect-T0"
       CXX_O_FLAG_NORM="-xO2 -Qoption cg -Qrm-s -Qoption cg -Qiselect-T0"
       CXX_O_FLAG_DEBUG=""
+      CXX_O_FLAG_DEBUG_JVM=""
       CXX_O_FLAG_NONE=""
     fi
   else
@@ -498,48 +550,75 @@
       if test "x$OPENJDK_TARGET_OS" = xmacosx; then
         # On MacOSX we optimize for size, something
         # we should do for all platforms?
+        C_O_FLAG_HIGHEST_JVM="-Os"
         C_O_FLAG_HIGHEST="-Os"
         C_O_FLAG_HI="-Os"
         C_O_FLAG_NORM="-Os"
+        C_O_FLAG_SIZE="-Os"
       else
+        C_O_FLAG_HIGHEST_JVM="-O3"
         C_O_FLAG_HIGHEST="-O3"
         C_O_FLAG_HI="-O3"
         C_O_FLAG_NORM="-O2"
+        C_O_FLAG_SIZE="-Os"
       fi
       C_O_FLAG_DEBUG="-O0"
+      if test "x$OPENJDK_TARGET_OS" = xmacosx; then
+        C_O_FLAG_DEBUG_JVM=""
+      elif test "x$OPENJDK_TARGET_OS" = xlinux; then
+        C_O_FLAG_DEBUG_JVM="-O0"
+      fi
       C_O_FLAG_NONE="-O0"
     elif test "x$TOOLCHAIN_TYPE" = xclang; then
       if test "x$OPENJDK_TARGET_OS" = xmacosx; then
         # On MacOSX we optimize for size, something
         # we should do for all platforms?
+        C_O_FLAG_HIGHEST_JVM="-Os"
         C_O_FLAG_HIGHEST="-Os"
         C_O_FLAG_HI="-Os"
         C_O_FLAG_NORM="-Os"
+        C_O_FLAG_SIZE="-Os"
       else
+        C_O_FLAG_HIGHEST_JVM="-O3"
         C_O_FLAG_HIGHEST="-O3"
         C_O_FLAG_HI="-O3"
         C_O_FLAG_NORM="-O2"
+        C_O_FLAG_SIZE="-Os"
       fi
       C_O_FLAG_DEBUG="-O0"
+      if test "x$OPENJDK_TARGET_OS" = xmacosx; then
+        C_O_FLAG_DEBUG_JVM=""
+      elif test "x$OPENJDK_TARGET_OS" = xlinux; then
+        C_O_FLAG_DEBUG_JVM="-O0"
+      fi
       C_O_FLAG_NONE="-O0"
     elif test "x$TOOLCHAIN_TYPE" = xxlc; then
+      C_O_FLAG_HIGHEST_JVM="-O3"
       C_O_FLAG_HIGHEST="-O3"
       C_O_FLAG_HI="-O3 -qstrict"
       C_O_FLAG_NORM="-O2"
       C_O_FLAG_DEBUG="-qnoopt"
+      # FIXME: Value below not verified.
+      C_O_FLAG_DEBUG_JVM=""
       C_O_FLAG_NONE="-qnoopt"
     elif test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
+      C_O_FLAG_HIGHEST_JVM="-O2 -Oy-"
       C_O_FLAG_HIGHEST="-O2"
       C_O_FLAG_HI="-O1"
       C_O_FLAG_NORM="-O1"
       C_O_FLAG_DEBUG="-Od"
+      C_O_FLAG_DEBUG_JVM=""
       C_O_FLAG_NONE="-Od"
+      C_O_FLAG_SIZE="-Os"
     fi
+    CXX_O_FLAG_HIGHEST_JVM="$C_O_FLAG_HIGHEST_JVM"
     CXX_O_FLAG_HIGHEST="$C_O_FLAG_HIGHEST"
     CXX_O_FLAG_HI="$C_O_FLAG_HI"
     CXX_O_FLAG_NORM="$C_O_FLAG_NORM"
     CXX_O_FLAG_DEBUG="$C_O_FLAG_DEBUG"
+    CXX_O_FLAG_DEBUG_JVM="$C_O_FLAG_DEBUG_JVM"
     CXX_O_FLAG_NONE="$C_O_FLAG_NONE"
+    CXX_O_FLAG_SIZE="$C_O_FLAG_SIZE"
   fi
 
   # Adjust optimization flags according to debug level.
@@ -554,51 +633,105 @@
       ;;
     slowdebug )
       # Disable optimization
+      C_O_FLAG_HIGHEST_JVM="$C_O_FLAG_DEBUG_JVM"
       C_O_FLAG_HIGHEST="$C_O_FLAG_DEBUG"
       C_O_FLAG_HI="$C_O_FLAG_DEBUG"
       C_O_FLAG_NORM="$C_O_FLAG_DEBUG"
+      C_O_FLAG_SIZE="$C_O_FLAG_DEBUG"
+      CXX_O_FLAG_HIGHEST_JVM="$CXX_O_FLAG_DEBUG_JVM"
       CXX_O_FLAG_HIGHEST="$CXX_O_FLAG_DEBUG"
       CXX_O_FLAG_HI="$CXX_O_FLAG_DEBUG"
       CXX_O_FLAG_NORM="$CXX_O_FLAG_DEBUG"
+      CXX_O_FLAG_SIZE="$CXX_O_FLAG_DEBUG"
       ;;
   esac
 
+  AC_SUBST(C_O_FLAG_HIGHEST_JVM)
   AC_SUBST(C_O_FLAG_HIGHEST)
   AC_SUBST(C_O_FLAG_HI)
   AC_SUBST(C_O_FLAG_NORM)
   AC_SUBST(C_O_FLAG_DEBUG)
   AC_SUBST(C_O_FLAG_NONE)
+  AC_SUBST(C_O_FLAG_SIZE)
+  AC_SUBST(CXX_O_FLAG_HIGHEST_JVM)
   AC_SUBST(CXX_O_FLAG_HIGHEST)
   AC_SUBST(CXX_O_FLAG_HI)
   AC_SUBST(CXX_O_FLAG_NORM)
   AC_SUBST(CXX_O_FLAG_DEBUG)
   AC_SUBST(CXX_O_FLAG_NONE)
+  AC_SUBST(CXX_O_FLAG_SIZE)
 ])
 
-AC_DEFUN_ONCE([FLAGS_SETUP_COMPILER_FLAGS_FOR_JDK],
+
+AC_DEFUN([FLAGS_SETUP_COMPILER_FLAGS_FOR_JDK],
+[
+
+  FLAGS_SETUP_COMPILER_FLAGS_FOR_JDK_HELPER([TARGET])
+  FLAGS_SETUP_COMPILER_FLAGS_FOR_JDK_HELPER([BUILD], [OPENJDK_BUILD_])
+
+  # Tests are only ever compiled for TARGET
+  # Flags for compiling test libraries
+  CFLAGS_TESTLIB="$COMMON_CCXXFLAGS_JDK $CFLAGS_JDK $PICFLAG $CFLAGS_JDKLIB_EXTRA"
+  CXXFLAGS_TESTLIB="$COMMON_CCXXFLAGS_JDK $CXXFLAGS_JDK $PICFLAG $CXXFLAGS_JDKLIB_EXTRA"
+
+  # Flags for compiling test executables
+  CFLAGS_TESTEXE="$COMMON_CCXXFLAGS_JDK $CFLAGS_JDK"
+  CXXFLAGS_TESTEXE="$COMMON_CCXXFLAGS_JDK $CXXFLAGS_JDK"
+
+  AC_SUBST(CFLAGS_TESTLIB)
+  AC_SUBST(CFLAGS_TESTEXE)
+  AC_SUBST(CXXFLAGS_TESTLIB)
+  AC_SUBST(CXXFLAGS_TESTEXE)
+
+  LDFLAGS_TESTLIB="$LDFLAGS_JDKLIB"
+  LDFLAGS_TESTEXE="$LDFLAGS_JDKEXE"
+
+  AC_SUBST(LDFLAGS_TESTLIB)
+  AC_SUBST(LDFLAGS_TESTEXE)
+
+])
+
+################################################################################
+# $1 - Either BUILD or TARGET to pick the correct OS/CPU variables to check
+#      conditionals against.
+# $2 - Optional prefix for each variable defined.
+AC_DEFUN([FLAGS_SETUP_COMPILER_FLAGS_FOR_JDK_HELPER],
 [
   # Special extras...
   if test "x$TOOLCHAIN_TYPE" = xsolstudio; then
-    if test "x$OPENJDK_TARGET_CPU_ARCH" = "xsparc"; then
-      CFLAGS_JDKLIB_EXTRA="${CFLAGS_JDKLIB_EXTRA} -xregs=no%appl"
-      CXXFLAGS_JDKLIB_EXTRA="${CXXFLAGS_JDKLIB_EXTRA} -xregs=no%appl"
+    if test "x$OPENJDK_$1_CPU_ARCH" = "xsparc"; then
+      $2CFLAGS_JDKLIB_EXTRA="${$2CFLAGS_JDKLIB_EXTRA} -xregs=no%appl"
+      $2CXXFLAGS_JDKLIB_EXTRA="${$2CXXFLAGS_JDKLIB_EXTRA} -xregs=no%appl"
     fi
-    CFLAGS_JDKLIB_EXTRA="${CFLAGS_JDKLIB_EXTRA} -errtags=yes -errfmt"
-    CXXFLAGS_JDKLIB_EXTRA="${CXXFLAGS_JDKLIB_EXTRA} -errtags=yes -errfmt"
+    $2CFLAGS_JDKLIB_EXTRA="${$2CFLAGS_JDKLIB_EXTRA} -errtags=yes -errfmt"
+    $2CXXFLAGS_JDKLIB_EXTRA="${$2CXXFLAGS_JDKLIB_EXTRA} -errtags=yes -errfmt"
   elif test "x$TOOLCHAIN_TYPE" = xxlc; then
+    $2CFLAGS_JDK="${$2CFLAGS_JDK} -qchars=signed -qfullpath -qsaveopt"
+    $2CXXFLAGS_JDK="${$2CXXFLAGS_JDK} -qchars=signed -qfullpath -qsaveopt"
+  elif test "x$TOOLCHAIN_TYPE" = xgcc; then
+    $2CXXSTD_CXXFLAG="-std=gnu++98"
+    FLAGS_CXX_COMPILER_CHECK_ARGUMENTS(ARGUMENT: [[$]$2CXXSTD_CXXFLAG -Werror],
+    						 IF_FALSE: [$2CXXSTD_CXXFLAG=""])
+    $2CXXFLAGS_JDK="${$2CXXFLAGS_JDK} ${$2CXXSTD_CXXFLAG}"
+    AC_SUBST([$2CXXSTD_CXXFLAG])
+  fi
+  if test "x$OPENJDK_TARGET_OS" = xsolaris; then
+    $2CFLAGS_JDK="${$2CFLAGS_JDK} -D__solaris__"
+    $2CXXFLAGS_JDK="${$2CXXFLAGS_JDK} -D__solaris__"
+    $2CFLAGS_JDKLIB_EXTRA='-xstrconst'
     CFLAGS_JDK="${CFLAGS_JDK} -qchars=signed -qfullpath -qsaveopt"
     CXXFLAGS_JDK="${CXXFLAGS_JDK} -qchars=signed -qfullpath -qsaveopt"
-  elif test "x$TOOLCHAIN_TYPE" = xgcc; then
-    CXXSTD_CXXFLAG="-std=gnu++98"
-    FLAGS_CXX_COMPILER_CHECK_ARGUMENTS(ARGUMENT: [$CXXSTD_CXXFLAG -Werror],
-    						 IF_FALSE: [CXXSTD_CXXFLAG=""])
-    CXXFLAGS_JDK="${CXXFLAGS_JDK} ${CXXSTD_CXXFLAG}"
-    AC_SUBST([CXXSTD_CXXFLAG])
   fi
 
-  CFLAGS_JDK="${CFLAGS_JDK} $EXTRA_CFLAGS"
-  CXXFLAGS_JDK="${CXXFLAGS_JDK} $EXTRA_CXXFLAGS"
-  LDFLAGS_JDK="${LDFLAGS_JDK} $EXTRA_LDFLAGS"
+  if test "x$OPENJDK_TARGET_OS" = xsolaris; then
+    $2CFLAGS_JDK="${$2CFLAGS_JDK} -D__solaris__"
+    $2CXXFLAGS_JDK="${$2CXXFLAGS_JDK} -D__solaris__"
+    $2CFLAGS_JDKLIB_EXTRA='-xstrconst'
+  fi
+
+  $2CFLAGS_JDK="${$2CFLAGS_JDK} ${$2EXTRA_CFLAGS}"
+  $2CXXFLAGS_JDK="${$2CXXFLAGS_JDK} ${$2EXTRA_CXXFLAGS}"
+  $2LDFLAGS_JDK="${$2LDFLAGS_JDK} ${$2EXTRA_LDFLAGS}"
 
   ###############################################################################
   #
@@ -607,79 +740,94 @@
   #
 
   # Setup compiler/platform specific flags into
-  #    CFLAGS_JDK    - C Compiler flags
-  #    CXXFLAGS_JDK  - C++ Compiler flags
-  #    COMMON_CCXXFLAGS_JDK - common to C and C++
+  #    $2CFLAGS_JDK    - C Compiler flags
+  #    $2CXXFLAGS_JDK  - C++ Compiler flags
+  #    $2COMMON_CCXXFLAGS_JDK - common to C and C++
   if test "x$TOOLCHAIN_TYPE" = xgcc; then
-    if test "x$OPENJDK_TARGET_CPU" = xx86; then
+    $2JVM_CFLAGS="[$]$2JVM_CFLAGS -D_GNU_SOURCE"
+    $2JVM_CFLAGS="[$]$2JVM_CFLAGS -D_REENTRANT"
+    $2JVM_CFLAGS="[$]$2JVM_CFLAGS -fcheck-new"
+    if test "x$OPENJDK_$1_CPU" = xx86; then
       # Force compatibility with i586 on 32 bit intel platforms.
-      COMMON_CCXXFLAGS="${COMMON_CCXXFLAGS} -march=i586"
+      $2COMMON_CCXXFLAGS="${$2COMMON_CCXXFLAGS} -march=i586"
+      $2JVM_CFLAGS="[$]$2JVM_CFLAGS -march=i586"
     fi
-    COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS $COMMON_CCXXFLAGS_JDK -Wall -Wextra -Wno-unused -Wno-unused-parameter -Wformat=2 \
+    $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS [$]$2COMMON_CCXXFLAGS_JDK -Wall -Wextra -Wno-unused -Wno-unused-parameter -Wformat=2 \
         -pipe -D_GNU_SOURCE -D_REENTRANT -D_LARGEFILE64_SOURCE"
-    case $OPENJDK_TARGET_CPU_ARCH in
+    case $OPENJDK_$1_CPU_ARCH in
       arm )
         # on arm we don't prevent gcc to omit frame pointer but do prevent strict aliasing
-        CFLAGS_JDK="${CFLAGS_JDK} -fno-strict-aliasing"
+        $2CFLAGS_JDK="${$2CFLAGS_JDK} -fno-strict-aliasing"
         ;;
       ppc )
         # on ppc we don't prevent gcc to omit frame pointer but do prevent strict aliasing
-        CFLAGS_JDK="${CFLAGS_JDK} -fno-strict-aliasing"
+        $2CFLAGS_JDK="${$2CFLAGS_JDK} -fno-strict-aliasing"
         ;;
       * )
-        COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -fno-omit-frame-pointer"
-        CFLAGS_JDK="${CFLAGS_JDK} -fno-strict-aliasing"
+        $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK -fno-omit-frame-pointer"
+        $2CFLAGS_JDK="${$2CFLAGS_JDK} -fno-strict-aliasing"
         ;;
     esac
     TOOLCHAIN_CHECK_COMPILER_VERSION(VERSION: 6, IF_AT_LEAST: FLAGS_SETUP_GCC6_COMPILER_FLAGS)
   elif test "x$TOOLCHAIN_TYPE" = xclang; then
-    if test "x$OPENJDK_TARGET_OS" = xlinux; then
-      if test "x$OPENJDK_TARGET_CPU" = xx86; then
+    $2JVM_CFLAGS="[$]$2JVM_CFLAGS -D_GNU_SOURCE"
+
+    # Restrict the debug information created by Clang to avoid
+    # too big object files and speed the build up a little bit
+    # (see http://llvm.org/bugs/show_bug.cgi?id=7554)
+    $2JVM_CFLAGS="[$]$2JVM_CFLAGS -flimit-debug-info"
+    if test "x$OPENJDK_$1_OS" = xlinux; then
+      if test "x$OPENJDK_$1_CPU" = xx86; then
         # Force compatibility with i586 on 32 bit intel platforms.
-        COMMON_CCXXFLAGS="${COMMON_CCXXFLAGS} -march=i586"
+        $2COMMON_CCXXFLAGS="${$2COMMON_CCXXFLAGS} -march=i586"
+        $2JVM_CFLAGS="[$]$2JVM_CFLAGS -march=i586"
       fi
-      COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS $COMMON_CCXXFLAGS_JDK -Wall -Wextra -Wno-unused -Wno-unused-parameter -Wformat=2 \
+      $2JVM_CFLAGS="[$]$2JVM_CFLAGS -Wno-sometimes-uninitialized"
+      $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS [$]$2COMMON_CCXXFLAGS_JDK -Wall -Wextra -Wno-unused -Wno-unused-parameter -Wformat=2 \
           -pipe -D_GNU_SOURCE -D_REENTRANT -D_LARGEFILE64_SOURCE"
-      case $OPENJDK_TARGET_CPU_ARCH in
+      case $OPENJDK_$1_CPU_ARCH in
         ppc )
           # on ppc we don't prevent gcc to omit frame pointer but do prevent strict aliasing
-          CFLAGS_JDK="${CFLAGS_JDK} -fno-strict-aliasing"
+          $2CFLAGS_JDK="${$2CFLAGS_JDK} -fno-strict-aliasing"
           ;;
         * )
-          COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -fno-omit-frame-pointer"
-          CFLAGS_JDK="${CFLAGS_JDK} -fno-strict-aliasing"
+          $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK -fno-omit-frame-pointer"
+          $2CFLAGS_JDK="${$2CFLAGS_JDK} -fno-strict-aliasing"
           ;;
       esac
     fi
   elif test "x$TOOLCHAIN_TYPE" = xsolstudio; then
-    COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS $COMMON_CCXXFLAGS_JDK -DTRACING -DMACRO_MEMSYS_OPS -DBREAKPTS"
-    if test "x$OPENJDK_TARGET_CPU_ARCH" = xx86; then
-      COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -DcpuIntel -Di586 -D$OPENJDK_TARGET_CPU_LEGACY_LIB"
+    $2JVM_CFLAGS="[$]$2JVM_CFLAGS -DSPARC_WORKS"
+    $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS [$]$2COMMON_CCXXFLAGS_JDK -DTRACING -DMACRO_MEMSYS_OPS -DBREAKPTS"
+    if test "x$OPENJDK_$1_CPU_ARCH" = xx86; then
+      $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK -DcpuIntel -Di586 -D$OPENJDK_$1_CPU_LEGACY_LIB"
     fi
 
-    CFLAGS_JDK="$CFLAGS_JDK -xc99=%none -xCC -errshort=tags -Xa -v -mt -W0,-noglobal"
-    CXXFLAGS_JDK="$CXXFLAGS_JDK -errtags=yes +w -mt -features=no%except -DCC_NOEX -norunpath -xnolib"
+    $2CFLAGS_JDK="[$]$2CFLAGS_JDK -xc99=%none -xCC -errshort=tags -Xa -v -mt -W0,-noglobal"
+    $2CXXFLAGS_JDK="[$]$2CXXFLAGS_JDK -errtags=yes +w -mt -features=no%except -DCC_NOEX -norunpath -xnolib"
   elif test "x$TOOLCHAIN_TYPE" = xxlc; then
-    CFLAGS_JDK="$CFLAGS_JDK -D_GNU_SOURCE -D_REENTRANT -D_LARGEFILE64_SOURCE -DSTDC"
-    CXXFLAGS_JDK="$CXXFLAGS_JDK -D_GNU_SOURCE -D_REENTRANT -D_LARGEFILE64_SOURCE -DSTDC"
+    $2JVM_CFLAGS="[$]$2JVM_CFLAGS -D_REENTRANT -D__STDC_FORMAT_MACROS"
+    $2CFLAGS_JDK="[$]$2CFLAGS_JDK -D_GNU_SOURCE -D_REENTRANT -D_LARGEFILE64_SOURCE -DSTDC"
+    $2CXXFLAGS_JDK="[$]$2CXXFLAGS_JDK -D_GNU_SOURCE -D_REENTRANT -D_LARGEFILE64_SOURCE -DSTDC"
   elif test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
-    COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS $COMMON_CCXXFLAGS_JDK \
+    $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS [$]$2COMMON_CCXXFLAGS_JDK \
         -MD -Zc:wchar_t- -W3 -wd4800 \
         -DWIN32_LEAN_AND_MEAN \
         -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE \
         -D_WINSOCK_DEPRECATED_NO_WARNINGS \
         -DWIN32 -DIAL"
-    if test "x$OPENJDK_TARGET_CPU" = xx86_64; then
-      COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -D_AMD64_ -Damd64"
+    if test "x$OPENJDK_$1_CPU" = xx86_64; then
+      $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK -D_AMD64_ -Damd64"
     else
-      COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -D_X86_ -Dx86"
+      $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK -D_X86_ -Dx86"
     fi
     # If building with Visual Studio 2010, we can still use _STATIC_CPPLIB to
     # avoid bundling msvcpNNN.dll. Doesn't work with newer versions of visual
     # studio.
     if test "x$TOOLCHAIN_VERSION" = "x2010"; then
       STATIC_CPPLIB_FLAGS="-D_STATIC_CPPLIB -D_DISABLE_DEPRECATE_STATIC_CPPLIB"
-      COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK $STATIC_CPPLIB_FLAGS"
+      $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK $STATIC_CPPLIB_FLAGS"
+      $2JVM_CFLAGS="[$]$2JVM_CFLAGS $STATIC_CPPLIB_FLAGS"
     fi
   fi
 
@@ -688,8 +836,8 @@
   # Adjust flags according to debug level.
   case $DEBUG_LEVEL in
     fastdebug | slowdebug )
-      CFLAGS_JDK="$CFLAGS_JDK $CFLAGS_DEBUG_SYMBOLS $CFLAGS_DEBUG_OPTIONS"
-      CXXFLAGS_JDK="$CXXFLAGS_JDK $CXXFLAGS_DEBUG_SYMBOLS $CXXFLAGS_DEBUG_OPTIONS"
+      $2CFLAGS_JDK="[$]$2CFLAGS_JDK $CFLAGS_DEBUG_SYMBOLS $CFLAGS_DEBUG_OPTIONS"
+      $2CXXFLAGS_JDK="[$]$2CXXFLAGS_JDK $CXXFLAGS_DEBUG_SYMBOLS $CXXFLAGS_DEBUG_OPTIONS"
       JAVAC_FLAGS="$JAVAC_FLAGS -g"
       ;;
     release )
@@ -703,58 +851,142 @@
   # -D is universally accepted.
 
   # Setup endianness
-  if test "x$OPENJDK_TARGET_CPU_ENDIAN" = xlittle; then
+  if test "x$OPENJDK_$1_CPU_ENDIAN" = xlittle; then
     # The macro _LITTLE_ENDIAN needs to be defined the same to avoid the
     #   Sun C compiler warning message: warning: macro redefined: _LITTLE_ENDIAN
     #   (The Solaris X86 system defines this in file /usr/include/sys/isa_defs.h).
     #   Note: -Dmacro         is the same as    #define macro 1
     #         -Dmacro=        is the same as    #define macro
-    if test "x$OPENJDK_TARGET_OS" = xsolaris; then
-      COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -D_LITTLE_ENDIAN="
+    if test "x$OPENJDK_$1_OS" = xsolaris; then
+      $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK -D_LITTLE_ENDIAN="
     else
-      COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -D_LITTLE_ENDIAN"
+      $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK -D_LITTLE_ENDIAN"
     fi
   else
     # Same goes for _BIG_ENDIAN. Do we really need to set *ENDIAN on Solaris if they
     # are defined in the system?
-    if test "x$OPENJDK_TARGET_OS" = xsolaris; then
-      COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -D_BIG_ENDIAN="
+    if test "x$OPENJDK_$1_OS" = xsolaris; then
+      $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK -D_BIG_ENDIAN="
     else
-      COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -D_BIG_ENDIAN"
+      $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK -D_BIG_ENDIAN"
     fi
   fi
 
   # Setup target OS define. Use OS target name but in upper case.
-  OPENJDK_TARGET_OS_UPPERCASE=`$ECHO $OPENJDK_TARGET_OS | $TR 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
-  COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -D$OPENJDK_TARGET_OS_UPPERCASE"
+  OPENJDK_$1_OS_UPPERCASE=`$ECHO $OPENJDK_$1_OS | $TR 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+  $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK -D$OPENJDK_$1_OS_UPPERCASE"
 
   # Setup target CPU
-  OPENJDK_TARGET_CCXXFLAGS_JDK="$OPENJDK_TARGET_CCXXFLAGS_JDK \
-      $ADD_LP64 \
-      -DARCH='\"$OPENJDK_TARGET_CPU_LEGACY\"' -D$OPENJDK_TARGET_CPU_LEGACY"
-  OPENJDK_BUILD_CCXXFLAGS_JDK="$OPENJDK_BUILD_CCXXFLAGS_JDK \
-      $OPENJDK_BUILD_ADD_LP64 \
-      -DARCH='\"$OPENJDK_BUILD_CPU_LEGACY\"' -D$OPENJDK_BUILD_CPU_LEGACY"
+  $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK \
+      $OPENJDK_$1_ADD_LP64 \
+      -DARCH='\"$OPENJDK_$1_CPU_LEGACY\"' -D$OPENJDK_$1_CPU_LEGACY"
 
   # Setup debug/release defines
   if test "x$DEBUG_LEVEL" = xrelease; then
-    COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -DNDEBUG"
-    if test "x$OPENJDK_TARGET_OS" = xsolaris; then
-      COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -DTRIMMED"
+    $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK -DNDEBUG"
+    if test "x$OPENJDK_$1_OS" = xsolaris; then
+      $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK -DTRIMMED"
     fi
   else
-    COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -DDEBUG"
+    $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK -DDEBUG"
   fi
 
   # Set some additional per-OS defines.
-  if test "x$OPENJDK_TARGET_OS" = xmacosx; then
-    COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -D_ALLBSD_SOURCE -D_DARWIN_UNLIMITED_SELECT"
-  elif test "x$OPENJDK_TARGET_OS" = xbsd; then
-    COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -D_ALLBSD_SOURCE"
+  if test "x$OPENJDK_$1_OS" = xlinux; then
+    $2JVM_CFLAGS="[$]$2JVM_CFLAGS -DLINUX"
+    $2JVM_CFLAGS="[$]$2JVM_CFLAGS -pipe -fPIC -fno-rtti -fno-exceptions \
+        -fvisibility=hidden -fno-strict-aliasing -fno-omit-frame-pointer"
+  elif test "x$OPENJDK_$1_OS" = xsolaris; then
+    $2JVM_CFLAGS="[$]$2JVM_CFLAGS -DSOLARIS"
+    $2JVM_CFLAGS="[$]$2JVM_CFLAGS -template=no%extdef -features=no%split_init \
+        -D_Crun_inline_placement -library=%none -KPIC -mt -xwe -features=no%except"
+  elif test "x$OPENJDK_$1_OS" = xmacosx; then
+    $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK -D_ALLBSD_SOURCE -D_DARWIN_UNLIMITED_SELECT"
+    $2JVM_CFLAGS="[$]$2JVM_CFLAGS -D_ALLBSD_SOURCE"
+    $2JVM_CFLAGS="[$]$2JVM_CFLAGS -D_DARWIN_C_SOURCE -D_XOPEN_SOURCE"
+    $2JVM_CFLAGS="[$]$2JVM_CFLAGS -fno-rtti -fno-exceptions -fvisibility=hidden \
+        -mno-omit-leaf-frame-pointer -mstack-alignment=16 -pipe -fno-strict-aliasing \
+        -DMAC_OS_X_VERSION_MAX_ALLOWED=1070 -mmacosx-version-min=10.7.0 \
+        -fno-omit-frame-pointer"
+  elif test "x$OPENJDK_$1_OS" = xaix; then
+    $2JVM_CFLAGS="[$]$2JVM_CFLAGS -DAIX"
+    # We may need '-qminimaltoc' or '-qpic=large -bbigtoc' if the TOC overflows.
+    $2JVM_CFLAGS="[$]$2JVM_CFLAGS -qtune=balanced -qhot=level=1 -qinline \
+        -qinlglue -qalias=noansi -qstrict -qtls=default -qlanglvl=c99vla \
+        -qlanglvl=noredefmac -qnortti -qnoeh -qignerrno"
+  elif test "x$OPENJDK_$1_OS" = xbsd; then
+    $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK -D_ALLBSD_SOURCE"
+  elif test "x$OPENJDK_$1_OS" = xwindows; then
+    $2JVM_CFLAGS="[$]$2JVM_CFLAGS -D_WINDOWS -DWIN32 -D_JNI_IMPLEMENTATION_"
+    $2JVM_CFLAGS="[$]$2JVM_CFLAGS -nologo -W3 -MD -MP"
+  fi
+
+  # Set some additional per-CPU defines.
+  if test "x$OPENJDK_$1_OS-$OPENJDK_$1_CPU" = xwindows-x86; then
+    $2JVM_CFLAGS="[$]$2JVM_CFLAGS -arch:IA32"
+  elif test "x$OPENJDK_$1_CPU" = xsparcv9; then
+    $2JVM_CFLAGS="[$]$2JVM_CFLAGS -xarch=sparc"
+  elif test "x$OPENJDK_$1_CPU" = xppc64; then
+    if test "x$OPENJDK_$1_OS" = xlinux; then
+      $2JVM_CFLAGS="[$]$2JVM_CFLAGS -minsert-sched-nops=regroup_exact -mno-multiple -mno-string"
+      # fixes `relocation truncated to fit' error for gcc 4.1.
+      $2JVM_CFLAGS="[$]$2JVM_CFLAGS -mminimal-toc"
+      # Use ppc64 instructions, but schedule for power5
+      $2JVM_CFLAGS="[$]$2JVM_CFLAGS -mcpu=powerpc64 -mtune=power5"
+    elif test "x$OPENJDK_$1_OS" = xaix; then
+      $2JVM_CFLAGS="[$]$2JVM_CFLAGS -qarch=ppc64"
+    fi
+  elif test "x$OPENJDK_$1_CPU" = xppc64le; then
+    if test "x$OPENJDK_$1_OS" = xlinux; then
+      $2JVM_CFLAGS="[$]$2JVM_CFLAGS -minsert-sched-nops=regroup_exact -mno-multiple -mno-string"
+      # Little endian machine uses ELFv2 ABI.
+      $2JVM_CFLAGS="[$]$2JVM_CFLAGS -DABI_ELFv2"
+      # Use Power8, this is the first CPU to support PPC64 LE with ELFv2 ABI.
+      $2JVM_CFLAGS="[$]$2JVM_CFLAGS -mcpu=power7 -mtune=power8"
+    fi
+  fi
+
+  if test "x$OPENJDK_$1_CPU_ENDIAN" = xlittle; then
+    $2JVM_CFLAGS="[$]$2JVM_CFLAGS -DVM_LITTLE_ENDIAN"
+  fi
+
+  if test "x$OPENJDK_$1_CPU_BITS" = x64; then
+    if test "x$OPENJDK_$1_OS" != xsolaris && test "x$OPENJDK_$1_OS" != xaix; then
+      # Solaris does not have _LP64=1 in the old build.
+      # xlc on AIX defines _LP64=1 by default and issues a warning if we redefine it.
+      $2JVM_CFLAGS="[$]$2JVM_CFLAGS -D_LP64=1"
+    fi
+  fi
+
+  # Set $2JVM_CFLAGS warning handling
+  if test "x$OPENJDK_$1_OS" = xlinux; then
+    $2JVM_CFLAGS="[$]$2JVM_CFLAGS -Wpointer-arith -Wsign-compare -Wunused-function \
+        -Wunused-value -Woverloaded-virtual"
+
+    if test "x$TOOLCHAIN_TYPE" = xgcc; then
+      TOOLCHAIN_CHECK_COMPILER_VERSION(VERSION: [4.8],
+          IF_AT_LEAST: [
+            # These flags either do not work or give spurious warnings prior to gcc 4.8.
+            $2JVM_CFLAGS="[$]$2JVM_CFLAGS -Wno-format-zero-length -Wtype-limits -Wuninitialized"
+          ]
+      )
+    fi
+    if ! HOTSPOT_CHECK_JVM_VARIANT(zero) && ! HOTSPOT_CHECK_JVM_VARIANT(zeroshark); then
+      # Non-zero builds have stricter warnings
+      $2JVM_CFLAGS="[$]$2JVM_CFLAGS -Wreturn-type -Wundef -Wformat=2"
+    else
+      if test "x$TOOLCHAIN_TYPE" = xclang; then
+        # Some versions of llvm do not like -Wundef
+        $2JVM_CFLAGS="[$]$2JVM_CFLAGS -Wno-undef"
+      fi
+    fi
+  elif test "x$OPENJDK_$1_OS" = xmacosx; then
+    $2JVM_CFLAGS="[$]$2JVM_CFLAGS -Wno-deprecated -Wpointer-arith \
+        -Wsign-compare -Wundef -Wunused-function -Wformat=2"
   fi
 
   # Additional macosx handling
-  if test "x$OPENJDK_TARGET_OS" = xmacosx; then
+  if test "x$OPENJDK_$1_OS" = xmacosx; then
     # Setting these parameters makes it an error to link to macosx APIs that are
     # newer than the given OS version and makes the linked binaries compatible
     # even if built on a newer version of the OS.
@@ -765,108 +997,112 @@
     # The macro takes the version with no dots, ex: 1070
     # Let the flags variables get resolved in make for easier override on make
     # command line.
-    COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -DMAC_OS_X_VERSION_MAX_ALLOWED=\$(subst .,,\$(MACOSX_VERSION_MIN)) -mmacosx-version-min=\$(MACOSX_VERSION_MIN)"
-    LDFLAGS_JDK="$LDFLAGS_JDK -mmacosx-version-min=\$(MACOSX_VERSION_MIN)"
+    $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK -DMAC_OS_X_VERSION_MAX_ALLOWED=\$(subst .,,\$(MACOSX_VERSION_MIN)) -mmacosx-version-min=\$(MACOSX_VERSION_MIN)"
+    $2LDFLAGS_JDK="[$]$2LDFLAGS_JDK -mmacosx-version-min=\$(MACOSX_VERSION_MIN)"
   fi
 
   # Setup some hard coded includes
-  COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK \
+  $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK \
       -I${JDK_TOPDIR}/src/java.base/share/native/include \
-      -I${JDK_TOPDIR}/src/java.base/$OPENJDK_TARGET_OS/native/include \
-      -I${JDK_TOPDIR}/src/java.base/$OPENJDK_TARGET_OS_TYPE/native/include \
+      -I${JDK_TOPDIR}/src/java.base/$OPENJDK_$1_OS/native/include \
+      -I${JDK_TOPDIR}/src/java.base/$OPENJDK_$1_OS_TYPE/native/include \
       -I${JDK_TOPDIR}/src/java.base/share/native/libjava \
-      -I${JDK_TOPDIR}/src/java.base/$OPENJDK_TARGET_OS_TYPE/native/libjava"
+      -I${JDK_TOPDIR}/src/java.base/$OPENJDK_$1_OS_TYPE/native/libjava"
 
   # The shared libraries are compiled using the picflag.
-  CFLAGS_JDKLIB="$COMMON_CCXXFLAGS_JDK $OPENJDK_TARGET_CCXXFLAGS_JDK \
-      $CFLAGS_JDK $EXTRA_CFLAGS_JDK $PICFLAG $CFLAGS_JDKLIB_EXTRA"
-  CXXFLAGS_JDKLIB="$COMMON_CCXXFLAGS_JDK $OPENJDK_TARGET_CCXXFLAGS_JDK \
-      $CXXFLAGS_JDK $EXTRA_CXXFLAGS_JDK $PICFLAG $CXXFLAGS_JDKLIB_EXTRA"
+  $2CFLAGS_JDKLIB="[$]$2COMMON_CCXXFLAGS_JDK \
+      [$]$2CFLAGS_JDK [$]$2EXTRA_CFLAGS_JDK $PICFLAG [$]$2CFLAGS_JDKLIB_EXTRA"
+  $2CXXFLAGS_JDKLIB="[$]$2COMMON_CCXXFLAGS_JDK \
+      [$]$2CXXFLAGS_JDK [$]$2EXTRA_CXXFLAGS_JDK $PICFLAG [$]$2CXXFLAGS_JDKLIB_EXTRA"
 
   # Executable flags
-  CFLAGS_JDKEXE="$COMMON_CCXXFLAGS_JDK $OPENJDK_TARGET_CCXXFLAGS_JDK \
-      $CFLAGS_JDK $EXTRA_CFLAGS_JDK"
-  CXXFLAGS_JDKEXE="$COMMON_CCXXFLAGS_JDK $OPENJDK_TARGET_CCXXFLAGS_JDK \
-      $CXXFLAGS_JDK $EXTRA_CXXFLAGS_JDK"
-
-  # The corresponding flags for building for the build platform. This is still an
-  # approximation, we only need something that runs on this machine when cross
-  # compiling the product.
-  OPENJDK_BUILD_CFLAGS_JDKLIB="$COMMON_CCXXFLAGS_JDK $OPENJDK_BUILD_CCXXFLAGS_JDK \
-      $PICFLAG $CFLAGS_JDKLIB_EXTRA"
-  OPENJDK_BUILD_CXXFLAGS_JDKLIB="$COMMON_CCXXFLAGS_JDK $OPENJDK_BUILD_CCXXFLAGS_JDK \
-      $PICFLAG $CXXFLAGS_JDKLIB_EXTRA"
-  OPENJDK_BUILD_CFLAGS_JDKEXE="$COMMON_CCXXFLAGS_JDK $OPENJDK_BUILD_CCXXFLAGS_JDK"
-  OPENJDK_BUILD_CXXFLAGS_JDKEXE="$COMMON_CCXXFLAGS_JDK $OPENJDK_BUILD_CCXXFLAGS_JDK"
+  $2CFLAGS_JDKEXE="[$]$2COMMON_CCXXFLAGS_JDK [$]$2CFLAGS_JDK [$]$2EXTRA_CFLAGS_JDK"
+  $2CXXFLAGS_JDKEXE="[$]$2COMMON_CCXXFLAGS_JDK [$]$2CXXFLAGS_JDK [$]$2EXTRA_CXXFLAGS_JDK"
 
-  AC_SUBST(CFLAGS_JDKLIB)
-  AC_SUBST(CFLAGS_JDKEXE)
-  AC_SUBST(CXXFLAGS_JDKLIB)
-  AC_SUBST(CXXFLAGS_JDKEXE)
-  AC_SUBST(OPENJDK_BUILD_CFLAGS_JDKLIB)
-  AC_SUBST(OPENJDK_BUILD_CFLAGS_JDKEXE)
-  AC_SUBST(OPENJDK_BUILD_CXXFLAGS_JDKLIB)
-  AC_SUBST(OPENJDK_BUILD_CXXFLAGS_JDKEXE)
-
-  # Flags for compiling test libraries
-  CFLAGS_TESTLIB="$COMMON_CCXXFLAGS_JDK $CFLAGS_JDK $PICFLAG $CFLAGS_JDKLIB_EXTRA"
-  CXXFLAGS_TESTLIB="$COMMON_CCXXFLAGS_JDK $CXXFLAGS_JDK $PICFLAG $CXXFLAGS_JDKLIB_EXTRA"
-
-  # Flags for compiling test executables
-  CFLAGS_TESTEXE="$COMMON_CCXXFLAGS_JDK $CFLAGS_JDK"
-  CXXFLAGS_TESTEXE="$COMMON_CCXXFLAGS_JDK $CXXFLAGS_JDK"
-
-  AC_SUBST(CFLAGS_TESTLIB)
-  AC_SUBST(CFLAGS_TESTEXE)
-  AC_SUBST(CXXFLAGS_TESTLIB)
-  AC_SUBST(CXXFLAGS_TESTEXE)
+  AC_SUBST($2CFLAGS_JDKLIB)
+  AC_SUBST($2CFLAGS_JDKEXE)
+  AC_SUBST($2CXXFLAGS_JDKLIB)
+  AC_SUBST($2CXXFLAGS_JDKEXE)
 
   # Setup LDFLAGS et al.
   #
 
   if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
     LDFLAGS_MICROSOFT="-nologo -opt:ref"
-    LDFLAGS_JDK="$LDFLAGS_JDK $LDFLAGS_MICROSOFT -incremental:no"
-    if test "x$OPENJDK_TARGET_CPU_BITS" = "x32"; then
+    $2LDFLAGS_JDK="[$]$2LDFLAGS_JDK $LDFLAGS_MICROSOFT -incremental:no"
+    $2JVM_LDFLAGS="[$]$2JVM_LDFLAGS $LDFLAGS_MICROSOFT -opt:icf,8 -subsystem:windows -base:0x8000000"
+    if test "x$OPENJDK_$1_CPU_BITS" = "x32"; then
       LDFLAGS_SAFESH="-safeseh"
-      LDFLAGS_JDK="$LDFLAGS_JDK $LDFLAGS_SAFESH"
+      $2LDFLAGS_JDK="[$]$2LDFLAGS_JDK $LDFLAGS_SAFESH"
+      $2JVM_LDFLAGS="[$]$2JVM_LDFLAGS $LDFLAGS_SAFESH"
+      # NOTE: Old build added -machine. Probably not needed.
+      $2JVM_LDFLAGS="[$]$2JVM_LDFLAGS -machine:I386"
+    else
+      $2JVM_LDFLAGS="[$]$2JVM_LDFLAGS -machine:AMD64"
+    fi
+  elif test "x$TOOLCHAIN_TYPE" = xclang; then
+      $2JVM_LDFLAGS="[$]$2JVM_LDFLAGS -mno-omit-leaf-frame-pointer -mstack-alignment=16 -stdlib=libstdc++ -fPIC"
+      if test "x$OPENJDK_$1_OS" = xmacosx; then
+        # FIXME: We should really generalize SET_SHARED_LIBRARY_ORIGIN instead.
+        $2JVM_LDFLAGS="[$]$2JVM_LDFLAGS -Wl,-rpath,@loader_path/. -Wl,-rpath,@loader_path/.."
     fi
   elif test "x$TOOLCHAIN_TYPE" = xgcc; then
     # If this is a --hash-style=gnu system, use --hash-style=both, why?
     # We have previously set HAS_GNU_HASH if this is the case
     if test -n "$HAS_GNU_HASH"; then
-      LDFLAGS_HASH_STYLE="-Wl,--hash-style=both"
-      LDFLAGS_JDK="${LDFLAGS_JDK} $LDFLAGS_HASH_STYLE"
+      $2LDFLAGS_HASH_STYLE="-Wl,--hash-style=both"
+      $2LDFLAGS_JDK="${$2LDFLAGS_JDK} [$]$2LDFLAGS_HASH_STYLE"
+      $2JVM_LDFLAGS="[$]$2JVM_LDFLAGS [$]$2LDFLAGS_HASH_STYLE"
     fi
-    if test "x$OPENJDK_TARGET_OS" = xlinux; then
+      if test "x$OPENJDK_$1_OS" = xmacosx; then
+        $2JVM_LDFLAGS="[$]$2JVM_LDFLAGS -Wl,-rpath,@loader_path/. -Wl,-rpath,@loader_path/.."
+    fi
+    if test "x$OPENJDK_$1_OS" = xlinux; then
       # And since we now know that the linker is gnu, then add -z defs, to forbid
       # undefined symbols in object files.
       LDFLAGS_NO_UNDEF_SYM="-Wl,-z,defs"
-      LDFLAGS_JDK="${LDFLAGS_JDK} $LDFLAGS_NO_UNDEF_SYM"
+      $2LDFLAGS_JDK="${$2LDFLAGS_JDK} $LDFLAGS_NO_UNDEF_SYM"
+      $2JVM_LDFLAGS="[$]$2JVM_LDFLAGS  $LDFLAGS_NO_UNDEF_SYM"
+      LDFLAGS_NO_EXEC_STACK="-Wl,-z,noexecstack"
+      $2JVM_LDFLAGS="[$]$2JVM_LDFLAGS $LDFLAGS_NO_EXEC_STACK"
+      if test "x$OPENJDK_$1_CPU" = xx86; then
+        $2JVM_LDFLAGS="[$]$2JVM_LDFLAGS -march=i586"
+      fi
       case $DEBUG_LEVEL in
         release )
           # tell linker to optimize libraries.
           # Should this be supplied to the OSS linker as well?
           LDFLAGS_DEBUGLEVEL_release="-Wl,-O1"
-          LDFLAGS_JDK="${LDFLAGS_JDK} $LDFLAGS_DEBUGLEVEL_release"
+          $2LDFLAGS_JDK="${$2LDFLAGS_JDK} $LDFLAGS_DEBUGLEVEL_release"
+          $2JVM_LDFLAGS="[$]$2JVM_LDFLAGS $LDFLAGS_DEBUGLEVEL_release"
+          if test "x$HAS_LINKER_RELRO" = "xtrue"; then
+            $2JVM_LDFLAGS="[$]$2JVM_LDFLAGS $LINKER_RELRO_FLAG"
+          fi
           ;;
         slowdebug )
+          # Hotspot always let the linker optimize
+          $2JVM_LDFLAGS="[$]$2JVM_LDFLAGS -Wl,-O1"
           if test "x$HAS_LINKER_NOW" = "xtrue"; then
             # do relocations at load
-            LDFLAGS_JDK="$LDFLAGS_JDK $LINKER_NOW_FLAG"
-            LDFLAGS_CXX_JDK="$LDFLAGS_CXX_JDK $LINKER_NOW_FLAG"
+            $2LDFLAGS_JDK="[$]$2LDFLAGS_JDK $LINKER_NOW_FLAG"
+            $2LDFLAGS_CXX_JDK="[$]$2LDFLAGS_CXX_JDK $LINKER_NOW_FLAG"
+            $2JVM_LDFLAGS="[$]$2JVM_LDFLAGS $LINKER_NOW_FLAG"
           fi
           if test "x$HAS_LINKER_RELRO" = "xtrue"; then
             # mark relocations read only
-            LDFLAGS_JDK="$LDFLAGS_JDK $LINKER_RELRO_FLAG"
-            LDFLAGS_CXX_JDK="$LDFLAGS_CXX_JDK $LINKER_RELRO_FLAG"
+            $2LDFLAGS_JDK="[$]$2LDFLAGS_JDK $LINKER_RELRO_FLAG"
+            $2LDFLAGS_CXX_JDK="[$]$2LDFLAGS_CXX_JDK $LINKER_RELRO_FLAG"
+            $2JVM_LDFLAGS="[$]$2JVM_LDFLAGS $LINKER_RELRO_FLAG"
           fi
           ;;
         fastdebug )
+          # Hotspot always let the linker optimize
+          $2JVM_LDFLAGS="[$]$2JVM_LDFLAGS -Wl,-O1"
           if test "x$HAS_LINKER_RELRO" = "xtrue"; then
             # mark relocations read only
-            LDFLAGS_JDK="$LDFLAGS_JDK $LINKER_RELRO_FLAG"
-            LDFLAGS_CXX_JDK="$LDFLAGS_CXX_JDK $LINKER_RELRO_FLAG"
+            $2LDFLAGS_JDK="[$]$2LDFLAGS_JDK $LINKER_RELRO_FLAG"
+            $2LDFLAGS_CXX_JDK="[$]$2LDFLAGS_CXX_JDK $LINKER_RELRO_FLAG"
+            $2JVM_LDFLAGS="[$]$2JVM_LDFLAGS $LINKER_RELRO_FLAG"
           fi
           ;;
         * )
@@ -876,85 +1112,122 @@
     fi
   elif test "x$TOOLCHAIN_TYPE" = xsolstudio; then
     LDFLAGS_SOLSTUDIO="-Wl,-z,defs"
-    LDFLAGS_JDK="$LDFLAGS_JDK $LDFLAGS_SOLSTUDIO -xildoff -ztext"
+    $2LDFLAGS_JDK="[$]$2LDFLAGS_JDK $LDFLAGS_SOLSTUDIO -xildoff -ztext"
     LDFLAGS_CXX_SOLSTUDIO="-norunpath"
-    LDFLAGS_CXX_JDK="$LDFLAGS_CXX_JDK $LDFLAGS_CXX_SOLSTUDIO -xnolib"
+    $2LDFLAGS_CXX_JDK="[$]$2LDFLAGS_CXX_JDK $LDFLAGS_CXX_SOLSTUDIO -xnolib"
+    $2JVM_LDFLAGS="[$]$2JVM_LDFLAGS $LDFLAGS_SOLSTUDIO -library=%none -mt $LDFLAGS_CXX_SOLSTUDIO -z noversion"
+    if test "x$OPENJDK_$1_CPU_ARCH" = "xsparc"; then
+      $2JVM_LDFLAGS="[$]$2JVM_LDFLAGS -xarch=sparc"
+    fi
   elif test "x$TOOLCHAIN_TYPE" = xxlc; then
     LDFLAGS_XLC="-b64 -brtl -bnolibpath -bexpall -bernotok"
-    LDFLAGS_JDK="${LDFLAGS_JDK} $LDFLAGS_XLC"
+    $2LDFLAGS_JDK="${$2LDFLAGS_JDK} $LDFLAGS_XLC"
+    $2JVM_LDFLAGS="[$]$2JVM_LDFLAGS $LDFLAGS_XLC"
   fi
 
   # Customize LDFLAGS for executables
 
-  LDFLAGS_JDKEXE="${LDFLAGS_JDK}"
+  $2LDFLAGS_JDKEXE="${$2LDFLAGS_JDK}"
 
   if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
-    if test "x$OPENJDK_TARGET_CPU_BITS" = "x64"; then
+    if test "x$OPENJDK_$1_CPU_BITS" = "x64"; then
       LDFLAGS_STACK_SIZE=1048576
     else
       LDFLAGS_STACK_SIZE=327680
     fi
-    LDFLAGS_JDKEXE="${LDFLAGS_JDKEXE} /STACK:$LDFLAGS_STACK_SIZE"
-  elif test "x$OPENJDK_TARGET_OS" = xlinux; then
-    LDFLAGS_JDKEXE="$LDFLAGS_JDKEXE -Wl,--allow-shlib-undefined"
+    $2LDFLAGS_JDKEXE="${$2LDFLAGS_JDKEXE} /STACK:$LDFLAGS_STACK_SIZE"
+  elif test "x$OPENJDK_$1_OS" = xlinux; then
+    $2LDFLAGS_JDKEXE="[$]$2LDFLAGS_JDKEXE -Wl,--allow-shlib-undefined"
   fi
 
-  OPENJDK_BUILD_LDFLAGS_JDKEXE="${LDFLAGS_JDKEXE}"
-  LDFLAGS_JDKEXE="${LDFLAGS_JDKEXE} ${EXTRA_LDFLAGS_JDK}"
+  $2LDFLAGS_JDKEXE="${$2LDFLAGS_JDKEXE} ${$2EXTRA_LDFLAGS_JDK}"
 
   # Customize LDFLAGS for libs
-  LDFLAGS_JDKLIB="${LDFLAGS_JDK}"
+  $2LDFLAGS_JDKLIB="${$2LDFLAGS_JDK}"
 
-  LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} ${SHARED_LIBRARY_FLAGS}"
+  $2LDFLAGS_JDKLIB="${$2LDFLAGS_JDKLIB} ${SHARED_LIBRARY_FLAGS}"
   if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
-    LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} \
+    $2LDFLAGS_JDKLIB="${$2LDFLAGS_JDKLIB} \
         -libpath:${OUTPUT_ROOT}/support/modules_libs/java.base"
-    JDKLIB_LIBS=""
+    $2JDKLIB_LIBS=""
   else
-    LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} \
-        -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_TARGET_CPU_LIBDIR)"
+    $2LDFLAGS_JDKLIB="${$2LDFLAGS_JDKLIB} \
+        -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_$1_CPU_LIBDIR)"
 
+    if test "x$1" = "xTARGET"; then
     # On some platforms (mac) the linker warns about non existing -L dirs.
     # Add server first if available. Linking aginst client does not always produce the same results.
-    # Only add client dir if client is being built. Add minimal (note not minimal1) if only building minimal1.
+      # Only add client/minimal dir if client/minimal is being built.
     # Default to server for other variants.
-    if test "x$JVM_VARIANT_SERVER" = xtrue; then
-      LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_TARGET_CPU_LIBDIR)/server"
-    elif test "x$JVM_VARIANT_CLIENT" = xtrue; then
-      LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_TARGET_CPU_LIBDIR)/client"
-    elif test "x$JVM_VARIANT_MINIMAL1" = xtrue; then
-      LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_TARGET_CPU_LIBDIR)/minimal"
+      if HOTSPOT_CHECK_JVM_VARIANT(server); then
+        $2LDFLAGS_JDKLIB="${$2LDFLAGS_JDKLIB} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_$1_CPU_LIBDIR)/server"
+      elif HOTSPOT_CHECK_JVM_VARIANT(client); then
+        $2LDFLAGS_JDKLIB="${$2LDFLAGS_JDKLIB} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_$1_CPU_LIBDIR)/client"
+      elif HOTSPOT_CHECK_JVM_VARIANT(minimal); then
+        $2LDFLAGS_JDKLIB="${$2LDFLAGS_JDKLIB} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_$1_CPU_LIBDIR)/minimal"
     else
-      LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_TARGET_CPU_LIBDIR)/server"
+        $2LDFLAGS_JDKLIB="${$2LDFLAGS_JDKLIB} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_$1_CPU_LIBDIR)/server"
+    fi
+    elif test "x$1" = "xBUILD"; then
+      # When building a buildjdk, it's always only the server variant
+      $2LDFLAGS_JDKLIB="${$2LDFLAGS_JDKLIB} \
+          -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_$1_CPU_LIBDIR)/server"
     fi
 
-    JDKLIB_LIBS="-ljava -ljvm"
+    $2JDKLIB_LIBS="-ljava -ljvm"
     if test "x$TOOLCHAIN_TYPE" = xsolstudio; then
-      JDKLIB_LIBS="$JDKLIB_LIBS -lc"
+      $2JDKLIB_LIBS="[$]$2JDKLIB_LIBS -lc"
     fi
 
-    # When building a buildjdk, it's always only the server variant
-    OPENJDK_BUILD_LDFLAGS_JDKLIB="${OPENJDK_BUILD_LDFLAGS_JDKLIB} \
-        -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_TARGET_CPU_LIBDIR)/server"
   fi
 
-  OPENJDK_BUILD_LDFLAGS_JDKLIB="${OPENJDK_BUILD_LDFLAGS_JDKLIB} ${LDFLAGS_JDKLIB}"
-  LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} ${EXTRA_LDFLAGS_JDK}"
+  # Set $2JVM_LIBS (per os)
+  if test "x$OPENJDK_$1_OS" = xlinux; then
+    $2JVM_LIBS="[$]$2JVM_LIBS -lm -ldl -lpthread"
+  elif test "x$OPENJDK_$1_OS" = xsolaris; then
+    # FIXME: This hard-coded path is not really proper.
+    if test "x$OPENJDK_$1_CPU" = xx86_64; then
+      $2SOLARIS_LIBM_LIBS="/usr/lib/amd64/libm.so.1"
+    elif test "x$OPENJDK_$1_CPU" = xsparcv9; then
+      $2SOLARIS_LIBM_LIBS="/usr/lib/sparcv9/libm.so.1"
+    fi
+    $2JVM_LIBS="[$]$2JVM_LIBS -lsocket -lsched -ldl $SOLARIS_LIBM_LIBS -lCrun \
+        -lthread -ldoor -lc -ldemangle -lnsl -lkstat -lrt"
+  elif test "x$OPENJDK_$1_OS" = xmacosx; then
+    $2JVM_LIBS="[$]$2JVM_LIBS -lm"
+  elif test "x$OPENJDK_$1_OS" = xaix; then
+    $2JVM_LIBS="[$]$2JVM_LIBS -Wl,-lC_r -lm -ldl -lpthread"
+  elif test "x$OPENJDK_$1_OS" = xbsd; then
+    $2JVM_LIBS="[$]$2JVM_LIBS -lm"
+  elif test "x$OPENJDK_$1_OS" = xwindows; then
+    $2JVM_LIBS="[$]$2JVM_LIBS kernel32.lib user32.lib gdi32.lib winspool.lib \
+        comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib \
+        wsock32.lib winmm.lib version.lib psapi.lib"
+    fi
 
-  AC_SUBST(LDFLAGS_JDKLIB)
-  AC_SUBST(LDFLAGS_JDKEXE)
-  AC_SUBST(OPENJDK_BUILD_LDFLAGS_JDKLIB)
-  AC_SUBST(OPENJDK_BUILD_LDFLAGS_JDKEXE)
-  AC_SUBST(JDKLIB_LIBS)
-  AC_SUBST(JDKEXE_LIBS)
-  AC_SUBST(LDFLAGS_CXX_JDK)
-  AC_SUBST(LDFLAGS_HASH_STYLE)
+  # Set $2JVM_ASFLAGS
+  if test "x$OPENJDK_$1_OS" = xlinux; then
+    if test "x$OPENJDK_$1_CPU" = xx86; then
+      $2JVM_ASFLAGS="[$]$2JVM_ASFLAGS -march=i586"
+    fi
+  elif test "x$OPENJDK_$1_OS" = xmacosx; then
+    $2JVM_ASFLAGS="[$]$2JVM_ASFLAGS -x assembler-with-cpp -mno-omit-leaf-frame-pointer -mstack-alignment=16"
+  fi
+
+  $2LDFLAGS_JDKLIB="${$2LDFLAGS_JDKLIB} ${$2EXTRA_LDFLAGS_JDK}"
 
-  LDFLAGS_TESTLIB="$LDFLAGS_JDKLIB"
-  LDFLAGS_TESTEXE="$LDFLAGS_JDKEXE"
+  AC_SUBST($2LDFLAGS_JDKLIB)
+  AC_SUBST($2LDFLAGS_JDKEXE)
+  AC_SUBST($2JDKLIB_LIBS)
+  AC_SUBST($2JDKEXE_LIBS)
+  AC_SUBST($2LDFLAGS_CXX_JDK)
+  AC_SUBST($2LDFLAGS_HASH_STYLE)
 
-  AC_SUBST(LDFLAGS_TESTLIB)
-  AC_SUBST(LDFLAGS_TESTEXE)
+  AC_SUBST($2JVM_CFLAGS)
+  AC_SUBST($2JVM_LDFLAGS)
+  AC_SUBST($2JVM_ASFLAGS)
+  AC_SUBST($2JVM_LIBS)
+
 ])
 
 # FLAGS_C_COMPILER_CHECK_ARGUMENTS(ARGUMENT: [ARGUMENT], IF_TRUE: [RUN-IF-TRUE],
--- a/common/autoconf/generated-configure.sh	Thu Apr 21 12:57:17 2016 -0700
+++ b/common/autoconf/generated-configure.sh	Wed Jul 05 21:37:42 2017 +0200
@@ -652,7 +652,21 @@
 NUM_CORES
 BUILD_FAILURE_HANDLER
 ENABLE_INTREE_EC
+JVM_VARIANT_CORE
+JVM_VARIANT_ZEROSHARK
+JVM_VARIANT_ZERO
+JVM_VARIANT_HOTSPOT
+JVM_VARIANT_MINIMAL1
+JVM_VARIANT_CLIENT
+JVM_VARIANT_SERVER
+JVM_VARIANTS_COMMA
+TEST_IN_BUILD
 HOTSPOT_MAKE_ARGS
+MACOSX_UNIVERSAL
+DEBUG_CLASSFILES
+FASTDEBUG
+VARIANT
+USE_NEW_HOTSPOT_BUILD
 LIBZIP_CAN_USE_MMAP
 LIBDL
 LIBM
@@ -688,6 +702,15 @@
 STATIC_CXX_SETTING
 FIXPATH_DETACH_FLAG
 FIXPATH
+VALID_JVM_FEATURES
+JVM_FEATURES_custom
+JVM_FEATURES_zeroshark
+JVM_FEATURES_zero
+JVM_FEATURES_minimal
+JVM_FEATURES_core
+JVM_FEATURES_client
+JVM_FEATURES_server
+INCLUDE_DTRACE
 GCOV_ENABLED
 STRIP_POLICY
 DEBUG_BINARIES
@@ -703,22 +726,35 @@
 ZERO_ARCHFLAG
 LDFLAGS_TESTEXE
 LDFLAGS_TESTLIB
+CXXFLAGS_TESTEXE
+CXXFLAGS_TESTLIB
+CFLAGS_TESTEXE
+CFLAGS_TESTLIB
+OPENJDK_BUILD_JVM_LIBS
+OPENJDK_BUILD_JVM_ASFLAGS
+OPENJDK_BUILD_JVM_LDFLAGS
+OPENJDK_BUILD_JVM_CFLAGS
+OPENJDK_BUILD_LDFLAGS_HASH_STYLE
+OPENJDK_BUILD_LDFLAGS_CXX_JDK
+OPENJDK_BUILD_JDKEXE_LIBS
+OPENJDK_BUILD_JDKLIB_LIBS
+OPENJDK_BUILD_LDFLAGS_JDKEXE
+OPENJDK_BUILD_LDFLAGS_JDKLIB
+OPENJDK_BUILD_CXXFLAGS_JDKEXE
+OPENJDK_BUILD_CXXFLAGS_JDKLIB
+OPENJDK_BUILD_CFLAGS_JDKEXE
+OPENJDK_BUILD_CFLAGS_JDKLIB
+OPENJDK_BUILD_CXXSTD_CXXFLAG
+JVM_LIBS
+JVM_ASFLAGS
+JVM_LDFLAGS
+JVM_CFLAGS
 LDFLAGS_HASH_STYLE
 LDFLAGS_CXX_JDK
 JDKEXE_LIBS
 JDKLIB_LIBS
-OPENJDK_BUILD_LDFLAGS_JDKEXE
-OPENJDK_BUILD_LDFLAGS_JDKLIB
 LDFLAGS_JDKEXE
 LDFLAGS_JDKLIB
-CXXFLAGS_TESTEXE
-CXXFLAGS_TESTLIB
-CFLAGS_TESTEXE
-CFLAGS_TESTLIB
-OPENJDK_BUILD_CXXFLAGS_JDKEXE
-OPENJDK_BUILD_CXXFLAGS_JDKLIB
-OPENJDK_BUILD_CFLAGS_JDKEXE
-OPENJDK_BUILD_CFLAGS_JDKLIB
 CXXFLAGS_JDKEXE
 CXXFLAGS_JDKLIB
 CFLAGS_JDKEXE
@@ -727,16 +763,21 @@
 NO_LIFETIME_DSE_CFLAG
 NO_NULL_POINTER_CHECK_CFLAG
 CXXSTD_CXXFLAG
+CXX_O_FLAG_SIZE
 CXX_O_FLAG_NONE
 CXX_O_FLAG_DEBUG
 CXX_O_FLAG_NORM
 CXX_O_FLAG_HI
 CXX_O_FLAG_HIGHEST
+CXX_O_FLAG_HIGHEST_JVM
+C_O_FLAG_SIZE
 C_O_FLAG_NONE
 C_O_FLAG_DEBUG
 C_O_FLAG_NORM
 C_O_FLAG_HI
 C_O_FLAG_HIGHEST
+C_O_FLAG_HIGHEST_JVM
+JVM_CFLAGS_SYMBOLS
 CXXFLAGS_DEBUG_SYMBOLS
 CFLAGS_DEBUG_SYMBOLS
 CXX_FLAG_DEPS
@@ -748,6 +789,7 @@
 SET_EXECUTABLE_ORIGIN
 CXX_FLAG_REORDER
 C_FLAG_REORDER
+JVM_RCFLAGS
 RC_FLAGS
 AR_OUT_OPTION
 LD_OUT_OPTION
@@ -760,6 +802,7 @@
 COMPILER_TARGET_BITS_FLAG
 JT_HOME
 JTREGEXE
+HOTSPOT_TOOLCHAIN_TYPE
 USING_BROKEN_SUSE_LD
 PACKAGE_PATH
 USE_CLANG
@@ -822,6 +865,9 @@
 CYGWIN_LINK
 SYSROOT_LDFLAGS
 SYSROOT_CFLAGS
+EXTRA_LDFLAGS
+EXTRA_CXXFLAGS
+EXTRA_CFLAGS
 LEGACY_EXTRA_LDFLAGS
 LEGACY_EXTRA_CXXFLAGS
 LEGACY_EXTRA_CFLAGS
@@ -878,12 +924,12 @@
 VERSION_MAJOR
 MACOSX_BUNDLE_ID_BASE
 MACOSX_BUNDLE_NAME_BASE
+HOTSPOT_VM_DISTRO
 COMPANY_NAME
 JDK_RC_PLATFORM_NAME
 PRODUCT_SUFFIX
 PRODUCT_NAME
 LAUNCHER_NAME
-TEST_IN_BUILD
 JLINK_KEEP_PACKAGED_MODULES
 COPYRIGHT_YEAR
 COMPRESS_JARS
@@ -905,6 +951,7 @@
 DSYMUTIL
 IS_GNU_TIME
 PATCH
+DTRACE
 TIME
 STAT
 HG
@@ -928,20 +975,10 @@
 SPEC
 SDKROOT
 XCODEBUILD
-BUILD_VARIANT_RELEASE
-DEBUG_CLASSFILES
-FASTDEBUG
-VARIANT
+VALID_JVM_VARIANTS
+JVM_VARIANTS
 DEBUG_LEVEL
-MACOSX_UNIVERSAL
-JVM_VARIANT_CORE
-JVM_VARIANT_ZEROSHARK
-JVM_VARIANT_ZERO
-JVM_VARIANT_MINIMAL1
-JVM_VARIANT_CLIENT
-JVM_VARIANT_SERVER
-JVM_VARIANTS
-JVM_INTERPRETER
+HOTSPOT_DEBUG_LEVEL
 JDK_VARIANT
 SET_OPENJDK
 USERNAME
@@ -950,16 +987,29 @@
 TOPDIR
 PATH_SEP
 ZERO_ARCHDEF
+HOTSPOT_BUILD_CPU_DEFINE
+HOTSPOT_BUILD_CPU_ARCH
+HOTSPOT_BUILD_CPU
+HOTSPOT_BUILD_OS_TYPE
+HOTSPOT_BUILD_OS
+OPENJDK_BUILD_OS_EXPORT_DIR
+OPENJDK_BUILD_CPU_JLI_CFLAGS
+OPENJDK_BUILD_CPU_OSARCH
+OPENJDK_BUILD_CPU_ISADIR
+OPENJDK_BUILD_CPU_LIBDIR
+OPENJDK_BUILD_CPU_LEGACY_LIB
+OPENJDK_BUILD_CPU_LEGACY
+HOTSPOT_TARGET_CPU_DEFINE
+HOTSPOT_TARGET_CPU_ARCH
+HOTSPOT_TARGET_CPU
+HOTSPOT_TARGET_OS_TYPE
+HOTSPOT_TARGET_OS
 DEFINE_CROSS_COMPILE_ARCH
 LP64
 OPENJDK_TARGET_OS_EXPORT_DIR
-OPENJDK_BUILD_CPU_JLI_CFLAGS
 OPENJDK_TARGET_CPU_JLI_CFLAGS
 OPENJDK_TARGET_CPU_OSARCH
 OPENJDK_TARGET_CPU_ISADIR
-OPENJDK_BUILD_CPU_LIBDIR
-OPENJDK_BUILD_CPU_LEGACY_LIB
-OPENJDK_BUILD_CPU_LEGACY
 OPENJDK_TARGET_CPU_LIBDIR
 OPENJDK_TARGET_CPU_LEGACY_LIB
 OPENJDK_TARGET_CPU_LEGACY
@@ -1089,10 +1139,9 @@
 enable_openjdk_only
 with_custom_make_dir
 with_jdk_variant
-with_jvm_interpreter
-with_jvm_variants
 enable_debug
 with_debug_level
+with_jvm_variants
 with_devkit
 with_sys_root
 with_sysroot
@@ -1108,7 +1157,6 @@
 enable_unlimited_crypto
 with_copyright_year
 enable_keep_packaged_modules
-enable_hotspot_test_in_build
 with_milestone
 with_update_version
 with_user_release_suffix
@@ -1148,6 +1196,9 @@
 enable_debug_symbols
 enable_zip_debug_info
 enable_native_coverage
+enable_dtrace
+with_jvm_features
+with_jvm_interpreter
 with_stdc__lib
 with_msvcr_dll
 with_msvcp_dll
@@ -1174,6 +1225,8 @@
 with_dxsdk_lib
 with_dxsdk_include
 enable_jtreg_failure_handler
+enable_new_hotspot_build
+enable_hotspot_test_in_build
 with_num_cores
 with_memory_size
 with_jobs
@@ -1246,6 +1299,7 @@
 HG
 STAT
 TIME
+DTRACE
 PATCH
 DSYMUTIL
 XATTR
@@ -1925,8 +1979,6 @@
                           Enable unlimited crypto policy [disabled]
   --disable-keep-packaged-modules
                           Do not keep packaged modules in jdk image [enable]
-  --enable-hotspot-test-in-build
-                          run the Queens test after Hotspot build [disabled]
   --enable-static-build   enable static library build [disabled]
   --disable-warnings-as-errors
                           do not consider native warnings to be an error
@@ -1938,10 +1990,18 @@
   --enable-native-coverage
                           enable native compilation with code coverage
                           data[disabled]
+  --enable-dtrace[=yes/no/auto]
+                          enable dtrace. Default is auto, where dtrace is
+                          enabled if all dependencies are present.
   --disable-freetype-bundling
                           disable bundling of the freetype library with the
                           build result [enabled on Windows or when using
                           --with-freetype, disabled otherwise]
+  --disable-new-hotspot-build
+                          disable the new hotspot build system (use the old)
+                          [enabled]
+  --enable-hotspot-test-in-build
+                          run the Queens test after Hotspot build [disabled]
   --enable-jtreg-failure-handler
                           forces build of the jtreg failure handler to be
                           enabled, missing dependencies become fatal errors.
@@ -1967,11 +2027,11 @@
   --with-custom-make-dir  Deprecated. Option is kept for backwards
                           compatibility and is ignored
   --with-jdk-variant      JDK variant to build (normal) [normal]
-  --with-jvm-interpreter  JVM interpreter to build (template, cpp) [template]
-  --with-jvm-variants     JVM variants (separated by commas) to build (server,
-                          client, minimal1, zero, zeroshark, core) [server]
   --with-debug-level      set the debug level (release, fastdebug, slowdebug,
                           optimized) [release]
+  --with-jvm-variants     JVM variants (separated by commas) to build
+                          (server,client,minimal,core,zero,zeroshark,custom)
+                          [server]
   --with-devkit           use this devkit for compilers, tools and resources
   --with-sys-root         alias for --with-sysroot for backwards compatability
   --with-sysroot          use this directory as sysroot
@@ -2058,6 +2118,10 @@
   --with-native-debug-symbols
                           set the native debug symbol configuration (none,
                           internal, external, zipped) [varying]
+  --with-jvm-features     additional JVM features to enable (separated by
+                          comma), use '--help' to show possible values [none]
+  --with-jvm-interpreter  Deprecated. Option is kept for backwards
+                          compatibility and is ignored
   --with-stdc++lib=<static>,<dynamic>,<default>
                           force linking of the C++ runtime on Linux to either
                           static or dynamic, default is static with dynamic as
@@ -2178,6 +2242,7 @@
   HG          Override default value for HG
   STAT        Override default value for STAT
   TIME        Override default value for TIME
+  DTRACE      Override default value for DTRACE
   PATCH       Override default value for PATCH
   DSYMUTIL    Override default value for DSYMUTIL
   XATTR       Override default value for XATTR
@@ -3977,6 +4042,13 @@
 
 
 
+
+################################################################################
+# $1 - Either BUILD or TARGET to pick the correct OS/CPU variables to check
+#      conditionals against.
+# $2 - Optional prefix for each variable defined.
+
+
 # FLAGS_C_COMPILER_CHECK_ARGUMENTS(ARGUMENT: [ARGUMENT], IF_TRUE: [RUN-IF-TRUE],
 #                                  IF_FALSE: [RUN-IF-FALSE])
 # ------------------------------------------------------------
@@ -4101,6 +4173,8 @@
       PKGHANDLER_COMMAND="sudo apt-get install libX11-dev libxext-dev libxrender-dev libxtst-dev libxt-dev" ;;
     ccache)
       PKGHANDLER_COMMAND="sudo apt-get install ccache" ;;
+    dtrace)
+      PKGHANDLER_COMMAND="sudo apt-get install systemtap-sdt-dev" ;;
   esac
 }
 
@@ -4170,37 +4244,66 @@
 # questions.
 #
 
+# All valid JVM features, regardless of platform
+VALID_JVM_FEATURES="compiler1 compiler2 zero shark minimal dtrace jvmti jvmci \
+    fprof vm-structs jni-check services management all-gcs nmt cds static-build"
+
+# All valid JVM variants
+VALID_JVM_VARIANTS="server client minimal core zero zeroshark custom"
+
 ###############################################################################
-# Check which interpreter of the JVM we want to build.
-# Currently we have:
-#    template: Template interpreter (the default)
-#    cpp     : C++ interpreter
+# Check if the specified JVM variant should be built. To be used in shell if
+# constructs, like this:
+# if HOTSPOT_CHECK_JVM_VARIANT(server); then
+#
+# Only valid to use after HOTSPOT_SETUP_JVM_VARIANTS has setup variants.
+
+# Definition kept in one line to allow inlining in if statements.
+# Additional [] needed to keep m4 from mangling shell constructs.
+
+
+###############################################################################
+# Check if the specified JVM features are explicitly enabled. To be used in
+# shell if constructs, like this:
+# if HOTSPOT_CHECK_JVM_FEATURE(jvmti); then
+#
+# Only valid to use after HOTSPOT_SETUP_JVM_FEATURES has setup features.
+
+# Definition kept in one line to allow inlining in if statements.
+# Additional [] needed to keep m4 from mangling shell constructs.
 
 
 ###############################################################################
-# Check which variants of the JVM that we want to build.
-# Currently we have:
-#    server: normal interpreter and a C2 or tiered C1/C2 compiler
-#    client: normal interpreter and C1 (no C2 compiler) (only 32-bit platforms)
-#    minimal1: reduced form of client with optional VM services and features stripped out
-#    zero: no machine code interpreter, no compiler
-#    zeroshark: zero interpreter and shark/llvm compiler backend
-#    core: interpreter only, no compiler (only works on some platforms)
-
+# Check which variants of the JVM that we want to build. Available variants are:
+#   server: normal interpreter, and a tiered C1/C2 compiler
+#   client: normal interpreter, and C1 (no C2 compiler)
+#   minimal: reduced form of client with optional features stripped out
+#   core: normal interpreter only, no compiler
+#   zero: C++ based interpreter only, no compiler
+#   zeroshark: C++ based interpreter, and a llvm-based compiler
+#   custom: baseline JVM with no default features
+#
 
 
 ###############################################################################
-# Setup legacy vars/targets and new vars to deal with different debug levels.
-#
-#    release: no debug information, all optimizations, no asserts.
-#    optimized: no debug information, all optimizations, no asserts, HotSpot target is 'optimized'.
-#    fastdebug: debug information (-g), all optimizations, all asserts
-#    slowdebug: debug information (-g), no optimizations, all asserts
-#
-
-
-
-
+# Check if dtrace should be enabled and has all prerequisites present.
+#
+
+
+###############################################################################
+# Set up all JVM features for each JVM variant.
+#
+
+
+###############################################################################
+# Validate JVM features once all setup is complete, including custom setup.
+#
+
+
+###############################################################################
+# Support for old hotspot build. Remove once new hotspot build has proven
+# to work satisfactory.
+#
 
 
 #
@@ -4543,7 +4646,7 @@
 
 
 #
-# 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
@@ -4627,7 +4730,7 @@
 
 
 #
-# Copyright (c) 2011, 2012, 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
@@ -4678,6 +4781,9 @@
 #
 
 
+# $1 - Either TARGET or BUILD to setup the variables for.
+
+
 
 
 #%%% Build and target systems %%%
@@ -4989,6 +5095,13 @@
       TOOLCHAIN_DESCRIPTION=${!toolchain_var_name}
       $PRINTF "  %-10s  %s\n" $toolchain "$TOOLCHAIN_DESCRIPTION"
     done
+    $PRINTF "\n"
+
+    # Print available jvm features
+    $PRINTF "The following JVM features are available as arguments to --with-jvm-features.\n"
+    $PRINTF "Which are valid to use depends on the target platform.\n  "
+    $PRINTF "%s " $VALID_JVM_FEATURES
+    $PRINTF "\n"
 
     # And now exit directly
     exit 0
@@ -15229,6 +15342,7 @@
 
 
 
+
   # Also store the legacy naming of the cpu.
   # Ie i586 and amd64 instead of x86 and x86_64
   OPENJDK_TARGET_CPU_LEGACY="$OPENJDK_TARGET_CPU"
@@ -15259,37 +15373,6 @@
   fi
 
 
-  # Now do the same for OPENJDK_BUILD_CPU...
-  # Also store the legacy naming of the cpu.
-  # Ie i586 and amd64 instead of x86 and x86_64
-  OPENJDK_BUILD_CPU_LEGACY="$OPENJDK_BUILD_CPU"
-  if test "x$OPENJDK_BUILD_CPU" = xx86; then
-    OPENJDK_BUILD_CPU_LEGACY="i586"
-  elif test "x$OPENJDK_BUILD_OS" != xmacosx && test "x$OPENJDK_BUILD_CPU" = xx86_64; then
-    # On all platforms except MacOSX replace x86_64 with amd64.
-    OPENJDK_BUILD_CPU_LEGACY="amd64"
-  fi
-
-
-  # And the second legacy naming of the cpu.
-  # Ie i386 and amd64 instead of x86 and x86_64.
-  OPENJDK_BUILD_CPU_LEGACY_LIB="$OPENJDK_BUILD_CPU"
-  if test "x$OPENJDK_BUILD_CPU" = xx86; then
-    OPENJDK_BUILD_CPU_LEGACY_LIB="i386"
-  elif test "x$OPENJDK_BUILD_CPU" = xx86_64; then
-    OPENJDK_BUILD_CPU_LEGACY_LIB="amd64"
-  fi
-
-
-  # This is the name of the cpu (but using i386 and amd64 instead of
-  # x86 and x86_64, respectively), preceeded by a /, to be used when
-  # locating libraries. On macosx, it's empty, though.
-  OPENJDK_BUILD_CPU_LIBDIR="/$OPENJDK_BUILD_CPU_LEGACY_LIB"
-  if test "x$OPENJDK_BUILD_OS" = xmacosx; then
-    OPENJDK_BUILD_CPU_LIBDIR=""
-  fi
-
-
   # OPENJDK_TARGET_CPU_ISADIR is normally empty. On 64-bit Solaris systems, it is set to
   # /amd64 or /sparcv9. This string is appended to some library paths, like this:
   # /usr/lib${OPENJDK_TARGET_CPU_ISADIR}/libexample.so
@@ -15332,6 +15415,144 @@
   fi
 
 
+  if test "x$OPENJDK_TARGET_OS" = xmacosx; then
+      OPENJDK_TARGET_OS_EXPORT_DIR=macosx
+  else
+      OPENJDK_TARGET_OS_EXPORT_DIR=${OPENJDK_TARGET_OS_TYPE}
+  fi
+
+
+  if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then
+    A_LP64="LP64:="
+    # -D_LP64=1 is only set on linux and mac. Setting on windows causes diff in
+    # unpack200.exe
+    if test "x$OPENJDK_TARGET_OS" = xlinux || test "x$OPENJDK_TARGET_OS" = xmacosx; then
+      OPENJDK_TARGET_ADD_LP64="-D_LP64=1"
+    fi
+  fi
+  LP64=$A_LP64
+
+
+  if test "x$COMPILE_TYPE" = "xcross"; then
+    # FIXME: ... or should this include reduced builds..?
+    DEFINE_CROSS_COMPILE_ARCH="CROSS_COMPILE_ARCH:=$OPENJDK_TARGET_CPU_LEGACY"
+  else
+    DEFINE_CROSS_COMPILE_ARCH=""
+  fi
+
+
+  # Convert openjdk platform names to hotspot names
+
+  HOTSPOT_TARGET_OS=${OPENJDK_TARGET_OS}
+  if test "x$OPENJDK_TARGET_OS" = xmacosx; then
+    HOTSPOT_TARGET_OS=bsd
+  fi
+
+
+  HOTSPOT_TARGET_OS_TYPE=${OPENJDK_TARGET_OS_TYPE}
+  if test "x$OPENJDK_TARGET_OS_TYPE" = xunix; then
+    HOTSPOT_TARGET_OS_TYPE=posix
+  fi
+
+
+  HOTSPOT_TARGET_CPU=${OPENJDK_TARGET_CPU}
+  if test "x$OPENJDK_TARGET_CPU" = xx86; then
+    HOTSPOT_TARGET_CPU=x86_32
+  elif test "x$OPENJDK_TARGET_CPU" = xsparcv9; then
+    HOTSPOT_TARGET_CPU=sparc
+  elif test "x$OPENJDK_TARGET_CPU" = xppc64; then
+    HOTSPOT_TARGET_CPU=ppc_64
+  elif test "x$OPENJDK_TARGET_CPU" = xppc64le; then
+    HOTSPOT_TARGET_CPU=ppc_64
+  fi
+
+
+  # This is identical with OPENJDK_*, but define anyway for consistency.
+  HOTSPOT_TARGET_CPU_ARCH=${OPENJDK_TARGET_CPU_ARCH}
+
+
+  # Setup HOTSPOT_TARGET_CPU_DEFINE
+  if test "x$OPENJDK_TARGET_CPU" = xx86; then
+    HOTSPOT_TARGET_CPU_DEFINE=IA32
+  elif test "x$OPENJDK_TARGET_CPU" = xx86_64; then
+    HOTSPOT_TARGET_CPU_DEFINE=AMD64
+  elif test "x$OPENJDK_TARGET_CPU" = xsparcv9; then
+    HOTSPOT_TARGET_CPU_DEFINE=SPARC
+  elif test "x$OPENJDK_TARGET_CPU" = xaarch64; then
+    HOTSPOT_TARGET_CPU_DEFINE=AARCH64
+  elif test "x$OPENJDK_TARGET_CPU" = xppc64; then
+    HOTSPOT_TARGET_CPU_DEFINE=PPC64
+  elif test "x$OPENJDK_TARGET_CPU" = xppc64le; then
+    HOTSPOT_TARGET_CPU_DEFINE=PPC64
+
+  # The cpu defines below are for zero, we don't support them directly.
+  elif test "x$OPENJDK_TARGET_CPU" = xsparc; then
+    HOTSPOT_TARGET_CPU_DEFINE=SPARC
+  elif test "x$OPENJDK_TARGET_CPU" = xppc; then
+    HOTSPOT_TARGET_CPU_DEFINE=PPC32
+  elif test "x$OPENJDK_TARGET_CPU" = xs390; then
+    HOTSPOT_TARGET_CPU_DEFINE=S390
+  elif test "x$OPENJDK_TARGET_CPU" = ss390x; then
+    HOTSPOT_TARGET_CPU_DEFINE=S390
+  fi
+
+
+
+
+  # Also store the legacy naming of the cpu.
+  # Ie i586 and amd64 instead of x86 and x86_64
+  OPENJDK_BUILD_CPU_LEGACY="$OPENJDK_BUILD_CPU"
+  if test "x$OPENJDK_BUILD_CPU" = xx86; then
+    OPENJDK_BUILD_CPU_LEGACY="i586"
+  elif test "x$OPENJDK_BUILD_OS" != xmacosx && test "x$OPENJDK_BUILD_CPU" = xx86_64; then
+    # On all platforms except MacOSX replace x86_64 with amd64.
+    OPENJDK_BUILD_CPU_LEGACY="amd64"
+  fi
+
+
+  # And the second legacy naming of the cpu.
+  # Ie i386 and amd64 instead of x86 and x86_64.
+  OPENJDK_BUILD_CPU_LEGACY_LIB="$OPENJDK_BUILD_CPU"
+  if test "x$OPENJDK_BUILD_CPU" = xx86; then
+    OPENJDK_BUILD_CPU_LEGACY_LIB="i386"
+  elif test "x$OPENJDK_BUILD_CPU" = xx86_64; then
+    OPENJDK_BUILD_CPU_LEGACY_LIB="amd64"
+  fi
+
+
+  # This is the name of the cpu (but using i386 and amd64 instead of
+  # x86 and x86_64, respectively), preceeded by a /, to be used when
+  # locating libraries. On macosx, it's empty, though.
+  OPENJDK_BUILD_CPU_LIBDIR="/$OPENJDK_BUILD_CPU_LEGACY_LIB"
+  if test "x$OPENJDK_BUILD_OS" = xmacosx; then
+    OPENJDK_BUILD_CPU_LIBDIR=""
+  fi
+
+
+  # OPENJDK_BUILD_CPU_ISADIR is normally empty. On 64-bit Solaris systems, it is set to
+  # /amd64 or /sparcv9. This string is appended to some library paths, like this:
+  # /usr/lib${OPENJDK_BUILD_CPU_ISADIR}/libexample.so
+  OPENJDK_BUILD_CPU_ISADIR=""
+  if test "x$OPENJDK_BUILD_OS" = xsolaris; then
+    if test "x$OPENJDK_BUILD_CPU" = xx86_64; then
+      OPENJDK_BUILD_CPU_ISADIR="/amd64"
+    elif test "x$OPENJDK_BUILD_CPU" = xsparcv9; then
+      OPENJDK_BUILD_CPU_ISADIR="/sparcv9"
+    fi
+  fi
+
+
+  # Setup OPENJDK_BUILD_CPU_OSARCH, which is used to set the os.arch Java system property
+  OPENJDK_BUILD_CPU_OSARCH="$OPENJDK_BUILD_CPU"
+  if test "x$OPENJDK_BUILD_OS" = xlinux && test "x$OPENJDK_BUILD_CPU" = xx86; then
+    # On linux only, we replace x86 with i386.
+    OPENJDK_BUILD_CPU_OSARCH="i386"
+  elif test "x$OPENJDK_BUILD_OS" != xmacosx && test "x$OPENJDK_BUILD_CPU" = xx86_64; then
+    # On all platforms except macosx, we replace x86_64 with amd64.
+    OPENJDK_BUILD_CPU_OSARCH="amd64"
+  fi
+
+
   OPENJDK_BUILD_CPU_JLI="$OPENJDK_BUILD_CPU"
   if test "x$OPENJDK_BUILD_CPU" = xx86; then
     OPENJDK_BUILD_CPU_JLI="i386"
@@ -15350,47 +15571,94 @@
   fi
 
 
-  if test "x$OPENJDK_TARGET_OS" = xmacosx; then
-      OPENJDK_TARGET_OS_EXPORT_DIR=macosx
-  else
-      OPENJDK_TARGET_OS_EXPORT_DIR=${OPENJDK_TARGET_OS_TYPE}
-  fi
-
-
-  if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then
+  if test "x$OPENJDK_BUILD_OS" = xmacosx; then
+      OPENJDK_BUILD_OS_EXPORT_DIR=macosx
+  else
+      OPENJDK_BUILD_OS_EXPORT_DIR=${OPENJDK_BUILD_OS_TYPE}
+  fi
+
+
+  if test "x$OPENJDK_BUILD_CPU_BITS" = x64; then
     A_LP64="LP64:="
     # -D_LP64=1 is only set on linux and mac. Setting on windows causes diff in
     # unpack200.exe
-    if test "x$OPENJDK_TARGET_OS" = xlinux || test "x$OPENJDK_TARGET_OS" = xmacosx; then
-      ADD_LP64="-D_LP64=1"
+    if test "x$OPENJDK_BUILD_OS" = xlinux || test "x$OPENJDK_BUILD_OS" = xmacosx; then
+      OPENJDK_BUILD_ADD_LP64="-D_LP64=1"
     fi
   fi
   LP64=$A_LP64
 
-  if test "x$OPENJDK_BUILD_CPU_BITS" = x64; then
-    if test "x$OPENJDK_BUILD_OS" = xlinux || test "x$OPENJDK_BUILD_OS" = xmacosx; then
-      OPENJDK_BUILD_ADD_LP64="-D_LP64=1"
-    fi
-  fi
 
   if test "x$COMPILE_TYPE" = "xcross"; then
     # FIXME: ... or should this include reduced builds..?
-    DEFINE_CROSS_COMPILE_ARCH="CROSS_COMPILE_ARCH:=$OPENJDK_TARGET_CPU_LEGACY"
+    DEFINE_CROSS_COMPILE_ARCH="CROSS_COMPILE_ARCH:=$OPENJDK_BUILD_CPU_LEGACY"
   else
     DEFINE_CROSS_COMPILE_ARCH=""
   fi
 
 
-  # ZERO_ARCHDEF is used to enable architecture-specific code
-  case "${OPENJDK_TARGET_CPU}" in
-    ppc)     ZERO_ARCHDEF=PPC32 ;;
-    ppc64)   ZERO_ARCHDEF=PPC64 ;;
-    s390*)   ZERO_ARCHDEF=S390  ;;
-    sparc*)  ZERO_ARCHDEF=SPARC ;;
-    x86_64*) ZERO_ARCHDEF=AMD64 ;;
-    x86)     ZERO_ARCHDEF=IA32  ;;
-    *)      ZERO_ARCHDEF=$(echo "${OPENJDK_TARGET_CPU_LEGACY_LIB}" | tr a-z A-Z)
-  esac
+  # Convert openjdk platform names to hotspot names
+
+  HOTSPOT_BUILD_OS=${OPENJDK_BUILD_OS}
+  if test "x$OPENJDK_BUILD_OS" = xmacosx; then
+    HOTSPOT_BUILD_OS=bsd
+  fi
+
+
+  HOTSPOT_BUILD_OS_TYPE=${OPENJDK_BUILD_OS_TYPE}
+  if test "x$OPENJDK_BUILD_OS_TYPE" = xunix; then
+    HOTSPOT_BUILD_OS_TYPE=posix
+  fi
+
+
+  HOTSPOT_BUILD_CPU=${OPENJDK_BUILD_CPU}
+  if test "x$OPENJDK_BUILD_CPU" = xx86; then
+    HOTSPOT_BUILD_CPU=x86_32
+  elif test "x$OPENJDK_BUILD_CPU" = xsparcv9; then
+    HOTSPOT_BUILD_CPU=sparc
+  elif test "x$OPENJDK_BUILD_CPU" = xppc64; then
+    HOTSPOT_BUILD_CPU=ppc_64
+  elif test "x$OPENJDK_BUILD_CPU" = xppc64le; then
+    HOTSPOT_BUILD_CPU=ppc_64
+  fi
+
+
+  # This is identical with OPENJDK_*, but define anyway for consistency.
+  HOTSPOT_BUILD_CPU_ARCH=${OPENJDK_BUILD_CPU_ARCH}
+
+
+  # Setup HOTSPOT_BUILD_CPU_DEFINE
+  if test "x$OPENJDK_BUILD_CPU" = xx86; then
+    HOTSPOT_BUILD_CPU_DEFINE=IA32
+  elif test "x$OPENJDK_BUILD_CPU" = xx86_64; then
+    HOTSPOT_BUILD_CPU_DEFINE=AMD64
+  elif test "x$OPENJDK_BUILD_CPU" = xsparcv9; then
+    HOTSPOT_BUILD_CPU_DEFINE=SPARC
+  elif test "x$OPENJDK_BUILD_CPU" = xaarch64; then
+    HOTSPOT_BUILD_CPU_DEFINE=AARCH64
+  elif test "x$OPENJDK_BUILD_CPU" = xppc64; then
+    HOTSPOT_BUILD_CPU_DEFINE=PPC64
+  elif test "x$OPENJDK_BUILD_CPU" = xppc64le; then
+    HOTSPOT_BUILD_CPU_DEFINE=PPC64
+
+  # The cpu defines below are for zero, we don't support them directly.
+  elif test "x$OPENJDK_BUILD_CPU" = xsparc; then
+    HOTSPOT_BUILD_CPU_DEFINE=SPARC
+  elif test "x$OPENJDK_BUILD_CPU" = xppc; then
+    HOTSPOT_BUILD_CPU_DEFINE=PPC32
+  elif test "x$OPENJDK_BUILD_CPU" = xs390; then
+    HOTSPOT_BUILD_CPU_DEFINE=S390
+  elif test "x$OPENJDK_BUILD_CPU" = ss390x; then
+    HOTSPOT_BUILD_CPU_DEFINE=S390
+  fi
+
+
+
+
+  # ZERO_ARCHDEF is used to enable architecture-specific code.
+  # This is used in legacy hotspot build.
+  ZERO_ARCHDEF="$HOTSPOT_TARGET_CPU_DEFINE"
+
 
 
 
@@ -15929,98 +16197,6 @@
 $as_echo "$JDK_VARIANT" >&6; }
 
 
-
-# Check whether --with-jvm-interpreter was given.
-if test "${with_jvm_interpreter+set}" = set; then :
-  withval=$with_jvm_interpreter;
-fi
-
-
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking which interpreter of the JVM to build" >&5
-$as_echo_n "checking which interpreter of the JVM to build... " >&6; }
-  if test "x$with_jvm_interpreter" = x; then
-    JVM_INTERPRETER="template"
-  else
-    JVM_INTERPRETER="$with_jvm_interpreter"
-  fi
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $JVM_INTERPRETER" >&5
-$as_echo "$JVM_INTERPRETER" >&6; }
-
-  if test "x$JVM_INTERPRETER" != xtemplate && test "x$JVM_INTERPRETER" != xcpp; then
-    as_fn_error $? "The available JVM interpreters are: template, cpp" "$LINENO" 5
-  fi
-
-
-
-
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking which variants of the JVM to build" >&5
-$as_echo_n "checking which variants of the JVM to build... " >&6; }
-
-# Check whether --with-jvm-variants was given.
-if test "${with_jvm_variants+set}" = set; then :
-  withval=$with_jvm_variants;
-fi
-
-
-  if test "x$with_jvm_variants" = x; then
-    with_jvm_variants="server"
-  fi
-
-  JVM_VARIANTS=",$with_jvm_variants,"
-  TEST_VARIANTS=`$ECHO "$JVM_VARIANTS" | $SED -e 's/server,//' -e 's/client,//'  -e 's/minimal1,//' -e 's/zero,//' -e 's/zeroshark,//' -e 's/core,//'`
-
-  if test "x$TEST_VARIANTS" != "x,"; then
-    as_fn_error $? "The available JVM variants are: server, client, minimal1, zero, zeroshark, core" "$LINENO" 5
-  fi
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_jvm_variants" >&5
-$as_echo "$with_jvm_variants" >&6; }
-
-  JVM_VARIANT_SERVER=`$ECHO "$JVM_VARIANTS" | $SED -e '/,server,/!s/.*/false/g' -e '/,server,/s/.*/true/g'`
-  JVM_VARIANT_CLIENT=`$ECHO "$JVM_VARIANTS" | $SED -e '/,client,/!s/.*/false/g' -e '/,client,/s/.*/true/g'`
-  JVM_VARIANT_MINIMAL1=`$ECHO "$JVM_VARIANTS" | $SED -e '/,minimal1,/!s/.*/false/g' -e '/,minimal1,/s/.*/true/g'`
-  JVM_VARIANT_ZERO=`$ECHO "$JVM_VARIANTS" | $SED -e '/,zero,/!s/.*/false/g' -e '/,zero,/s/.*/true/g'`
-  JVM_VARIANT_ZEROSHARK=`$ECHO "$JVM_VARIANTS" | $SED -e '/,zeroshark,/!s/.*/false/g' -e '/,zeroshark,/s/.*/true/g'`
-  JVM_VARIANT_CORE=`$ECHO "$JVM_VARIANTS" | $SED -e '/,core,/!s/.*/false/g' -e '/,core,/s/.*/true/g'`
-
-  if test "x$JVM_VARIANT_CLIENT" = xtrue; then
-    if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then
-      as_fn_error $? "You cannot build a client JVM for a 64-bit machine." "$LINENO" 5
-    fi
-  fi
-  if test "x$JVM_VARIANT_MINIMAL1" = xtrue; then
-    if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then
-      as_fn_error $? "You cannot build a minimal JVM for a 64-bit machine." "$LINENO" 5
-    fi
-  fi
-
-  # Replace the commas with AND for use in the build directory name.
-  ANDED_JVM_VARIANTS=`$ECHO "$JVM_VARIANTS" | $SED -e 's/^,//' -e 's/,$//' -e 's/,/AND/g'`
-  COUNT_VARIANTS=`$ECHO "$JVM_VARIANTS" | $SED -e 's/server,/1/' -e 's/client,/1/' -e 's/minimal1,/1/' -e 's/zero,/1/' -e 's/zeroshark,/1/' -e 's/core,/1/'`
-  if test "x$COUNT_VARIANTS" != "x,1"; then
-    BUILDING_MULTIPLE_JVM_VARIANTS=yes
-  else
-    BUILDING_MULTIPLE_JVM_VARIANTS=no
-  fi
-
-  if test "x$JVM_VARIANT_ZERO" = xtrue && test "x$BUILDING_MULTIPLE_JVM_VARIANTS" = xyes; then
-    as_fn_error $? "You cannot build multiple variants with zero." "$LINENO" 5
-  fi
-
-
-
-
-
-
-
-
-
-  if test "x$OPENJDK_TARGET_OS" = "xmacosx"; then
-    MACOSX_UNIVERSAL="true"
-  fi
-
-
-
-
   DEBUG_LEVEL="release"
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking which debug level to use" >&5
 $as_echo_n "checking which debug level to use... " >&6; }
@@ -16056,105 +16232,88 @@
     as_fn_error $? "Allowed debug levels are: release, fastdebug, slowdebug and optimized" "$LINENO" 5
   fi
 
-
-  case $DEBUG_LEVEL in
-    release )
-      VARIANT="OPT"
-      FASTDEBUG="false"
-      DEBUG_CLASSFILES="false"
-      BUILD_VARIANT_RELEASE=""
-      HOTSPOT_DEBUG_LEVEL="product"
-      HOTSPOT_EXPORT="product"
-      ;;
-    fastdebug )
-      VARIANT="DBG"
-      FASTDEBUG="true"
-      DEBUG_CLASSFILES="true"
-      BUILD_VARIANT_RELEASE="-fastdebug"
-      HOTSPOT_DEBUG_LEVEL="fastdebug"
-      HOTSPOT_EXPORT="fastdebug"
-      ;;
-    slowdebug )
-      VARIANT="DBG"
-      FASTDEBUG="false"
-      DEBUG_CLASSFILES="true"
-      BUILD_VARIANT_RELEASE="-debug"
-      HOTSPOT_DEBUG_LEVEL="debug"
-      HOTSPOT_EXPORT="debug"
-      ;;
-    optimized )
-      VARIANT="OPT"
-      FASTDEBUG="false"
-      DEBUG_CLASSFILES="false"
-      BUILD_VARIANT_RELEASE="-optimized"
-      HOTSPOT_DEBUG_LEVEL="optimized"
-      HOTSPOT_EXPORT="optimized"
-      ;;
-  esac
-
-  # The debug level 'optimized' is a little special because it is currently only
-  # applicable to the HotSpot build where it means to build a completely
-  # optimized version of the VM without any debugging code (like for the
-  # 'release' debug level which is called 'product' in the HotSpot build) but
-  # with the exception that it can contain additional code which is otherwise
-  # protected by '#ifndef PRODUCT' macros. These 'optimized' builds are used to
-  # test new and/or experimental features which are not intended for customer
-  # shipment. Because these new features need to be tested and benchmarked in
-  # real world scenarios, we want to build the containing JDK at the 'release'
-  # debug level.
+  # Translate DEBUG_LEVEL to debug level used by Hotspot
+  HOTSPOT_DEBUG_LEVEL="$DEBUG_LEVEL"
+  if test "x$DEBUG_LEVEL" = xrelease; then
+    HOTSPOT_DEBUG_LEVEL="product"
+  elif test "x$DEBUG_LEVEL" = xslowdebug; then
+    HOTSPOT_DEBUG_LEVEL="debug"
+  fi
+
   if test "x$DEBUG_LEVEL" = xoptimized; then
+    # The debug level 'optimized' is a little special because it is currently only
+    # applicable to the HotSpot build where it means to build a completely
+    # optimized version of the VM without any debugging code (like for the
+    # 'release' debug level which is called 'product' in the HotSpot build) but
+    # with the exception that it can contain additional code which is otherwise
+    # protected by '#ifndef PRODUCT' macros. These 'optimized' builds are used to
+    # test new and/or experimental features which are not intended for customer
+    # shipment. Because these new features need to be tested and benchmarked in
+    # real world scenarios, we want to build the containing JDK at the 'release'
+    # debug level.
     DEBUG_LEVEL="release"
   fi
 
-  #####
-  # Generate the legacy makefile targets for hotspot.
-  # The hotspot api for selecting the build artifacts, really, needs to be improved.
-  # JDK-7195896 will fix this on the hotspot side by using the JVM_VARIANT_* variables to
-  # determine what needs to be built. All we will need to set here is all_product, all_fastdebug etc
-  # But until then ...
-  HOTSPOT_TARGET=""
-
-  if test "x$JVM_VARIANT_SERVER" = xtrue; then
-    HOTSPOT_TARGET="$HOTSPOT_TARGET${HOTSPOT_DEBUG_LEVEL} "
-  fi
-
-  if test "x$JVM_VARIANT_CLIENT" = xtrue; then
-    HOTSPOT_TARGET="$HOTSPOT_TARGET${HOTSPOT_DEBUG_LEVEL}1 "
-  fi
-
-  if test "x$JVM_VARIANT_MINIMAL1" = xtrue; then
-    HOTSPOT_TARGET="$HOTSPOT_TARGET${HOTSPOT_DEBUG_LEVEL}minimal1 "
-  fi
-
-  if test "x$JVM_VARIANT_ZERO" = xtrue; then
-    HOTSPOT_TARGET="$HOTSPOT_TARGET${HOTSPOT_DEBUG_LEVEL}zero "
-  fi
-
-  if test "x$JVM_VARIANT_ZEROSHARK" = xtrue; then
-    HOTSPOT_TARGET="$HOTSPOT_TARGET${HOTSPOT_DEBUG_LEVEL}shark "
-  fi
-
-  if test "x$JVM_VARIANT_CORE" = xtrue; then
-    HOTSPOT_TARGET="$HOTSPOT_TARGET${HOTSPOT_DEBUG_LEVEL}core "
-  fi
-
-  HOTSPOT_TARGET="$HOTSPOT_TARGET docs export_$HOTSPOT_EXPORT"
-
-  # On Macosx universal binaries are produced, but they only contain
-  # 64 bit intel. This invalidates control of which jvms are built
-  # from configure, but only server is valid anyway. Fix this
-  # when hotspot makefiles are rewritten.
-  if test "x$MACOSX_UNIVERSAL" = xtrue; then
-    HOTSPOT_TARGET=universal_${HOTSPOT_EXPORT}
-  fi
-
-  #####
-
-
-
-
-
-
+
+
+
+
+
+# Check whether --with-jvm-variants was given.
+if test "${with_jvm_variants+set}" = set; then :
+  withval=$with_jvm_variants;
+fi
+
+
+  if test "x$with_jvm_variants" = x; then
+    with_jvm_variants="server"
+  fi
+  JVM_VARIANTS_OPT="$with_jvm_variants"
+
+  # Has the user listed more than one variant?
+  # Additional [] needed to keep m4 from mangling shell constructs.
+  if  [[ "$JVM_VARIANTS_OPT" =~ "," ]] ; then
+    BUILDING_MULTIPLE_JVM_VARIANTS=true
+  else
+    BUILDING_MULTIPLE_JVM_VARIANTS=false
+  fi
+  # Replace the commas with AND for use in the build directory name.
+  JVM_VARIANTS_WITH_AND=`$ECHO "$JVM_VARIANTS_OPT" | $SED -e 's/,/AND/g'`
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking which variants of the JVM to build" >&5
+$as_echo_n "checking which variants of the JVM to build... " >&6; }
+  # JVM_VARIANTS is a space-separated list.
+  # Also use minimal, not minimal1 (which is kept for backwards compatibility).
+  JVM_VARIANTS=`$ECHO $JVM_VARIANTS_OPT | $SED -e 's/,/ /g' -e 's/minimal1/minimal/'`
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $JVM_VARIANTS" >&5
+$as_echo "$JVM_VARIANTS" >&6; }
+
+  # Check that the selected variants are valid
+
+  # grep filter function inspired by a comment to http://stackoverflow.com/a/1617326
+  INVALID_VARIANTS=`$GREP -Fvx "${VALID_JVM_VARIANTS// /$'\n'}" <<< "${JVM_VARIANTS// /$'\n'}"`
+  if test "x$INVALID_VARIANTS" != x; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: Unknown variant(s) specified: $INVALID_VARIANTS" >&5
+$as_echo "$as_me: Unknown variant(s) specified: $INVALID_VARIANTS" >&6;}
+    as_fn_error $? "The available JVM variants are: $VALID_JVM_VARIANTS" "$LINENO" 5
+  fi
+
+  # All "special" variants share the same output directory ("server")
+  VALID_MULTIPLE_JVM_VARIANTS="server client minimal"
+  INVALID_MULTIPLE_VARIANTS=`$GREP -Fvx "${VALID_MULTIPLE_JVM_VARIANTS// /$'\n'}" <<< "${JVM_VARIANTS// /$'\n'}"`
+  if  test "x$INVALID_MULTIPLE_VARIANTS" != x && test "x$BUILDING_MULTIPLE_JVM_VARIANTS" = xtrue; then
+    as_fn_error $? "You cannot build multiple variants with anything else than $VALID_MULTIPLE_JVM_VARIANTS." "$LINENO" 5
+  fi
+
+
+
+
+  if   [[ " $JVM_VARIANTS " =~ " zero " ]]   ||   [[ " $JVM_VARIANTS " =~ " zeroshark " ]]  ; then
+    # zero behaves as a platform and rewrites these values. This is really weird. :(
+    # We are guaranteed that we do not build any other variants when building zero.
+    HOTSPOT_TARGET_CPU=zero
+    HOTSPOT_TARGET_CPU_ARCH=zero
+  fi
 
 
 # With basic setup done, call the custom early hook.
@@ -16603,8 +16762,8 @@
 
 
   if test "x$OPENJDK_BUILD_OS" = "xsolaris"; then
-    # Add extra search paths on solaris for utilities like ar and as etc...
-    PATH="$PATH:/usr/ccs/bin:/usr/sfw/bin:/opt/csw/bin"
+    # 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
@@ -16643,7 +16802,7 @@
     if test "x${CONF_NAME}" = x; then
       { $as_echo "$as_me:${as_lineno-$LINENO}: result: in default location" >&5
 $as_echo "in default location" >&6; }
-      CONF_NAME="${OPENJDK_TARGET_OS}-${OPENJDK_TARGET_CPU}-${JDK_VARIANT}-${ANDED_JVM_VARIANTS}-${DEBUG_LEVEL}"
+      CONF_NAME="${OPENJDK_TARGET_OS}-${OPENJDK_TARGET_CPU}-${JDK_VARIANT}-${JVM_VARIANTS_WITH_AND}-${DEBUG_LEVEL}"
     else
       { $as_echo "$as_me:${as_lineno-$LINENO}: result: in build directory with custom name" >&5
 $as_echo "in build directory with custom name" >&6; }
@@ -22143,6 +22302,203 @@
   # Publish this variable in the help.
 
 
+  if [ -z "${DTRACE+x}" ]; then
+    # The variable is not set by user, try to locate tool using the code snippet
+    for ac_prog in dtrace
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_DTRACE+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $DTRACE in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_DTRACE="$DTRACE" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_DTRACE="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  ;;
+esac
+fi
+DTRACE=$ac_cv_path_DTRACE
+if test -n "$DTRACE"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DTRACE" >&5
+$as_echo "$DTRACE" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$DTRACE" && break
+done
+
+  else
+    # The variable is set, but is it from the command line or the environment?
+
+    # Try to remove the string !DTRACE! from our list.
+    try_remove_var=${CONFIGURE_OVERRIDDEN_VARIABLES//!DTRACE!/}
+    if test "x$try_remove_var" = "x$CONFIGURE_OVERRIDDEN_VARIABLES"; then
+      # If it failed, the variable was not from the command line. Ignore it,
+      # but warn the user (except for BASH, which is always set by the calling BASH).
+      if test "xDTRACE" != xBASH; then
+        { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Ignoring value of DTRACE from the environment. Use command line variables instead." >&5
+$as_echo "$as_me: WARNING: Ignoring value of DTRACE from the environment. Use command line variables instead." >&2;}
+      fi
+      # Try to locate tool using the code snippet
+      for ac_prog in dtrace
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_DTRACE+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $DTRACE in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_DTRACE="$DTRACE" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_DTRACE="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  ;;
+esac
+fi
+DTRACE=$ac_cv_path_DTRACE
+if test -n "$DTRACE"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DTRACE" >&5
+$as_echo "$DTRACE" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$DTRACE" && break
+done
+
+    else
+      # If it succeeded, then it was overridden by the user. We will use it
+      # for the tool.
+
+      # First remove it from the list of overridden variables, so we can test
+      # for unknown variables in the end.
+      CONFIGURE_OVERRIDDEN_VARIABLES="$try_remove_var"
+
+      # Check if we try to supply an empty value
+      if test "x$DTRACE" = x; then
+        { $as_echo "$as_me:${as_lineno-$LINENO}: Setting user supplied tool DTRACE= (no value)" >&5
+$as_echo "$as_me: Setting user supplied tool DTRACE= (no value)" >&6;}
+        { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DTRACE" >&5
+$as_echo_n "checking for DTRACE... " >&6; }
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: disabled" >&5
+$as_echo "disabled" >&6; }
+      else
+        # Check if the provided tool contains a complete path.
+        tool_specified="$DTRACE"
+        tool_basename="${tool_specified##*/}"
+        if test "x$tool_basename" = "x$tool_specified"; then
+          # A command without a complete path is provided, search $PATH.
+          { $as_echo "$as_me:${as_lineno-$LINENO}: Will search for user supplied tool DTRACE=$tool_basename" >&5
+$as_echo "$as_me: Will search for user supplied tool DTRACE=$tool_basename" >&6;}
+          # Extract the first word of "$tool_basename", so it can be a program name with args.
+set dummy $tool_basename; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_DTRACE+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $DTRACE in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_DTRACE="$DTRACE" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_DTRACE="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  ;;
+esac
+fi
+DTRACE=$ac_cv_path_DTRACE
+if test -n "$DTRACE"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DTRACE" >&5
+$as_echo "$DTRACE" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+          if test "x$DTRACE" = x; then
+            as_fn_error $? "User supplied tool $tool_basename could not be found" "$LINENO" 5
+          fi
+        else
+          # Otherwise we believe it is a complete path. Use it as it is.
+          { $as_echo "$as_me:${as_lineno-$LINENO}: Will use user supplied tool DTRACE=$tool_specified" >&5
+$as_echo "$as_me: Will use user supplied tool DTRACE=$tool_specified" >&6;}
+          { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DTRACE" >&5
+$as_echo_n "checking for DTRACE... " >&6; }
+          if test ! -x "$tool_specified"; then
+            { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
+$as_echo "not found" >&6; }
+            as_fn_error $? "User supplied tool DTRACE=$tool_specified does not exist or is not executable" "$LINENO" 5
+          fi
+          { $as_echo "$as_me:${as_lineno-$LINENO}: result: $tool_specified" >&5
+$as_echo "$tool_specified" >&6; }
+        fi
+      fi
+    fi
+
+  fi
+
+
+
+
+  # Publish this variable in the help.
+
+
   if [ -z "${PATCH+x}" ]; then
     # The variable is not set by user, try to locate tool using the code snippet
     for ac_prog in gpatch patch
@@ -23422,10 +23778,7 @@
 
   # Should we build the serviceability agent (SA)?
   INCLUDE_SA=true
-  if test "x$JVM_VARIANT_ZERO" = xtrue ; then
-    INCLUDE_SA=false
-  fi
-  if test "x$JVM_VARIANT_ZEROSHARK" = xtrue ; then
+  if   [[ " $JVM_VARIANTS " =~ " zero " ]]   ||   [[ " $JVM_VARIANTS " =~ " zeroshark " ]]  ; then
     INCLUDE_SA=false
   fi
   if test "x$OPENJDK_TARGET_OS" = xaix ; then
@@ -23487,22 +23840,6 @@
 
 
 
-  # Control wether Hotspot runs Queens test after build.
-  # Check whether --enable-hotspot-test-in-build was given.
-if test "${enable_hotspot_test_in_build+set}" = set; then :
-  enableval=$enable_hotspot_test_in_build;
-else
-  enable_hotspot_test_in_build=no
-fi
-
-  if test "x$enable_hotspot_test_in_build" = "xyes"; then
-    TEST_IN_BUILD=true
-  else
-    TEST_IN_BUILD=false
-  fi
-
-
-
   # Warn user that old version arguments are deprecated.
 
 
@@ -23553,6 +23890,7 @@
 
 
 
+
   # Override version from arguments
 
   # If --with-version-string is set, process it first. It is possible to
@@ -30625,6 +30963,10 @@
 
 
 
+
+
+
+
   # The global CFLAGS and LDLAGS variables are used by configure tests and
   # should include the extra parameters
   CFLAGS="$EXTRA_CFLAGS"
@@ -46752,6 +47094,17 @@
   fi
 
 
+  # Setup hotspot lecagy names for toolchains
+  HOTSPOT_TOOLCHAIN_TYPE=$TOOLCHAIN_TYPE
+  if test "x$TOOLCHAIN_TYPE" = xclang; then
+    HOTSPOT_TOOLCHAIN_TYPE=gcc
+  elif test "x$TOOLCHAIN_TYPE" = xsolstudio; then
+    HOTSPOT_TOOLCHAIN_TYPE=sparcWorks
+  elif test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
+    HOTSPOT_TOOLCHAIN_TYPE=visCPP
+  fi
+
+
 
 # Setup the JTReg Regression Test Harness.
 
@@ -47231,8 +47584,10 @@
   # On Windows, we need to set RC flags.
   if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
     RC_FLAGS="-nologo -l0x409"
+    JVM_RCFLAGS="-nologo"
     if test "x$DEBUG_LEVEL" = xrelease; then
       RC_FLAGS="$RC_FLAGS -DNDEBUG"
+      JVM_RCFLAGS="$JVM_RCFLAGS -DNDEBUG"
     fi
 
     # The version variables used to create RC_FLAGS may be overridden
@@ -47248,7 +47603,18 @@
         -D\"JDK_COPYRIGHT=Copyright \xA9 $COPYRIGHT_YEAR\" \
         -D\"JDK_NAME=\$(PRODUCT_NAME) \$(JDK_RC_PLATFORM_NAME) \$(VERSION_MAJOR)\" \
         -D\"JDK_FVER=\$(subst .,\$(COMMA),\$(VERSION_NUMBER_FOUR_POSITIONS))\""
-  fi
+
+    JVM_RCFLAGS="$JVM_RCFLAGS \
+        -D\"HS_BUILD_ID=\$(VERSION_STRING)\" \
+        -D\"HS_COMPANY=\$(COMPANY_NAME)\" \
+        -D\"JDK_DOTVER=\$(VERSION_NUMBER_FOUR_POSITIONS)\" \
+        -D\"HS_COPYRIGHT=Copyright $COPYRIGHT_YEAR\" \
+        -D\"HS_NAME=\$(PRODUCT_NAME) \$(VERSION_SHORT)\" \
+        -D\"JDK_VER=\$(subst .,\$(COMMA),\$(VERSION_NUMBER_FOUR_POSITIONS))\" \
+        -D\"HS_FNAME=jvm.dll\" \
+        -D\"HS_INTERNAL_NAME=jvm\""
+  fi
+
 
 
   if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
@@ -47416,6 +47782,10 @@
   CXXFLAGS_JDK="${CXXFLAGS_JDK}${ADDED_CXXFLAGS}"
   LDFLAGS_JDK="${LDFLAGS_JDK}${ADDED_LDFLAGS}"
 
+  JVM_CFLAGS="$JVM_CFLAGS $ADDED_CFLAGS"
+  JVM_LDFLAGS="$JVM_LDFLAGS $ADDED_LDFLAGS"
+  JVM_ASFLAGS="$JVM_ASFLAGS $ADDED_CFLAGS"
+
   elif test "x$COMPILE_TYPE" = xreduced; then
     if test "x$OPENJDK_TARGET_OS_TYPE" = xunix; then
       # Specify -m if running reduced on unix platforms
@@ -47436,7 +47806,16 @@
   CXXFLAGS_JDK="${CXXFLAGS_JDK}${ADDED_CXXFLAGS}"
   LDFLAGS_JDK="${LDFLAGS_JDK}${ADDED_LDFLAGS}"
 
-    fi
+  JVM_CFLAGS="$JVM_CFLAGS $ADDED_CFLAGS"
+  JVM_LDFLAGS="$JVM_LDFLAGS $ADDED_LDFLAGS"
+  JVM_ASFLAGS="$JVM_ASFLAGS $ADDED_CFLAGS"
+
+    fi
+  fi
+  if test "x$OPENJDK_TARGET_OS" = xmacosx; then
+    JVM_CFLAGS="$JVM_CFLAGS ${COMPILER_TARGET_BITS_FLAG}${OPENJDK_TARGET_CPU_BITS}"
+    JVM_LDFLAGS="$JVM_LDFLAGS ${COMPILER_TARGET_BITS_FLAG}${OPENJDK_TARGET_CPU_BITS}"
+    JVM_ASFLAGS="$JVM_ASFLAGS ${COMPILER_TARGET_BITS_FLAG}${OPENJDK_TARGET_CPU_BITS}"
   fi
 
   # Make compilation sanity check
@@ -47562,6 +47941,10 @@
   CXXFLAGS_JDK="${CXXFLAGS_JDK}${ADDED_CXXFLAGS}"
   LDFLAGS_JDK="${LDFLAGS_JDK}${ADDED_LDFLAGS}"
 
+  JVM_CFLAGS="$JVM_CFLAGS $ADDED_CFLAGS"
+  JVM_LDFLAGS="$JVM_LDFLAGS $ADDED_LDFLAGS"
+  JVM_ASFLAGS="$JVM_ASFLAGS $ADDED_CFLAGS"
+
 
       # We have to unset 'ac_cv_sizeof_int_p' first, otherwise AC_CHECK_SIZEOF will use the previously cached value!
       unset ac_cv_sizeof_int_p
@@ -47908,6 +48291,7 @@
         SHARED_LIBRARY_FLAGS ='-undefined dynamic_lookup'
       else
         SHARED_LIBRARY_FLAGS="-dynamiclib -compatibility_version 1.0.0 -current_version 1.0.0 $PICFLAG"
+        JVM_CFLAGS="$JVM_CFLAGS $PICFLAG"
       fi
       SET_EXECUTABLE_ORIGIN='-Wl,-rpath,@loader_path/.'
       SET_SHARED_LIBRARY_ORIGIN="$SET_EXECUTABLE_ORIGIN"
@@ -47933,6 +48317,10 @@
       SET_SHARED_LIBRARY_ORIGIN="$SET_EXECUTABLE_ORIGIN"
       SET_SHARED_LIBRARY_NAME='-Wl,-install_name,@rpath/$1'
       SET_SHARED_LIBRARY_MAPFILE='-Wl,-exported_symbols_list,$1'
+
+      if test "x$STATIC_BUILD" = xfalse; then
+        JVM_CFLAGS="$JVM_CFLAGS -fPIC"
+      fi
     else
       # Default works for linux, might work on other platforms as well.
       PICFLAG='-fPIC'
@@ -47992,11 +48380,6 @@
 
 
 
-  if test "x$OPENJDK_TARGET_OS" = xsolaris; then
-    CFLAGS_JDK="${CFLAGS_JDK} -D__solaris__"
-    CXXFLAGS_JDK="${CXXFLAGS_JDK} -D__solaris__"
-    CFLAGS_JDKLIB_EXTRA='-xstrconst'
-  fi
   # The (cross) compiler is now configured, we can now test capabilities
   # of the target platform.
 
@@ -48054,6 +48437,22 @@
 
 
 
+  # Debug symbols for JVM_CFLAGS
+  if test "x$TOOLCHAIN_TYPE" = xsolstudio; then
+    JVM_CFLAGS_SYMBOLS="$JVM_CFLAGS_SYMBOLS -xs"
+    if test "x$DEBUG_LEVEL" = xslowdebug; then
+      JVM_CFLAGS_SYMBOLS="$JVM_CFLAGS_SYMBOLS -g"
+    else
+      # -g0 does not disable inlining, which -g does.
+      JVM_CFLAGS_SYMBOLS="$JVM_CFLAGS_SYMBOLS -g0"
+    fi
+  elif test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
+    JVM_CFLAGS_SYMBOLS="$JVM_CFLAGS_SYMBOLS -Z7 -d2Zi+"
+  else
+    JVM_CFLAGS_SYMBOLS="$JVM_CFLAGS_SYMBOLS -g"
+  fi
+
+
   # bounds, memory and behavior checking options
   if test "x$TOOLCHAIN_TYPE" = xgcc; then
     case $DEBUG_LEVEL in
@@ -48064,7 +48463,7 @@
       # no adjustment
       ;;
     slowdebug )
-      # FIXME: By adding this to C(XX)FLAGS_DEBUG_OPTIONS it
+      # FIXME: By adding this to C(XX)FLAGS_DEBUG_OPTIONS/JVM_CFLAGS_SYMBOLS it
       # get's added conditionally on whether we produce debug symbols or not.
       # This is most likely not really correct.
 
@@ -48339,40 +48738,59 @@
 
       CFLAGS_DEBUG_OPTIONS="$STACK_PROTECTOR_CFLAG --param ssp-buffer-size=1"
       CXXFLAGS_DEBUG_OPTIONS="$STACK_PROTECTOR_CFLAG --param ssp-buffer-size=1"
+      if test "x$STACK_PROTECTOR_CFLAG" != x; then
+        JVM_CFLAGS_SYMBOLS="$JVM_CFLAGS_SYMBOLS $STACK_PROTECTOR_CFLAG --param ssp-buffer-size=1"
+      fi
       ;;
     esac
   fi
 
+  if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
+    if test "x$DEBUG_LEVEL" != xrelease; then
+      if test "x$OPENJDK_TARGET_CPU" = xx86_64; then
+        JVM_CFLAGS="$JVM_CFLAGS -homeparams"
+      fi
+    fi
+  fi
+
   # Optimization levels
   if test "x$TOOLCHAIN_TYPE" = xsolstudio; then
     CC_HIGHEST="$CC_HIGHEST -fns -fsimple -fsingle -xbuiltin=%all -xdepend -xrestrict -xlibmil"
 
     if test "x$OPENJDK_TARGET_CPU_ARCH" = "xx86"; then
       # FIXME: seems we always set -xregs=no%frameptr; put it elsewhere more global?
+      C_O_FLAG_HIGHEST_JVM="-xO4"
       C_O_FLAG_HIGHEST="-xO4 -Wu,-O4~yz $CC_HIGHEST -xalias_level=basic -xregs=no%frameptr"
       C_O_FLAG_HI="-xO4 -Wu,-O4~yz -xregs=no%frameptr"
       C_O_FLAG_NORM="-xO2 -Wu,-O2~yz -xregs=no%frameptr"
       C_O_FLAG_DEBUG="-xregs=no%frameptr"
+      C_O_FLAG_DEBUG_JVM=""
       C_O_FLAG_NONE="-xregs=no%frameptr"
+      CXX_O_FLAG_HIGHEST_JVM="-xO4"
       CXX_O_FLAG_HIGHEST="-xO4 -Qoption ube -O4~yz $CC_HIGHEST -xregs=no%frameptr"
       CXX_O_FLAG_HI="-xO4 -Qoption ube -O4~yz -xregs=no%frameptr"
       CXX_O_FLAG_NORM="-xO2 -Qoption ube -O2~yz -xregs=no%frameptr"
       CXX_O_FLAG_DEBUG="-xregs=no%frameptr"
+      CXX_O_FLAG_DEBUG_JVM=""
       CXX_O_FLAG_NONE="-xregs=no%frameptr"
       if test "x$OPENJDK_TARGET_CPU_BITS" = "x32"; then
         C_O_FLAG_HIGHEST="$C_O_FLAG_HIGHEST -xchip=pentium"
         CXX_O_FLAG_HIGHEST="$CXX_O_FLAG_HIGHEST -xchip=pentium"
       fi
     elif test "x$OPENJDK_TARGET_CPU_ARCH" = "xsparc"; then
+      C_O_FLAG_HIGHEST_JVM="-xO4"
       C_O_FLAG_HIGHEST="-xO4 -Wc,-Qrm-s -Wc,-Qiselect-T0 $CC_HIGHEST -xalias_level=basic -xprefetch=auto,explicit -xchip=ultra"
       C_O_FLAG_HI="-xO4 -Wc,-Qrm-s -Wc,-Qiselect-T0"
       C_O_FLAG_NORM="-xO2 -Wc,-Qrm-s -Wc,-Qiselect-T0"
       C_O_FLAG_DEBUG=""
+      C_O_FLAG_DEBUG_JVM=""
       C_O_FLAG_NONE=""
+      CXX_O_FLAG_HIGHEST_JVM="-xO4"
       CXX_O_FLAG_HIGHEST="-xO4 -Qoption cg -Qrm-s -Qoption cg -Qiselect-T0 $CC_HIGHEST -xprefetch=auto,explicit -xchip=ultra"
       CXX_O_FLAG_HI="-xO4 -Qoption cg -Qrm-s -Qoption cg -Qiselect-T0"
       CXX_O_FLAG_NORM="-xO2 -Qoption cg -Qrm-s -Qoption cg -Qiselect-T0"
       CXX_O_FLAG_DEBUG=""
+      CXX_O_FLAG_DEBUG_JVM=""
       CXX_O_FLAG_NONE=""
     fi
   else
@@ -48382,48 +48800,75 @@
       if test "x$OPENJDK_TARGET_OS" = xmacosx; then
         # On MacOSX we optimize for size, something
         # we should do for all platforms?
+        C_O_FLAG_HIGHEST_JVM="-Os"
         C_O_FLAG_HIGHEST="-Os"
         C_O_FLAG_HI="-Os"
         C_O_FLAG_NORM="-Os"
-      else
+        C_O_FLAG_SIZE="-Os"
+      else
+        C_O_FLAG_HIGHEST_JVM="-O3"
         C_O_FLAG_HIGHEST="-O3"
         C_O_FLAG_HI="-O3"
         C_O_FLAG_NORM="-O2"
+        C_O_FLAG_SIZE="-Os"
       fi
       C_O_FLAG_DEBUG="-O0"
+      if test "x$OPENJDK_TARGET_OS" = xmacosx; then
+        C_O_FLAG_DEBUG_JVM=""
+      elif test "x$OPENJDK_TARGET_OS" = xlinux; then
+        C_O_FLAG_DEBUG_JVM="-O0"
+      fi
       C_O_FLAG_NONE="-O0"
     elif test "x$TOOLCHAIN_TYPE" = xclang; then
       if test "x$OPENJDK_TARGET_OS" = xmacosx; then
         # On MacOSX we optimize for size, something
         # we should do for all platforms?
+        C_O_FLAG_HIGHEST_JVM="-Os"
         C_O_FLAG_HIGHEST="-Os"
         C_O_FLAG_HI="-Os"
         C_O_FLAG_NORM="-Os"
-      else
+        C_O_FLAG_SIZE="-Os"
+      else
+        C_O_FLAG_HIGHEST_JVM="-O3"
         C_O_FLAG_HIGHEST="-O3"
         C_O_FLAG_HI="-O3"
         C_O_FLAG_NORM="-O2"
+        C_O_FLAG_SIZE="-Os"
       fi
       C_O_FLAG_DEBUG="-O0"
+      if test "x$OPENJDK_TARGET_OS" = xmacosx; then
+        C_O_FLAG_DEBUG_JVM=""
+      elif test "x$OPENJDK_TARGET_OS" = xlinux; then
+        C_O_FLAG_DEBUG_JVM="-O0"
+      fi
       C_O_FLAG_NONE="-O0"
     elif test "x$TOOLCHAIN_TYPE" = xxlc; then
+      C_O_FLAG_HIGHEST_JVM="-O3"
       C_O_FLAG_HIGHEST="-O3"
       C_O_FLAG_HI="-O3 -qstrict"
       C_O_FLAG_NORM="-O2"
       C_O_FLAG_DEBUG="-qnoopt"
+      # FIXME: Value below not verified.
+      C_O_FLAG_DEBUG_JVM=""
       C_O_FLAG_NONE="-qnoopt"
     elif test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
+      C_O_FLAG_HIGHEST_JVM="-O2 -Oy-"
       C_O_FLAG_HIGHEST="-O2"
       C_O_FLAG_HI="-O1"
       C_O_FLAG_NORM="-O1"
       C_O_FLAG_DEBUG="-Od"
+      C_O_FLAG_DEBUG_JVM=""
       C_O_FLAG_NONE="-Od"
-    fi
+      C_O_FLAG_SIZE="-Os"
+    fi
+    CXX_O_FLAG_HIGHEST_JVM="$C_O_FLAG_HIGHEST_JVM"
     CXX_O_FLAG_HIGHEST="$C_O_FLAG_HIGHEST"
     CXX_O_FLAG_HI="$C_O_FLAG_HI"
     CXX_O_FLAG_NORM="$C_O_FLAG_NORM"
     CXX_O_FLAG_DEBUG="$C_O_FLAG_DEBUG"
+    CXX_O_FLAG_DEBUG_JVM="$C_O_FLAG_DEBUG_JVM"
     CXX_O_FLAG_NONE="$C_O_FLAG_NONE"
+    CXX_O_FLAG_SIZE="$C_O_FLAG_SIZE"
   fi
 
   # Adjust optimization flags according to debug level.
@@ -48438,12 +48883,16 @@
       ;;
     slowdebug )
       # Disable optimization
+      C_O_FLAG_HIGHEST_JVM="$C_O_FLAG_DEBUG_JVM"
       C_O_FLAG_HIGHEST="$C_O_FLAG_DEBUG"
       C_O_FLAG_HI="$C_O_FLAG_DEBUG"
       C_O_FLAG_NORM="$C_O_FLAG_DEBUG"
+      C_O_FLAG_SIZE="$C_O_FLAG_DEBUG"
+      CXX_O_FLAG_HIGHEST_JVM="$CXX_O_FLAG_DEBUG_JVM"
       CXX_O_FLAG_HIGHEST="$CXX_O_FLAG_DEBUG"
       CXX_O_FLAG_HI="$CXX_O_FLAG_DEBUG"
       CXX_O_FLAG_NORM="$CXX_O_FLAG_DEBUG"
+      CXX_O_FLAG_SIZE="$CXX_O_FLAG_DEBUG"
       ;;
   esac
 
@@ -48459,6 +48908,12 @@
 
 
 
+
+
+
+
+
+
   # Special extras...
   if test "x$TOOLCHAIN_TYPE" = xsolstudio; then
     if test "x$OPENJDK_TARGET_CPU_ARCH" = "xsparc"; then
@@ -48570,10 +49025,23 @@
     CXXFLAGS_JDK="${CXXFLAGS_JDK} ${CXXSTD_CXXFLAG}"
 
   fi
-
-  CFLAGS_JDK="${CFLAGS_JDK} $EXTRA_CFLAGS"
-  CXXFLAGS_JDK="${CXXFLAGS_JDK} $EXTRA_CXXFLAGS"
-  LDFLAGS_JDK="${LDFLAGS_JDK} $EXTRA_LDFLAGS"
+  if test "x$OPENJDK_TARGET_OS" = xsolaris; then
+    CFLAGS_JDK="${CFLAGS_JDK} -D__solaris__"
+    CXXFLAGS_JDK="${CXXFLAGS_JDK} -D__solaris__"
+    CFLAGS_JDKLIB_EXTRA='-xstrconst'
+    CFLAGS_JDK="${CFLAGS_JDK} -qchars=signed -qfullpath -qsaveopt"
+    CXXFLAGS_JDK="${CXXFLAGS_JDK} -qchars=signed -qfullpath -qsaveopt"
+  fi
+
+  if test "x$OPENJDK_TARGET_OS" = xsolaris; then
+    CFLAGS_JDK="${CFLAGS_JDK} -D__solaris__"
+    CXXFLAGS_JDK="${CXXFLAGS_JDK} -D__solaris__"
+    CFLAGS_JDKLIB_EXTRA='-xstrconst'
+  fi
+
+  CFLAGS_JDK="${CFLAGS_JDK} ${EXTRA_CFLAGS}"
+  CXXFLAGS_JDK="${CXXFLAGS_JDK} ${EXTRA_CXXFLAGS}"
+  LDFLAGS_JDK="${LDFLAGS_JDK} ${EXTRA_LDFLAGS}"
 
   ###############################################################################
   #
@@ -48586,9 +49054,13 @@
   #    CXXFLAGS_JDK  - C++ Compiler flags
   #    COMMON_CCXXFLAGS_JDK - common to C and C++
   if test "x$TOOLCHAIN_TYPE" = xgcc; then
+    JVM_CFLAGS="$JVM_CFLAGS -D_GNU_SOURCE"
+    JVM_CFLAGS="$JVM_CFLAGS -D_REENTRANT"
+    JVM_CFLAGS="$JVM_CFLAGS -fcheck-new"
     if test "x$OPENJDK_TARGET_CPU" = xx86; then
       # Force compatibility with i586 on 32 bit intel platforms.
       COMMON_CCXXFLAGS="${COMMON_CCXXFLAGS} -march=i586"
+      JVM_CFLAGS="$JVM_CFLAGS -march=i586"
     fi
     COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS $COMMON_CCXXFLAGS_JDK -Wall -Wextra -Wno-unused -Wno-unused-parameter -Wformat=2 \
         -pipe -D_GNU_SOURCE -D_REENTRANT -D_LARGEFILE64_SOURCE"
@@ -49225,11 +49697,19 @@
 
 
   elif test "x$TOOLCHAIN_TYPE" = xclang; then
+    JVM_CFLAGS="$JVM_CFLAGS -D_GNU_SOURCE"
+
+    # Restrict the debug information created by Clang to avoid
+    # too big object files and speed the build up a little bit
+    # (see http://llvm.org/bugs/show_bug.cgi?id=7554)
+    JVM_CFLAGS="$JVM_CFLAGS -flimit-debug-info"
     if test "x$OPENJDK_TARGET_OS" = xlinux; then
       if test "x$OPENJDK_TARGET_CPU" = xx86; then
         # Force compatibility with i586 on 32 bit intel platforms.
         COMMON_CCXXFLAGS="${COMMON_CCXXFLAGS} -march=i586"
-      fi
+        JVM_CFLAGS="$JVM_CFLAGS -march=i586"
+      fi
+      JVM_CFLAGS="$JVM_CFLAGS -Wno-sometimes-uninitialized"
       COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS $COMMON_CCXXFLAGS_JDK -Wall -Wextra -Wno-unused -Wno-unused-parameter -Wformat=2 \
           -pipe -D_GNU_SOURCE -D_REENTRANT -D_LARGEFILE64_SOURCE"
       case $OPENJDK_TARGET_CPU_ARCH in
@@ -49244,6 +49724,7 @@
       esac
     fi
   elif test "x$TOOLCHAIN_TYPE" = xsolstudio; then
+    JVM_CFLAGS="$JVM_CFLAGS -DSPARC_WORKS"
     COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS $COMMON_CCXXFLAGS_JDK -DTRACING -DMACRO_MEMSYS_OPS -DBREAKPTS"
     if test "x$OPENJDK_TARGET_CPU_ARCH" = xx86; then
       COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -DcpuIntel -Di586 -D$OPENJDK_TARGET_CPU_LEGACY_LIB"
@@ -49252,6 +49733,7 @@
     CFLAGS_JDK="$CFLAGS_JDK -xc99=%none -xCC -errshort=tags -Xa -v -mt -W0,-noglobal"
     CXXFLAGS_JDK="$CXXFLAGS_JDK -errtags=yes +w -mt -features=no%except -DCC_NOEX -norunpath -xnolib"
   elif test "x$TOOLCHAIN_TYPE" = xxlc; then
+    JVM_CFLAGS="$JVM_CFLAGS -D_REENTRANT -D__STDC_FORMAT_MACROS"
     CFLAGS_JDK="$CFLAGS_JDK -D_GNU_SOURCE -D_REENTRANT -D_LARGEFILE64_SOURCE -DSTDC"
     CXXFLAGS_JDK="$CXXFLAGS_JDK -D_GNU_SOURCE -D_REENTRANT -D_LARGEFILE64_SOURCE -DSTDC"
   elif test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
@@ -49272,6 +49754,7 @@
     if test "x$TOOLCHAIN_VERSION" = "x2010"; then
       STATIC_CPPLIB_FLAGS="-D_STATIC_CPPLIB -D_DISABLE_DEPRECATE_STATIC_CPPLIB"
       COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK $STATIC_CPPLIB_FLAGS"
+      JVM_CFLAGS="$JVM_CFLAGS $STATIC_CPPLIB_FLAGS"
     fi
   fi
 
@@ -49321,12 +49804,9 @@
   COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -D$OPENJDK_TARGET_OS_UPPERCASE"
 
   # Setup target CPU
-  OPENJDK_TARGET_CCXXFLAGS_JDK="$OPENJDK_TARGET_CCXXFLAGS_JDK \
-      $ADD_LP64 \
+  COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK \
+      $OPENJDK_TARGET_ADD_LP64 \
       -DARCH='\"$OPENJDK_TARGET_CPU_LEGACY\"' -D$OPENJDK_TARGET_CPU_LEGACY"
-  OPENJDK_BUILD_CCXXFLAGS_JDK="$OPENJDK_BUILD_CCXXFLAGS_JDK \
-      $OPENJDK_BUILD_ADD_LP64 \
-      -DARCH='\"$OPENJDK_BUILD_CPU_LEGACY\"' -D$OPENJDK_BUILD_CPU_LEGACY"
 
   # Setup debug/release defines
   if test "x$DEBUG_LEVEL" = xrelease; then
@@ -49339,10 +49819,172 @@
   fi
 
   # Set some additional per-OS defines.
-  if test "x$OPENJDK_TARGET_OS" = xmacosx; then
+  if test "x$OPENJDK_TARGET_OS" = xlinux; then
+    JVM_CFLAGS="$JVM_CFLAGS -DLINUX"
+    JVM_CFLAGS="$JVM_CFLAGS -pipe -fPIC -fno-rtti -fno-exceptions \
+        -fvisibility=hidden -fno-strict-aliasing -fno-omit-frame-pointer"
+  elif test "x$OPENJDK_TARGET_OS" = xsolaris; then
+    JVM_CFLAGS="$JVM_CFLAGS -DSOLARIS"
+    JVM_CFLAGS="$JVM_CFLAGS -template=no%extdef -features=no%split_init \
+        -D_Crun_inline_placement -library=%none -KPIC -mt -xwe -features=no%except"
+  elif test "x$OPENJDK_TARGET_OS" = xmacosx; then
     COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -D_ALLBSD_SOURCE -D_DARWIN_UNLIMITED_SELECT"
+    JVM_CFLAGS="$JVM_CFLAGS -D_ALLBSD_SOURCE"
+    JVM_CFLAGS="$JVM_CFLAGS -D_DARWIN_C_SOURCE -D_XOPEN_SOURCE"
+    JVM_CFLAGS="$JVM_CFLAGS -fno-rtti -fno-exceptions -fvisibility=hidden \
+        -mno-omit-leaf-frame-pointer -mstack-alignment=16 -pipe -fno-strict-aliasing \
+        -DMAC_OS_X_VERSION_MAX_ALLOWED=1070 -mmacosx-version-min=10.7.0 \
+        -fno-omit-frame-pointer"
+  elif test "x$OPENJDK_TARGET_OS" = xaix; then
+    JVM_CFLAGS="$JVM_CFLAGS -DAIX"
+    # We may need '-qminimaltoc' or '-qpic=large -bbigtoc' if the TOC overflows.
+    JVM_CFLAGS="$JVM_CFLAGS -qtune=balanced -qhot=level=1 -qinline \
+        -qinlglue -qalias=noansi -qstrict -qtls=default -qlanglvl=c99vla \
+        -qlanglvl=noredefmac -qnortti -qnoeh -qignerrno"
   elif test "x$OPENJDK_TARGET_OS" = xbsd; then
     COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -D_ALLBSD_SOURCE"
+  elif test "x$OPENJDK_TARGET_OS" = xwindows; then
+    JVM_CFLAGS="$JVM_CFLAGS -D_WINDOWS -DWIN32 -D_JNI_IMPLEMENTATION_"
+    JVM_CFLAGS="$JVM_CFLAGS -nologo -W3 -MD -MP"
+  fi
+
+  # Set some additional per-CPU defines.
+  if test "x$OPENJDK_TARGET_OS-$OPENJDK_TARGET_CPU" = xwindows-x86; then
+    JVM_CFLAGS="$JVM_CFLAGS -arch:IA32"
+  elif test "x$OPENJDK_TARGET_CPU" = xsparcv9; then
+    JVM_CFLAGS="$JVM_CFLAGS -xarch=sparc"
+  elif test "x$OPENJDK_TARGET_CPU" = xppc64; then
+    if test "x$OPENJDK_TARGET_OS" = xlinux; then
+      JVM_CFLAGS="$JVM_CFLAGS -minsert-sched-nops=regroup_exact -mno-multiple -mno-string"
+      # fixes `relocation truncated to fit' error for gcc 4.1.
+      JVM_CFLAGS="$JVM_CFLAGS -mminimal-toc"
+      # Use ppc64 instructions, but schedule for power5
+      JVM_CFLAGS="$JVM_CFLAGS -mcpu=powerpc64 -mtune=power5"
+    elif test "x$OPENJDK_TARGET_OS" = xaix; then
+      JVM_CFLAGS="$JVM_CFLAGS -qarch=ppc64"
+    fi
+  elif test "x$OPENJDK_TARGET_CPU" = xppc64le; then
+    if test "x$OPENJDK_TARGET_OS" = xlinux; then
+      JVM_CFLAGS="$JVM_CFLAGS -minsert-sched-nops=regroup_exact -mno-multiple -mno-string"
+      # Little endian machine uses ELFv2 ABI.
+      JVM_CFLAGS="$JVM_CFLAGS -DABI_ELFv2"
+      # Use Power8, this is the first CPU to support PPC64 LE with ELFv2 ABI.
+      JVM_CFLAGS="$JVM_CFLAGS -mcpu=power7 -mtune=power8"
+    fi
+  fi
+
+  if test "x$OPENJDK_TARGET_CPU_ENDIAN" = xlittle; then
+    JVM_CFLAGS="$JVM_CFLAGS -DVM_LITTLE_ENDIAN"
+  fi
+
+  if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then
+    if test "x$OPENJDK_TARGET_OS" != xsolaris && test "x$OPENJDK_TARGET_OS" != xaix; then
+      # Solaris does not have _LP64=1 in the old build.
+      # xlc on AIX defines _LP64=1 by default and issues a warning if we redefine it.
+      JVM_CFLAGS="$JVM_CFLAGS -D_LP64=1"
+    fi
+  fi
+
+  # Set JVM_CFLAGS warning handling
+  if test "x$OPENJDK_TARGET_OS" = xlinux; then
+    JVM_CFLAGS="$JVM_CFLAGS -Wpointer-arith -Wsign-compare -Wunused-function \
+        -Wunused-value -Woverloaded-virtual"
+
+    if test "x$TOOLCHAIN_TYPE" = xgcc; then
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    # Execute function body
+
+  # Need to assign to a variable since m4 is blocked from modifying parts in [].
+  REFERENCE_VERSION=4.8
+
+  if  [[ "$REFERENCE_VERSION" =~ (.*\.){3} ]] ; then
+    as_fn_error $? "Internal error: Cannot compare to 4.8, only three parts (X.Y.Z) is supported" "$LINENO" 5
+  fi
+
+  if  [[ "$REFERENCE_VERSION" =~ [0-9]{6} ]] ; then
+    as_fn_error $? "Internal error: Cannot compare to 4.8, only parts < 99999 is supported" "$LINENO" 5
+  fi
+
+  # Version comparison method inspired by http://stackoverflow.com/a/24067243
+  COMPARABLE_REFERENCE_VERSION=`$AWK -F. '{ printf("%05d%05d%05d\n", $1, $2, $3) }' <<< "$REFERENCE_VERSION"`
+
+  if test $COMPARABLE_ACTUAL_VERSION -ge $COMPARABLE_REFERENCE_VERSION ; then
+    :
+
+            # These flags either do not work or give spurious warnings prior to gcc 4.8.
+            JVM_CFLAGS="$JVM_CFLAGS -Wno-format-zero-length -Wtype-limits -Wuninitialized"
+
+
+  else
+    :
+
+  fi
+
+
+
+
+
+
+
+
+
+
+
+
+    fi
+    if !   [[ " $JVM_VARIANTS " =~ " zero " ]]   && !   [[ " $JVM_VARIANTS " =~ " zeroshark " ]]  ; then
+      # Non-zero builds have stricter warnings
+      JVM_CFLAGS="$JVM_CFLAGS -Wreturn-type -Wundef -Wformat=2"
+    else
+      if test "x$TOOLCHAIN_TYPE" = xclang; then
+        # Some versions of llvm do not like -Wundef
+        JVM_CFLAGS="$JVM_CFLAGS -Wno-undef"
+      fi
+    fi
+  elif test "x$OPENJDK_TARGET_OS" = xmacosx; then
+    JVM_CFLAGS="$JVM_CFLAGS -Wno-deprecated -Wpointer-arith \
+        -Wsign-compare -Wundef -Wunused-function -Wformat=2"
   fi
 
   # Additional macosx handling
@@ -49370,43 +50012,14 @@
       -I${JDK_TOPDIR}/src/java.base/$OPENJDK_TARGET_OS_TYPE/native/libjava"
 
   # The shared libraries are compiled using the picflag.
-  CFLAGS_JDKLIB="$COMMON_CCXXFLAGS_JDK $OPENJDK_TARGET_CCXXFLAGS_JDK \
+  CFLAGS_JDKLIB="$COMMON_CCXXFLAGS_JDK \
       $CFLAGS_JDK $EXTRA_CFLAGS_JDK $PICFLAG $CFLAGS_JDKLIB_EXTRA"
-  CXXFLAGS_JDKLIB="$COMMON_CCXXFLAGS_JDK $OPENJDK_TARGET_CCXXFLAGS_JDK \
+  CXXFLAGS_JDKLIB="$COMMON_CCXXFLAGS_JDK \
       $CXXFLAGS_JDK $EXTRA_CXXFLAGS_JDK $PICFLAG $CXXFLAGS_JDKLIB_EXTRA"
 
   # Executable flags
-  CFLAGS_JDKEXE="$COMMON_CCXXFLAGS_JDK $OPENJDK_TARGET_CCXXFLAGS_JDK \
-      $CFLAGS_JDK $EXTRA_CFLAGS_JDK"
-  CXXFLAGS_JDKEXE="$COMMON_CCXXFLAGS_JDK $OPENJDK_TARGET_CCXXFLAGS_JDK \
-      $CXXFLAGS_JDK $EXTRA_CXXFLAGS_JDK"
-
-  # The corresponding flags for building for the build platform. This is still an
-  # approximation, we only need something that runs on this machine when cross
-  # compiling the product.
-  OPENJDK_BUILD_CFLAGS_JDKLIB="$COMMON_CCXXFLAGS_JDK $OPENJDK_BUILD_CCXXFLAGS_JDK \
-      $PICFLAG $CFLAGS_JDKLIB_EXTRA"
-  OPENJDK_BUILD_CXXFLAGS_JDKLIB="$COMMON_CCXXFLAGS_JDK $OPENJDK_BUILD_CCXXFLAGS_JDK \
-      $PICFLAG $CXXFLAGS_JDKLIB_EXTRA"
-  OPENJDK_BUILD_CFLAGS_JDKEXE="$COMMON_CCXXFLAGS_JDK $OPENJDK_BUILD_CCXXFLAGS_JDK"
-  OPENJDK_BUILD_CXXFLAGS_JDKEXE="$COMMON_CCXXFLAGS_JDK $OPENJDK_BUILD_CCXXFLAGS_JDK"
-
-
-
-
-
-
-
-
-
-
-  # Flags for compiling test libraries
-  CFLAGS_TESTLIB="$COMMON_CCXXFLAGS_JDK $CFLAGS_JDK $PICFLAG $CFLAGS_JDKLIB_EXTRA"
-  CXXFLAGS_TESTLIB="$COMMON_CCXXFLAGS_JDK $CXXFLAGS_JDK $PICFLAG $CXXFLAGS_JDKLIB_EXTRA"
-
-  # Flags for compiling test executables
-  CFLAGS_TESTEXE="$COMMON_CCXXFLAGS_JDK $CFLAGS_JDK"
-  CXXFLAGS_TESTEXE="$COMMON_CCXXFLAGS_JDK $CXXFLAGS_JDK"
+  CFLAGS_JDKEXE="$COMMON_CCXXFLAGS_JDK $CFLAGS_JDK $EXTRA_CFLAGS_JDK"
+  CXXFLAGS_JDKEXE="$COMMON_CCXXFLAGS_JDK $CXXFLAGS_JDK $EXTRA_CXXFLAGS_JDK"
 
 
 
@@ -49419,9 +50032,21 @@
   if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
     LDFLAGS_MICROSOFT="-nologo -opt:ref"
     LDFLAGS_JDK="$LDFLAGS_JDK $LDFLAGS_MICROSOFT -incremental:no"
+    JVM_LDFLAGS="$JVM_LDFLAGS $LDFLAGS_MICROSOFT -opt:icf,8 -subsystem:windows -base:0x8000000"
     if test "x$OPENJDK_TARGET_CPU_BITS" = "x32"; then
       LDFLAGS_SAFESH="-safeseh"
       LDFLAGS_JDK="$LDFLAGS_JDK $LDFLAGS_SAFESH"
+      JVM_LDFLAGS="$JVM_LDFLAGS $LDFLAGS_SAFESH"
+      # NOTE: Old build added -machine. Probably not needed.
+      JVM_LDFLAGS="$JVM_LDFLAGS -machine:I386"
+    else
+      JVM_LDFLAGS="$JVM_LDFLAGS -machine:AMD64"
+    fi
+  elif test "x$TOOLCHAIN_TYPE" = xclang; then
+      JVM_LDFLAGS="$JVM_LDFLAGS -mno-omit-leaf-frame-pointer -mstack-alignment=16 -stdlib=libstdc++ -fPIC"
+      if test "x$OPENJDK_TARGET_OS" = xmacosx; then
+        # FIXME: We should really generalize SET_SHARED_LIBRARY_ORIGIN instead.
+        JVM_LDFLAGS="$JVM_LDFLAGS -Wl,-rpath,@loader_path/. -Wl,-rpath,@loader_path/.."
     fi
   elif test "x$TOOLCHAIN_TYPE" = xgcc; then
     # If this is a --hash-style=gnu system, use --hash-style=both, why?
@@ -49429,36 +50054,57 @@
     if test -n "$HAS_GNU_HASH"; then
       LDFLAGS_HASH_STYLE="-Wl,--hash-style=both"
       LDFLAGS_JDK="${LDFLAGS_JDK} $LDFLAGS_HASH_STYLE"
+      JVM_LDFLAGS="$JVM_LDFLAGS $LDFLAGS_HASH_STYLE"
+    fi
+      if test "x$OPENJDK_TARGET_OS" = xmacosx; then
+        JVM_LDFLAGS="$JVM_LDFLAGS -Wl,-rpath,@loader_path/. -Wl,-rpath,@loader_path/.."
     fi
     if test "x$OPENJDK_TARGET_OS" = xlinux; then
       # And since we now know that the linker is gnu, then add -z defs, to forbid
       # undefined symbols in object files.
       LDFLAGS_NO_UNDEF_SYM="-Wl,-z,defs"
       LDFLAGS_JDK="${LDFLAGS_JDK} $LDFLAGS_NO_UNDEF_SYM"
+      JVM_LDFLAGS="$JVM_LDFLAGS  $LDFLAGS_NO_UNDEF_SYM"
+      LDFLAGS_NO_EXEC_STACK="-Wl,-z,noexecstack"
+      JVM_LDFLAGS="$JVM_LDFLAGS $LDFLAGS_NO_EXEC_STACK"
+      if test "x$OPENJDK_TARGET_CPU" = xx86; then
+        JVM_LDFLAGS="$JVM_LDFLAGS -march=i586"
+      fi
       case $DEBUG_LEVEL in
         release )
           # tell linker to optimize libraries.
           # Should this be supplied to the OSS linker as well?
           LDFLAGS_DEBUGLEVEL_release="-Wl,-O1"
           LDFLAGS_JDK="${LDFLAGS_JDK} $LDFLAGS_DEBUGLEVEL_release"
+          JVM_LDFLAGS="$JVM_LDFLAGS $LDFLAGS_DEBUGLEVEL_release"
+          if test "x$HAS_LINKER_RELRO" = "xtrue"; then
+            JVM_LDFLAGS="$JVM_LDFLAGS $LINKER_RELRO_FLAG"
+          fi
           ;;
         slowdebug )
+          # Hotspot always let the linker optimize
+          JVM_LDFLAGS="$JVM_LDFLAGS -Wl,-O1"
           if test "x$HAS_LINKER_NOW" = "xtrue"; then
             # do relocations at load
             LDFLAGS_JDK="$LDFLAGS_JDK $LINKER_NOW_FLAG"
             LDFLAGS_CXX_JDK="$LDFLAGS_CXX_JDK $LINKER_NOW_FLAG"
+            JVM_LDFLAGS="$JVM_LDFLAGS $LINKER_NOW_FLAG"
           fi
           if test "x$HAS_LINKER_RELRO" = "xtrue"; then
             # mark relocations read only
             LDFLAGS_JDK="$LDFLAGS_JDK $LINKER_RELRO_FLAG"
             LDFLAGS_CXX_JDK="$LDFLAGS_CXX_JDK $LINKER_RELRO_FLAG"
+            JVM_LDFLAGS="$JVM_LDFLAGS $LINKER_RELRO_FLAG"
           fi
           ;;
         fastdebug )
+          # Hotspot always let the linker optimize
+          JVM_LDFLAGS="$JVM_LDFLAGS -Wl,-O1"
           if test "x$HAS_LINKER_RELRO" = "xtrue"; then
             # mark relocations read only
             LDFLAGS_JDK="$LDFLAGS_JDK $LINKER_RELRO_FLAG"
             LDFLAGS_CXX_JDK="$LDFLAGS_CXX_JDK $LINKER_RELRO_FLAG"
+            JVM_LDFLAGS="$JVM_LDFLAGS $LINKER_RELRO_FLAG"
           fi
           ;;
         * )
@@ -49471,9 +50117,14 @@
     LDFLAGS_JDK="$LDFLAGS_JDK $LDFLAGS_SOLSTUDIO -xildoff -ztext"
     LDFLAGS_CXX_SOLSTUDIO="-norunpath"
     LDFLAGS_CXX_JDK="$LDFLAGS_CXX_JDK $LDFLAGS_CXX_SOLSTUDIO -xnolib"
+    JVM_LDFLAGS="$JVM_LDFLAGS $LDFLAGS_SOLSTUDIO -library=%none -mt $LDFLAGS_CXX_SOLSTUDIO -z noversion"
+    if test "x$OPENJDK_TARGET_CPU_ARCH" = "xsparc"; then
+      JVM_LDFLAGS="$JVM_LDFLAGS -xarch=sparc"
+    fi
   elif test "x$TOOLCHAIN_TYPE" = xxlc; then
     LDFLAGS_XLC="-b64 -brtl -bnolibpath -bexpall -bernotok"
     LDFLAGS_JDK="${LDFLAGS_JDK} $LDFLAGS_XLC"
+    JVM_LDFLAGS="$JVM_LDFLAGS $LDFLAGS_XLC"
   fi
 
   # Customize LDFLAGS for executables
@@ -49491,7 +50142,6 @@
     LDFLAGS_JDKEXE="$LDFLAGS_JDKEXE -Wl,--allow-shlib-undefined"
   fi
 
-  OPENJDK_BUILD_LDFLAGS_JDKEXE="${LDFLAGS_JDKEXE}"
   LDFLAGS_JDKEXE="${LDFLAGS_JDKEXE} ${EXTRA_LDFLAGS_JDK}"
 
   # Customize LDFLAGS for libs
@@ -49506,18 +50156,24 @@
     LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} \
         -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_TARGET_CPU_LIBDIR)"
 
+    if test "xTARGET" = "xTARGET"; then
     # On some platforms (mac) the linker warns about non existing -L dirs.
     # Add server first if available. Linking aginst client does not always produce the same results.
-    # Only add client dir if client is being built. Add minimal (note not minimal1) if only building minimal1.
+      # Only add client/minimal dir if client/minimal is being built.
     # Default to server for other variants.
-    if test "x$JVM_VARIANT_SERVER" = xtrue; then
-      LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_TARGET_CPU_LIBDIR)/server"
-    elif test "x$JVM_VARIANT_CLIENT" = xtrue; then
-      LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_TARGET_CPU_LIBDIR)/client"
-    elif test "x$JVM_VARIANT_MINIMAL1" = xtrue; then
-      LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_TARGET_CPU_LIBDIR)/minimal"
-    else
-      LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_TARGET_CPU_LIBDIR)/server"
+      if   [[ " $JVM_VARIANTS " =~ " server " ]]  ; then
+        LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_TARGET_CPU_LIBDIR)/server"
+      elif   [[ " $JVM_VARIANTS " =~ " client " ]]  ; then
+        LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_TARGET_CPU_LIBDIR)/client"
+      elif   [[ " $JVM_VARIANTS " =~ " minimal " ]]  ; then
+        LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_TARGET_CPU_LIBDIR)/minimal"
+    else
+        LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_TARGET_CPU_LIBDIR)/server"
+    fi
+    elif test "xTARGET" = "xBUILD"; then
+      # When building a buildjdk, it's always only the server variant
+      LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} \
+          -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_TARGET_CPU_LIBDIR)/server"
     fi
 
     JDKLIB_LIBS="-ljava -ljvm"
@@ -49525,17 +50181,842 @@
       JDKLIB_LIBS="$JDKLIB_LIBS -lc"
     fi
 
-    # When building a buildjdk, it's always only the server variant
+  fi
+
+  # Set JVM_LIBS (per os)
+  if test "x$OPENJDK_TARGET_OS" = xlinux; then
+    JVM_LIBS="$JVM_LIBS -lm -ldl -lpthread"
+  elif test "x$OPENJDK_TARGET_OS" = xsolaris; then
+    # FIXME: This hard-coded path is not really proper.
+    if test "x$OPENJDK_TARGET_CPU" = xx86_64; then
+      SOLARIS_LIBM_LIBS="/usr/lib/amd64/libm.so.1"
+    elif test "x$OPENJDK_TARGET_CPU" = xsparcv9; then
+      SOLARIS_LIBM_LIBS="/usr/lib/sparcv9/libm.so.1"
+    fi
+    JVM_LIBS="$JVM_LIBS -lsocket -lsched -ldl $SOLARIS_LIBM_LIBS -lCrun \
+        -lthread -ldoor -lc -ldemangle -lnsl -lkstat -lrt"
+  elif test "x$OPENJDK_TARGET_OS" = xmacosx; then
+    JVM_LIBS="$JVM_LIBS -lm"
+  elif test "x$OPENJDK_TARGET_OS" = xaix; then
+    JVM_LIBS="$JVM_LIBS -Wl,-lC_r -lm -ldl -lpthread"
+  elif test "x$OPENJDK_TARGET_OS" = xbsd; then
+    JVM_LIBS="$JVM_LIBS -lm"
+  elif test "x$OPENJDK_TARGET_OS" = xwindows; then
+    JVM_LIBS="$JVM_LIBS kernel32.lib user32.lib gdi32.lib winspool.lib \
+        comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib \
+        wsock32.lib winmm.lib version.lib psapi.lib"
+    fi
+
+  # Set JVM_ASFLAGS
+  if test "x$OPENJDK_TARGET_OS" = xlinux; then
+    if test "x$OPENJDK_TARGET_CPU" = xx86; then
+      JVM_ASFLAGS="$JVM_ASFLAGS -march=i586"
+    fi
+  elif test "x$OPENJDK_TARGET_OS" = xmacosx; then
+    JVM_ASFLAGS="$JVM_ASFLAGS -x assembler-with-cpp -mno-omit-leaf-frame-pointer -mstack-alignment=16"
+  fi
+
+  LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} ${EXTRA_LDFLAGS_JDK}"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+  # Special extras...
+  if test "x$TOOLCHAIN_TYPE" = xsolstudio; then
+    if test "x$OPENJDK_BUILD_CPU_ARCH" = "xsparc"; then
+      OPENJDK_BUILD_CFLAGS_JDKLIB_EXTRA="${OPENJDK_BUILD_CFLAGS_JDKLIB_EXTRA} -xregs=no%appl"
+      OPENJDK_BUILD_CXXFLAGS_JDKLIB_EXTRA="${OPENJDK_BUILD_CXXFLAGS_JDKLIB_EXTRA} -xregs=no%appl"
+    fi
+    OPENJDK_BUILD_CFLAGS_JDKLIB_EXTRA="${OPENJDK_BUILD_CFLAGS_JDKLIB_EXTRA} -errtags=yes -errfmt"
+    OPENJDK_BUILD_CXXFLAGS_JDKLIB_EXTRA="${OPENJDK_BUILD_CXXFLAGS_JDKLIB_EXTRA} -errtags=yes -errfmt"
+  elif test "x$TOOLCHAIN_TYPE" = xxlc; then
+    OPENJDK_BUILD_CFLAGS_JDK="${OPENJDK_BUILD_CFLAGS_JDK} -qchars=signed -qfullpath -qsaveopt"
+    OPENJDK_BUILD_CXXFLAGS_JDK="${OPENJDK_BUILD_CXXFLAGS_JDK} -qchars=signed -qfullpath -qsaveopt"
+  elif test "x$TOOLCHAIN_TYPE" = xgcc; then
+    OPENJDK_BUILD_CXXSTD_CXXFLAG="-std=gnu++98"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    # Execute function body
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the C++ compiler supports \"$OPENJDK_BUILD_CXXSTD_CXXFLAG -Werror\"" >&5
+$as_echo_n "checking if the C++ compiler supports \"$OPENJDK_BUILD_CXXSTD_CXXFLAG -Werror\"... " >&6; }
+  supports=yes
+
+  saved_cxxflags="$CXXFLAGS"
+  CXXFLAGS="$CXXFLAG $OPENJDK_BUILD_CXXSTD_CXXFLAG -Werror"
+  ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+int i;
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+
+else
+  supports=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+  CXXFLAGS="$saved_cxxflags"
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $supports" >&5
+$as_echo "$supports" >&6; }
+  if test "x$supports" = "xyes" ; then
+    :
+
+  else
+    :
+    OPENJDK_BUILD_CXXSTD_CXXFLAG=""
+  fi
+
+
+
+
+
+
+
+
+
+
+
+
+    OPENJDK_BUILD_CXXFLAGS_JDK="${OPENJDK_BUILD_CXXFLAGS_JDK} ${OPENJDK_BUILD_CXXSTD_CXXFLAG}"
+
+  fi
+  if test "x$OPENJDK_TARGET_OS" = xsolaris; then
+    OPENJDK_BUILD_CFLAGS_JDK="${OPENJDK_BUILD_CFLAGS_JDK} -D__solaris__"
+    OPENJDK_BUILD_CXXFLAGS_JDK="${OPENJDK_BUILD_CXXFLAGS_JDK} -D__solaris__"
+    OPENJDK_BUILD_CFLAGS_JDKLIB_EXTRA='-xstrconst'
+    CFLAGS_JDK="${CFLAGS_JDK} -qchars=signed -qfullpath -qsaveopt"
+    CXXFLAGS_JDK="${CXXFLAGS_JDK} -qchars=signed -qfullpath -qsaveopt"
+  fi
+
+  if test "x$OPENJDK_TARGET_OS" = xsolaris; then
+    OPENJDK_BUILD_CFLAGS_JDK="${OPENJDK_BUILD_CFLAGS_JDK} -D__solaris__"
+    OPENJDK_BUILD_CXXFLAGS_JDK="${OPENJDK_BUILD_CXXFLAGS_JDK} -D__solaris__"
+    OPENJDK_BUILD_CFLAGS_JDKLIB_EXTRA='-xstrconst'
+  fi
+
+  OPENJDK_BUILD_CFLAGS_JDK="${OPENJDK_BUILD_CFLAGS_JDK} ${OPENJDK_BUILD_EXTRA_CFLAGS}"
+  OPENJDK_BUILD_CXXFLAGS_JDK="${OPENJDK_BUILD_CXXFLAGS_JDK} ${OPENJDK_BUILD_EXTRA_CXXFLAGS}"
+  OPENJDK_BUILD_LDFLAGS_JDK="${OPENJDK_BUILD_LDFLAGS_JDK} ${OPENJDK_BUILD_EXTRA_LDFLAGS}"
+
+  ###############################################################################
+  #
+  # Now setup the CFLAGS and LDFLAGS for the JDK build.
+  # Later we will also have CFLAGS and LDFLAGS for the hotspot subrepo build.
+  #
+
+  # Setup compiler/platform specific flags into
+  #    OPENJDK_BUILD_CFLAGS_JDK    - C Compiler flags
+  #    OPENJDK_BUILD_CXXFLAGS_JDK  - C++ Compiler flags
+  #    OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK - common to C and C++
+  if test "x$TOOLCHAIN_TYPE" = xgcc; then
+    OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -D_GNU_SOURCE"
+    OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -D_REENTRANT"
+    OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -fcheck-new"
+    if test "x$OPENJDK_BUILD_CPU" = xx86; then
+      # Force compatibility with i586 on 32 bit intel platforms.
+      OPENJDK_BUILD_COMMON_CCXXFLAGS="${OPENJDK_BUILD_COMMON_CCXXFLAGS} -march=i586"
+      OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -march=i586"
+    fi
+    OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS $OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK -Wall -Wextra -Wno-unused -Wno-unused-parameter -Wformat=2 \
+        -pipe -D_GNU_SOURCE -D_REENTRANT -D_LARGEFILE64_SOURCE"
+    case $OPENJDK_BUILD_CPU_ARCH in
+      arm )
+        # on arm we don't prevent gcc to omit frame pointer but do prevent strict aliasing
+        OPENJDK_BUILD_CFLAGS_JDK="${OPENJDK_BUILD_CFLAGS_JDK} -fno-strict-aliasing"
+        ;;
+      ppc )
+        # on ppc we don't prevent gcc to omit frame pointer but do prevent strict aliasing
+        OPENJDK_BUILD_CFLAGS_JDK="${OPENJDK_BUILD_CFLAGS_JDK} -fno-strict-aliasing"
+        ;;
+      * )
+        OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK -fno-omit-frame-pointer"
+        OPENJDK_BUILD_CFLAGS_JDK="${OPENJDK_BUILD_CFLAGS_JDK} -fno-strict-aliasing"
+        ;;
+    esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    # Execute function body
+
+  # Need to assign to a variable since m4 is blocked from modifying parts in [].
+  REFERENCE_VERSION=6
+
+  if  [[ "$REFERENCE_VERSION" =~ (.*\.){3} ]] ; then
+    as_fn_error $? "Internal error: Cannot compare to 6, only three parts (X.Y.Z) is supported" "$LINENO" 5
+  fi
+
+  if  [[ "$REFERENCE_VERSION" =~ [0-9]{6} ]] ; then
+    as_fn_error $? "Internal error: Cannot compare to 6, only parts < 99999 is supported" "$LINENO" 5
+  fi
+
+  # Version comparison method inspired by http://stackoverflow.com/a/24067243
+  COMPARABLE_REFERENCE_VERSION=`$AWK -F. '{ printf("%05d%05d%05d\n", $1, $2, $3) }' <<< "$REFERENCE_VERSION"`
+
+  if test $COMPARABLE_ACTUAL_VERSION -ge $COMPARABLE_REFERENCE_VERSION ; then
+    :
+
+  else
+    :
+
+  fi
+
+
+
+
+
+
+
+
+
+
+
+
+  elif test "x$TOOLCHAIN_TYPE" = xclang; then
+    OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -D_GNU_SOURCE"
+
+    # Restrict the debug information created by Clang to avoid
+    # too big object files and speed the build up a little bit
+    # (see http://llvm.org/bugs/show_bug.cgi?id=7554)
+    OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -flimit-debug-info"
+    if test "x$OPENJDK_BUILD_OS" = xlinux; then
+      if test "x$OPENJDK_BUILD_CPU" = xx86; then
+        # Force compatibility with i586 on 32 bit intel platforms.
+        OPENJDK_BUILD_COMMON_CCXXFLAGS="${OPENJDK_BUILD_COMMON_CCXXFLAGS} -march=i586"
+        OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -march=i586"
+      fi
+      OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -Wno-sometimes-uninitialized"
+      OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS $OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK -Wall -Wextra -Wno-unused -Wno-unused-parameter -Wformat=2 \
+          -pipe -D_GNU_SOURCE -D_REENTRANT -D_LARGEFILE64_SOURCE"
+      case $OPENJDK_BUILD_CPU_ARCH in
+        ppc )
+          # on ppc we don't prevent gcc to omit frame pointer but do prevent strict aliasing
+          OPENJDK_BUILD_CFLAGS_JDK="${OPENJDK_BUILD_CFLAGS_JDK} -fno-strict-aliasing"
+          ;;
+        * )
+          OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK -fno-omit-frame-pointer"
+          OPENJDK_BUILD_CFLAGS_JDK="${OPENJDK_BUILD_CFLAGS_JDK} -fno-strict-aliasing"
+          ;;
+      esac
+    fi
+  elif test "x$TOOLCHAIN_TYPE" = xsolstudio; then
+    OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -DSPARC_WORKS"
+    OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS $OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK -DTRACING -DMACRO_MEMSYS_OPS -DBREAKPTS"
+    if test "x$OPENJDK_BUILD_CPU_ARCH" = xx86; then
+      OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK -DcpuIntel -Di586 -D$OPENJDK_BUILD_CPU_LEGACY_LIB"
+    fi
+
+    OPENJDK_BUILD_CFLAGS_JDK="$OPENJDK_BUILD_CFLAGS_JDK -xc99=%none -xCC -errshort=tags -Xa -v -mt -W0,-noglobal"
+    OPENJDK_BUILD_CXXFLAGS_JDK="$OPENJDK_BUILD_CXXFLAGS_JDK -errtags=yes +w -mt -features=no%except -DCC_NOEX -norunpath -xnolib"
+  elif test "x$TOOLCHAIN_TYPE" = xxlc; then
+    OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -D_REENTRANT -D__STDC_FORMAT_MACROS"
+    OPENJDK_BUILD_CFLAGS_JDK="$OPENJDK_BUILD_CFLAGS_JDK -D_GNU_SOURCE -D_REENTRANT -D_LARGEFILE64_SOURCE -DSTDC"
+    OPENJDK_BUILD_CXXFLAGS_JDK="$OPENJDK_BUILD_CXXFLAGS_JDK -D_GNU_SOURCE -D_REENTRANT -D_LARGEFILE64_SOURCE -DSTDC"
+  elif test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
+    OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS $OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK \
+        -MD -Zc:wchar_t- -W3 -wd4800 \
+        -DWIN32_LEAN_AND_MEAN \
+        -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE \
+        -D_WINSOCK_DEPRECATED_NO_WARNINGS \
+        -DWIN32 -DIAL"
+    if test "x$OPENJDK_BUILD_CPU" = xx86_64; then
+      OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK -D_AMD64_ -Damd64"
+    else
+      OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK -D_X86_ -Dx86"
+    fi
+    # If building with Visual Studio 2010, we can still use _STATIC_CPPLIB to
+    # avoid bundling msvcpNNN.dll. Doesn't work with newer versions of visual
+    # studio.
+    if test "x$TOOLCHAIN_VERSION" = "x2010"; then
+      STATIC_CPPLIB_FLAGS="-D_STATIC_CPPLIB -D_DISABLE_DEPRECATE_STATIC_CPPLIB"
+      OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK $STATIC_CPPLIB_FLAGS"
+      OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS $STATIC_CPPLIB_FLAGS"
+    fi
+  fi
+
+  ###############################################################################
+
+  # Adjust flags according to debug level.
+  case $DEBUG_LEVEL in
+    fastdebug | slowdebug )
+      OPENJDK_BUILD_CFLAGS_JDK="$OPENJDK_BUILD_CFLAGS_JDK $CFLAGS_DEBUG_SYMBOLS $CFLAGS_DEBUG_OPTIONS"
+      OPENJDK_BUILD_CXXFLAGS_JDK="$OPENJDK_BUILD_CXXFLAGS_JDK $CXXFLAGS_DEBUG_SYMBOLS $CXXFLAGS_DEBUG_OPTIONS"
+      JAVAC_FLAGS="$JAVAC_FLAGS -g"
+      ;;
+    release )
+      ;;
+    * )
+      as_fn_error $? "Unrecognized \$DEBUG_LEVEL: $DEBUG_LEVEL" "$LINENO" 5
+      ;;
+  esac
+
+  # Set some common defines. These works for all compilers, but assume
+  # -D is universally accepted.
+
+  # Setup endianness
+  if test "x$OPENJDK_BUILD_CPU_ENDIAN" = xlittle; then
+    # The macro _LITTLE_ENDIAN needs to be defined the same to avoid the
+    #   Sun C compiler warning message: warning: macro redefined: _LITTLE_ENDIAN
+    #   (The Solaris X86 system defines this in file /usr/include/sys/isa_defs.h).
+    #   Note: -Dmacro         is the same as    #define macro 1
+    #         -Dmacro=        is the same as    #define macro
+    if test "x$OPENJDK_BUILD_OS" = xsolaris; then
+      OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK -D_LITTLE_ENDIAN="
+    else
+      OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK -D_LITTLE_ENDIAN"
+    fi
+  else
+    # Same goes for _BIG_ENDIAN. Do we really need to set *ENDIAN on Solaris if they
+    # are defined in the system?
+    if test "x$OPENJDK_BUILD_OS" = xsolaris; then
+      OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK -D_BIG_ENDIAN="
+    else
+      OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK -D_BIG_ENDIAN"
+    fi
+  fi
+
+  # Setup target OS define. Use OS target name but in upper case.
+  OPENJDK_BUILD_OS_UPPERCASE=`$ECHO $OPENJDK_BUILD_OS | $TR 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+  OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK -D$OPENJDK_BUILD_OS_UPPERCASE"
+
+  # Setup target CPU
+  OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK \
+      $OPENJDK_BUILD_ADD_LP64 \
+      -DARCH='\"$OPENJDK_BUILD_CPU_LEGACY\"' -D$OPENJDK_BUILD_CPU_LEGACY"
+
+  # Setup debug/release defines
+  if test "x$DEBUG_LEVEL" = xrelease; then
+    OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK -DNDEBUG"
+    if test "x$OPENJDK_BUILD_OS" = xsolaris; then
+      OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK -DTRIMMED"
+    fi
+  else
+    OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK -DDEBUG"
+  fi
+
+  # Set some additional per-OS defines.
+  if test "x$OPENJDK_BUILD_OS" = xlinux; then
+    OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -DLINUX"
+    OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -pipe -fPIC -fno-rtti -fno-exceptions \
+        -fvisibility=hidden -fno-strict-aliasing -fno-omit-frame-pointer"
+  elif test "x$OPENJDK_BUILD_OS" = xsolaris; then
+    OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -DSOLARIS"
+    OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -template=no%extdef -features=no%split_init \
+        -D_Crun_inline_placement -library=%none -KPIC -mt -xwe -features=no%except"
+  elif test "x$OPENJDK_BUILD_OS" = xmacosx; then
+    OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK -D_ALLBSD_SOURCE -D_DARWIN_UNLIMITED_SELECT"
+    OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -D_ALLBSD_SOURCE"
+    OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -D_DARWIN_C_SOURCE -D_XOPEN_SOURCE"
+    OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -fno-rtti -fno-exceptions -fvisibility=hidden \
+        -mno-omit-leaf-frame-pointer -mstack-alignment=16 -pipe -fno-strict-aliasing \
+        -DMAC_OS_X_VERSION_MAX_ALLOWED=1070 -mmacosx-version-min=10.7.0 \
+        -fno-omit-frame-pointer"
+  elif test "x$OPENJDK_BUILD_OS" = xaix; then
+    OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -DAIX"
+    # We may need '-qminimaltoc' or '-qpic=large -bbigtoc' if the TOC overflows.
+    OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -qtune=balanced -qhot=level=1 -qinline \
+        -qinlglue -qalias=noansi -qstrict -qtls=default -qlanglvl=c99vla \
+        -qlanglvl=noredefmac -qnortti -qnoeh -qignerrno"
+  elif test "x$OPENJDK_BUILD_OS" = xbsd; then
+    OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK -D_ALLBSD_SOURCE"
+  elif test "x$OPENJDK_BUILD_OS" = xwindows; then
+    OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -D_WINDOWS -DWIN32 -D_JNI_IMPLEMENTATION_"
+    OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -nologo -W3 -MD -MP"
+  fi
+
+  # Set some additional per-CPU defines.
+  if test "x$OPENJDK_BUILD_OS-$OPENJDK_BUILD_CPU" = xwindows-x86; then
+    OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -arch:IA32"
+  elif test "x$OPENJDK_BUILD_CPU" = xsparcv9; then
+    OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -xarch=sparc"
+  elif test "x$OPENJDK_BUILD_CPU" = xppc64; then
+    if test "x$OPENJDK_BUILD_OS" = xlinux; then
+      OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -minsert-sched-nops=regroup_exact -mno-multiple -mno-string"
+      # fixes `relocation truncated to fit' error for gcc 4.1.
+      OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -mminimal-toc"
+      # Use ppc64 instructions, but schedule for power5
+      OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -mcpu=powerpc64 -mtune=power5"
+    elif test "x$OPENJDK_BUILD_OS" = xaix; then
+      OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -qarch=ppc64"
+    fi
+  elif test "x$OPENJDK_BUILD_CPU" = xppc64le; then
+    if test "x$OPENJDK_BUILD_OS" = xlinux; then
+      OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -minsert-sched-nops=regroup_exact -mno-multiple -mno-string"
+      # Little endian machine uses ELFv2 ABI.
+      OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -DABI_ELFv2"
+      # Use Power8, this is the first CPU to support PPC64 LE with ELFv2 ABI.
+      OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -mcpu=power7 -mtune=power8"
+    fi
+  fi
+
+  if test "x$OPENJDK_BUILD_CPU_ENDIAN" = xlittle; then
+    OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -DVM_LITTLE_ENDIAN"
+  fi
+
+  if test "x$OPENJDK_BUILD_CPU_BITS" = x64; then
+    if test "x$OPENJDK_BUILD_OS" != xsolaris && test "x$OPENJDK_BUILD_OS" != xaix; then
+      # Solaris does not have _LP64=1 in the old build.
+      # xlc on AIX defines _LP64=1 by default and issues a warning if we redefine it.
+      OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -D_LP64=1"
+    fi
+  fi
+
+  # Set OPENJDK_BUILD_JVM_CFLAGS warning handling
+  if test "x$OPENJDK_BUILD_OS" = xlinux; then
+    OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -Wpointer-arith -Wsign-compare -Wunused-function \
+        -Wunused-value -Woverloaded-virtual"
+
+    if test "x$TOOLCHAIN_TYPE" = xgcc; then
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    # Execute function body
+
+  # Need to assign to a variable since m4 is blocked from modifying parts in [].
+  REFERENCE_VERSION=4.8
+
+  if  [[ "$REFERENCE_VERSION" =~ (.*\.){3} ]] ; then
+    as_fn_error $? "Internal error: Cannot compare to 4.8, only three parts (X.Y.Z) is supported" "$LINENO" 5
+  fi
+
+  if  [[ "$REFERENCE_VERSION" =~ [0-9]{6} ]] ; then
+    as_fn_error $? "Internal error: Cannot compare to 4.8, only parts < 99999 is supported" "$LINENO" 5
+  fi
+
+  # Version comparison method inspired by http://stackoverflow.com/a/24067243
+  COMPARABLE_REFERENCE_VERSION=`$AWK -F. '{ printf("%05d%05d%05d\n", $1, $2, $3) }' <<< "$REFERENCE_VERSION"`
+
+  if test $COMPARABLE_ACTUAL_VERSION -ge $COMPARABLE_REFERENCE_VERSION ; then
+    :
+
+            # These flags either do not work or give spurious warnings prior to gcc 4.8.
+            OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -Wno-format-zero-length -Wtype-limits -Wuninitialized"
+
+
+  else
+    :
+
+  fi
+
+
+
+
+
+
+
+
+
+
+
+
+    fi
+    if !   [[ " $JVM_VARIANTS " =~ " zero " ]]   && !   [[ " $JVM_VARIANTS " =~ " zeroshark " ]]  ; then
+      # Non-zero builds have stricter warnings
+      OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -Wreturn-type -Wundef -Wformat=2"
+    else
+      if test "x$TOOLCHAIN_TYPE" = xclang; then
+        # Some versions of llvm do not like -Wundef
+        OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -Wno-undef"
+      fi
+    fi
+  elif test "x$OPENJDK_BUILD_OS" = xmacosx; then
+    OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -Wno-deprecated -Wpointer-arith \
+        -Wsign-compare -Wundef -Wunused-function -Wformat=2"
+  fi
+
+  # Additional macosx handling
+  if test "x$OPENJDK_BUILD_OS" = xmacosx; then
+    # Setting these parameters makes it an error to link to macosx APIs that are
+    # newer than the given OS version and makes the linked binaries compatible
+    # even if built on a newer version of the OS.
+    # The expected format is X.Y.Z
+    MACOSX_VERSION_MIN=10.7.0
+
+
+    # The macro takes the version with no dots, ex: 1070
+    # Let the flags variables get resolved in make for easier override on make
+    # command line.
+    OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK -DMAC_OS_X_VERSION_MAX_ALLOWED=\$(subst .,,\$(MACOSX_VERSION_MIN)) -mmacosx-version-min=\$(MACOSX_VERSION_MIN)"
+    OPENJDK_BUILD_LDFLAGS_JDK="$OPENJDK_BUILD_LDFLAGS_JDK -mmacosx-version-min=\$(MACOSX_VERSION_MIN)"
+  fi
+
+  # Setup some hard coded includes
+  OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK \
+      -I${JDK_TOPDIR}/src/java.base/share/native/include \
+      -I${JDK_TOPDIR}/src/java.base/$OPENJDK_BUILD_OS/native/include \
+      -I${JDK_TOPDIR}/src/java.base/$OPENJDK_BUILD_OS_TYPE/native/include \
+      -I${JDK_TOPDIR}/src/java.base/share/native/libjava \
+      -I${JDK_TOPDIR}/src/java.base/$OPENJDK_BUILD_OS_TYPE/native/libjava"
+
+  # The shared libraries are compiled using the picflag.
+  OPENJDK_BUILD_CFLAGS_JDKLIB="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK \
+      $OPENJDK_BUILD_CFLAGS_JDK $OPENJDK_BUILD_EXTRA_CFLAGS_JDK $PICFLAG $OPENJDK_BUILD_CFLAGS_JDKLIB_EXTRA"
+  OPENJDK_BUILD_CXXFLAGS_JDKLIB="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK \
+      $OPENJDK_BUILD_CXXFLAGS_JDK $OPENJDK_BUILD_EXTRA_CXXFLAGS_JDK $PICFLAG $OPENJDK_BUILD_CXXFLAGS_JDKLIB_EXTRA"
+
+  # Executable flags
+  OPENJDK_BUILD_CFLAGS_JDKEXE="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK $OPENJDK_BUILD_CFLAGS_JDK $OPENJDK_BUILD_EXTRA_CFLAGS_JDK"
+  OPENJDK_BUILD_CXXFLAGS_JDKEXE="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK $OPENJDK_BUILD_CXXFLAGS_JDK $OPENJDK_BUILD_EXTRA_CXXFLAGS_JDK"
+
+
+
+
+
+
+  # Setup LDFLAGS et al.
+  #
+
+  if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
+    LDFLAGS_MICROSOFT="-nologo -opt:ref"
+    OPENJDK_BUILD_LDFLAGS_JDK="$OPENJDK_BUILD_LDFLAGS_JDK $LDFLAGS_MICROSOFT -incremental:no"
+    OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS $LDFLAGS_MICROSOFT -opt:icf,8 -subsystem:windows -base:0x8000000"
+    if test "x$OPENJDK_BUILD_CPU_BITS" = "x32"; then
+      LDFLAGS_SAFESH="-safeseh"
+      OPENJDK_BUILD_LDFLAGS_JDK="$OPENJDK_BUILD_LDFLAGS_JDK $LDFLAGS_SAFESH"
+      OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS $LDFLAGS_SAFESH"
+      # NOTE: Old build added -machine. Probably not needed.
+      OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS -machine:I386"
+    else
+      OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS -machine:AMD64"
+    fi
+  elif test "x$TOOLCHAIN_TYPE" = xclang; then
+      OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS -mno-omit-leaf-frame-pointer -mstack-alignment=16 -stdlib=libstdc++ -fPIC"
+      if test "x$OPENJDK_BUILD_OS" = xmacosx; then
+        # FIXME: We should really generalize SET_SHARED_LIBRARY_ORIGIN instead.
+        OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS -Wl,-rpath,@loader_path/. -Wl,-rpath,@loader_path/.."
+    fi
+  elif test "x$TOOLCHAIN_TYPE" = xgcc; then
+    # If this is a --hash-style=gnu system, use --hash-style=both, why?
+    # We have previously set HAS_GNU_HASH if this is the case
+    if test -n "$HAS_GNU_HASH"; then
+      OPENJDK_BUILD_LDFLAGS_HASH_STYLE="-Wl,--hash-style=both"
+      OPENJDK_BUILD_LDFLAGS_JDK="${OPENJDK_BUILD_LDFLAGS_JDK} $OPENJDK_BUILD_LDFLAGS_HASH_STYLE"
+      OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS $OPENJDK_BUILD_LDFLAGS_HASH_STYLE"
+    fi
+      if test "x$OPENJDK_BUILD_OS" = xmacosx; then
+        OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS -Wl,-rpath,@loader_path/. -Wl,-rpath,@loader_path/.."
+    fi
+    if test "x$OPENJDK_BUILD_OS" = xlinux; then
+      # And since we now know that the linker is gnu, then add -z defs, to forbid
+      # undefined symbols in object files.
+      LDFLAGS_NO_UNDEF_SYM="-Wl,-z,defs"
+      OPENJDK_BUILD_LDFLAGS_JDK="${OPENJDK_BUILD_LDFLAGS_JDK} $LDFLAGS_NO_UNDEF_SYM"
+      OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS  $LDFLAGS_NO_UNDEF_SYM"
+      LDFLAGS_NO_EXEC_STACK="-Wl,-z,noexecstack"
+      OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS $LDFLAGS_NO_EXEC_STACK"
+      if test "x$OPENJDK_BUILD_CPU" = xx86; then
+        OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS -march=i586"
+      fi
+      case $DEBUG_LEVEL in
+        release )
+          # tell linker to optimize libraries.
+          # Should this be supplied to the OSS linker as well?
+          LDFLAGS_DEBUGLEVEL_release="-Wl,-O1"
+          OPENJDK_BUILD_LDFLAGS_JDK="${OPENJDK_BUILD_LDFLAGS_JDK} $LDFLAGS_DEBUGLEVEL_release"
+          OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS $LDFLAGS_DEBUGLEVEL_release"
+          if test "x$HAS_LINKER_RELRO" = "xtrue"; then
+            OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS $LINKER_RELRO_FLAG"
+          fi
+          ;;
+        slowdebug )
+          # Hotspot always let the linker optimize
+          OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS -Wl,-O1"
+          if test "x$HAS_LINKER_NOW" = "xtrue"; then
+            # do relocations at load
+            OPENJDK_BUILD_LDFLAGS_JDK="$OPENJDK_BUILD_LDFLAGS_JDK $LINKER_NOW_FLAG"
+            OPENJDK_BUILD_LDFLAGS_CXX_JDK="$OPENJDK_BUILD_LDFLAGS_CXX_JDK $LINKER_NOW_FLAG"
+            OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS $LINKER_NOW_FLAG"
+          fi
+          if test "x$HAS_LINKER_RELRO" = "xtrue"; then
+            # mark relocations read only
+            OPENJDK_BUILD_LDFLAGS_JDK="$OPENJDK_BUILD_LDFLAGS_JDK $LINKER_RELRO_FLAG"
+            OPENJDK_BUILD_LDFLAGS_CXX_JDK="$OPENJDK_BUILD_LDFLAGS_CXX_JDK $LINKER_RELRO_FLAG"
+            OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS $LINKER_RELRO_FLAG"
+          fi
+          ;;
+        fastdebug )
+          # Hotspot always let the linker optimize
+          OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS -Wl,-O1"
+          if test "x$HAS_LINKER_RELRO" = "xtrue"; then
+            # mark relocations read only
+            OPENJDK_BUILD_LDFLAGS_JDK="$OPENJDK_BUILD_LDFLAGS_JDK $LINKER_RELRO_FLAG"
+            OPENJDK_BUILD_LDFLAGS_CXX_JDK="$OPENJDK_BUILD_LDFLAGS_CXX_JDK $LINKER_RELRO_FLAG"
+            OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS $LINKER_RELRO_FLAG"
+          fi
+          ;;
+        * )
+          as_fn_error $? "Unrecognized \$DEBUG_LEVEL: $DEBUG_LEVEL" "$LINENO" 5
+          ;;
+        esac
+    fi
+  elif test "x$TOOLCHAIN_TYPE" = xsolstudio; then
+    LDFLAGS_SOLSTUDIO="-Wl,-z,defs"
+    OPENJDK_BUILD_LDFLAGS_JDK="$OPENJDK_BUILD_LDFLAGS_JDK $LDFLAGS_SOLSTUDIO -xildoff -ztext"
+    LDFLAGS_CXX_SOLSTUDIO="-norunpath"
+    OPENJDK_BUILD_LDFLAGS_CXX_JDK="$OPENJDK_BUILD_LDFLAGS_CXX_JDK $LDFLAGS_CXX_SOLSTUDIO -xnolib"
+    OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS $LDFLAGS_SOLSTUDIO -library=%none -mt $LDFLAGS_CXX_SOLSTUDIO -z noversion"
+    if test "x$OPENJDK_BUILD_CPU_ARCH" = "xsparc"; then
+      OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS -xarch=sparc"
+    fi
+  elif test "x$TOOLCHAIN_TYPE" = xxlc; then
+    LDFLAGS_XLC="-b64 -brtl -bnolibpath -bexpall -bernotok"
+    OPENJDK_BUILD_LDFLAGS_JDK="${OPENJDK_BUILD_LDFLAGS_JDK} $LDFLAGS_XLC"
+    OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS $LDFLAGS_XLC"
+  fi
+
+  # Customize LDFLAGS for executables
+
+  OPENJDK_BUILD_LDFLAGS_JDKEXE="${OPENJDK_BUILD_LDFLAGS_JDK}"
+
+  if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
+    if test "x$OPENJDK_BUILD_CPU_BITS" = "x64"; then
+      LDFLAGS_STACK_SIZE=1048576
+    else
+      LDFLAGS_STACK_SIZE=327680
+    fi
+    OPENJDK_BUILD_LDFLAGS_JDKEXE="${OPENJDK_BUILD_LDFLAGS_JDKEXE} /STACK:$LDFLAGS_STACK_SIZE"
+  elif test "x$OPENJDK_BUILD_OS" = xlinux; then
+    OPENJDK_BUILD_LDFLAGS_JDKEXE="$OPENJDK_BUILD_LDFLAGS_JDKEXE -Wl,--allow-shlib-undefined"
+  fi
+
+  OPENJDK_BUILD_LDFLAGS_JDKEXE="${OPENJDK_BUILD_LDFLAGS_JDKEXE} ${OPENJDK_BUILD_EXTRA_LDFLAGS_JDK}"
+
+  # Customize LDFLAGS for libs
+  OPENJDK_BUILD_LDFLAGS_JDKLIB="${OPENJDK_BUILD_LDFLAGS_JDK}"
+
+  OPENJDK_BUILD_LDFLAGS_JDKLIB="${OPENJDK_BUILD_LDFLAGS_JDKLIB} ${SHARED_LIBRARY_FLAGS}"
+  if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
     OPENJDK_BUILD_LDFLAGS_JDKLIB="${OPENJDK_BUILD_LDFLAGS_JDKLIB} \
-        -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_TARGET_CPU_LIBDIR)/server"
-  fi
-
-  OPENJDK_BUILD_LDFLAGS_JDKLIB="${OPENJDK_BUILD_LDFLAGS_JDKLIB} ${LDFLAGS_JDKLIB}"
-  LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} ${EXTRA_LDFLAGS_JDK}"
-
-
-
-
+        -libpath:${OUTPUT_ROOT}/support/modules_libs/java.base"
+    OPENJDK_BUILD_JDKLIB_LIBS=""
+  else
+    OPENJDK_BUILD_LDFLAGS_JDKLIB="${OPENJDK_BUILD_LDFLAGS_JDKLIB} \
+        -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_BUILD_CPU_LIBDIR)"
+
+    if test "xBUILD" = "xTARGET"; then
+    # On some platforms (mac) the linker warns about non existing -L dirs.
+    # Add server first if available. Linking aginst client does not always produce the same results.
+      # Only add client/minimal dir if client/minimal is being built.
+    # Default to server for other variants.
+      if   [[ " $JVM_VARIANTS " =~ " server " ]]  ; then
+        OPENJDK_BUILD_LDFLAGS_JDKLIB="${OPENJDK_BUILD_LDFLAGS_JDKLIB} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_BUILD_CPU_LIBDIR)/server"
+      elif   [[ " $JVM_VARIANTS " =~ " client " ]]  ; then
+        OPENJDK_BUILD_LDFLAGS_JDKLIB="${OPENJDK_BUILD_LDFLAGS_JDKLIB} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_BUILD_CPU_LIBDIR)/client"
+      elif   [[ " $JVM_VARIANTS " =~ " minimal " ]]  ; then
+        OPENJDK_BUILD_LDFLAGS_JDKLIB="${OPENJDK_BUILD_LDFLAGS_JDKLIB} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_BUILD_CPU_LIBDIR)/minimal"
+    else
+        OPENJDK_BUILD_LDFLAGS_JDKLIB="${OPENJDK_BUILD_LDFLAGS_JDKLIB} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_BUILD_CPU_LIBDIR)/server"
+    fi
+    elif test "xBUILD" = "xBUILD"; then
+      # When building a buildjdk, it's always only the server variant
+      OPENJDK_BUILD_LDFLAGS_JDKLIB="${OPENJDK_BUILD_LDFLAGS_JDKLIB} \
+          -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_BUILD_CPU_LIBDIR)/server"
+    fi
+
+    OPENJDK_BUILD_JDKLIB_LIBS="-ljava -ljvm"
+    if test "x$TOOLCHAIN_TYPE" = xsolstudio; then
+      OPENJDK_BUILD_JDKLIB_LIBS="$OPENJDK_BUILD_JDKLIB_LIBS -lc"
+    fi
+
+  fi
+
+  # Set OPENJDK_BUILD_JVM_LIBS (per os)
+  if test "x$OPENJDK_BUILD_OS" = xlinux; then
+    OPENJDK_BUILD_JVM_LIBS="$OPENJDK_BUILD_JVM_LIBS -lm -ldl -lpthread"
+  elif test "x$OPENJDK_BUILD_OS" = xsolaris; then
+    # FIXME: This hard-coded path is not really proper.
+    if test "x$OPENJDK_BUILD_CPU" = xx86_64; then
+      OPENJDK_BUILD_SOLARIS_LIBM_LIBS="/usr/lib/amd64/libm.so.1"
+    elif test "x$OPENJDK_BUILD_CPU" = xsparcv9; then
+      OPENJDK_BUILD_SOLARIS_LIBM_LIBS="/usr/lib/sparcv9/libm.so.1"
+    fi
+    OPENJDK_BUILD_JVM_LIBS="$OPENJDK_BUILD_JVM_LIBS -lsocket -lsched -ldl $SOLARIS_LIBM_LIBS -lCrun \
+        -lthread -ldoor -lc -ldemangle -lnsl -lkstat -lrt"
+  elif test "x$OPENJDK_BUILD_OS" = xmacosx; then
+    OPENJDK_BUILD_JVM_LIBS="$OPENJDK_BUILD_JVM_LIBS -lm"
+  elif test "x$OPENJDK_BUILD_OS" = xaix; then
+    OPENJDK_BUILD_JVM_LIBS="$OPENJDK_BUILD_JVM_LIBS -Wl,-lC_r -lm -ldl -lpthread"
+  elif test "x$OPENJDK_BUILD_OS" = xbsd; then
+    OPENJDK_BUILD_JVM_LIBS="$OPENJDK_BUILD_JVM_LIBS -lm"
+  elif test "x$OPENJDK_BUILD_OS" = xwindows; then
+    OPENJDK_BUILD_JVM_LIBS="$OPENJDK_BUILD_JVM_LIBS kernel32.lib user32.lib gdi32.lib winspool.lib \
+        comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib \
+        wsock32.lib winmm.lib version.lib psapi.lib"
+    fi
+
+  # Set OPENJDK_BUILD_JVM_ASFLAGS
+  if test "x$OPENJDK_BUILD_OS" = xlinux; then
+    if test "x$OPENJDK_BUILD_CPU" = xx86; then
+      OPENJDK_BUILD_JVM_ASFLAGS="$OPENJDK_BUILD_JVM_ASFLAGS -march=i586"
+    fi
+  elif test "x$OPENJDK_BUILD_OS" = xmacosx; then
+    OPENJDK_BUILD_JVM_ASFLAGS="$OPENJDK_BUILD_JVM_ASFLAGS -x assembler-with-cpp -mno-omit-leaf-frame-pointer -mstack-alignment=16"
+  fi
+
+  OPENJDK_BUILD_LDFLAGS_JDKLIB="${OPENJDK_BUILD_LDFLAGS_JDKLIB} ${OPENJDK_BUILD_EXTRA_LDFLAGS_JDK}"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+  # Tests are only ever compiled for TARGET
+  # Flags for compiling test libraries
+  CFLAGS_TESTLIB="$COMMON_CCXXFLAGS_JDK $CFLAGS_JDK $PICFLAG $CFLAGS_JDKLIB_EXTRA"
+  CXXFLAGS_TESTLIB="$COMMON_CCXXFLAGS_JDK $CXXFLAGS_JDK $PICFLAG $CXXFLAGS_JDKLIB_EXTRA"
+
+  # Flags for compiling test executables
+  CFLAGS_TESTEXE="$COMMON_CCXXFLAGS_JDK $CFLAGS_JDK"
+  CXXFLAGS_TESTEXE="$COMMON_CCXXFLAGS_JDK $CXXFLAGS_JDK"
 
 
 
@@ -49549,6 +51030,7 @@
 
 
 
+
   # Some Zero and Shark settings.
   # ZERO_ARCHFLAG tells the compiler which mode to build for
   case "${OPENJDK_TARGET_CPU}" in
@@ -50897,6 +52379,222 @@
 
 
 
+# Need toolchain to setup dtrace
+
+  # Test for dtrace dependencies
+  # Check whether --enable-dtrace was given.
+if test "${enable_dtrace+set}" = set; then :
+  enableval=$enable_dtrace;
+fi
+
+
+  DTRACE_DEP_MISSING=false
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dtrace tool" >&5
+$as_echo_n "checking for dtrace tool... " >&6; }
+  if test "x$DTRACE" != "x" && test -x "$DTRACE"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DTRACE" >&5
+$as_echo "$DTRACE" >&6; }
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found, cannot build dtrace" >&5
+$as_echo "not found, cannot build dtrace" >&6; }
+    DTRACE_DEP_MISSING=true
+  fi
+
+  for ac_header in sys/sdt.h
+do :
+  ac_fn_cxx_check_header_mongrel "$LINENO" "sys/sdt.h" "ac_cv_header_sys_sdt_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_sdt_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_SYS_SDT_H 1
+_ACEOF
+ DTRACE_HEADERS_OK=yes
+else
+  DTRACE_HEADERS_OK=no
+fi
+
+done
+
+  if test "x$DTRACE_HEADERS_OK" != "xyes"; then
+    DTRACE_DEP_MISSING=true
+  fi
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if dtrace should be built" >&5
+$as_echo_n "checking if dtrace should be built... " >&6; }
+  if test "x$enable_dtrace" = "xyes"; then
+    if test "x$DTRACE_DEP_MISSING" = "xtrue"; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, missing dependencies" >&5
+$as_echo "no, missing dependencies" >&6; }
+
+  # Print a helpful message on how to acquire the necessary build dependency.
+  # dtrace is the help tag: freetype, cups, alsa etc
+  MISSING_DEPENDENCY=dtrace
+
+  if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then
+    cygwin_help $MISSING_DEPENDENCY
+  elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then
+    msys_help $MISSING_DEPENDENCY
+  else
+    PKGHANDLER_COMMAND=
+
+    case $PKGHANDLER in
+      apt-get)
+        apt_help     $MISSING_DEPENDENCY ;;
+      yum)
+        yum_help     $MISSING_DEPENDENCY ;;
+      port)
+        port_help    $MISSING_DEPENDENCY ;;
+      pkgutil)
+        pkgutil_help $MISSING_DEPENDENCY ;;
+      pkgadd)
+        pkgadd_help  $MISSING_DEPENDENCY ;;
+    esac
+
+    if test "x$PKGHANDLER_COMMAND" != x; then
+      HELP_MSG="You might be able to fix this by running '$PKGHANDLER_COMMAND'."
+    fi
+  fi
+
+      as_fn_error $? "Cannot enable dtrace with missing dependencies. See above. $HELP_MSG" "$LINENO" 5
+    else
+      INCLUDE_DTRACE=true
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes, forced" >&5
+$as_echo "yes, forced" >&6; }
+    fi
+  elif test "x$enable_dtrace" = "xno"; then
+    INCLUDE_DTRACE=false
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, forced" >&5
+$as_echo "no, forced" >&6; }
+  elif test "x$enable_dtrace" = "xauto" || test "x$enable_dtrace" = "x"; then
+    if test "x$OPENJDK_TARGET_OS" = "xlinux" && test "x$OPENJDK" != "xtrue"; then
+      INCLUDE_DTRACE=false
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, non-open linux build" >&5
+$as_echo "no, non-open linux build" >&6; }
+    elif test "x$DTRACE_DEP_MISSING" = "xtrue"; then
+      INCLUDE_DTRACE=false
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, missing dependencies" >&5
+$as_echo "no, missing dependencies" >&6; }
+    else
+      INCLUDE_DTRACE=true
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes, dependencies present" >&5
+$as_echo "yes, dependencies present" >&6; }
+    fi
+  else
+    as_fn_error $? "Invalid value for --enable-dtrace: $enable_dtrace" "$LINENO" 5
+  fi
+
+
+
+  # The user can in some cases supply additional jvm features. For the custom
+  # variant, this defines the entire variant.
+
+# Check whether --with-jvm-features was given.
+if test "${with_jvm_features+set}" = set; then :
+  withval=$with_jvm_features;
+fi
+
+  if test "x$with_jvm_features" != x; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking additional JVM features" >&5
+$as_echo_n "checking additional JVM features... " >&6; }
+    JVM_FEATURES=`$ECHO $with_jvm_features | $SED -e 's/,/ /g'`
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $JVM_FEATURES" >&5
+$as_echo "$JVM_FEATURES" >&6; }
+  fi
+
+  # Verify that dependencies are met for explicitly set features.
+  if   [[ " $JVM_FEATURES " =~ " jvmti " ]]   && !   [[ " $JVM_FEATURES " =~ " services " ]]  ; then
+    as_fn_error $? "Specified JVM feature 'jvmti' requires feature 'services'" "$LINENO" 5
+  fi
+
+  if   [[ " $JVM_FEATURES " =~ " management " ]]   && !   [[ " $JVM_FEATURES " =~ " nmt " ]]  ; then
+    as_fn_error $? "Specified JVM feature 'management' requires feature 'nmt'" "$LINENO" 5
+  fi
+
+  if   [[ " $JVM_FEATURES " =~ " jvmci " ]]   && !   [[ " $JVM_FEATURES " =~ " compiler2 " ]]  ; then
+    as_fn_error $? "Specified JVM feature 'jvmci' requires feature 'compiler2'" "$LINENO" 5
+  fi
+
+  if   [[ " $JVM_FEATURES " =~ " compiler2 " ]]   && !   [[ " $JVM_FEATURES " =~ " all-gcs " ]]  ; then
+    as_fn_error $? "Specified JVM feature 'compiler2' requires feature 'all-gcs'" "$LINENO" 5
+  fi
+
+  if   [[ " $JVM_FEATURES " =~ " vm-structs " ]]   && !   [[ " $JVM_FEATURES " =~ " all-gcs " ]]  ; then
+    as_fn_error $? "Specified JVM feature 'vm-structs' requires feature 'all-gcs'" "$LINENO" 5
+  fi
+
+  # Turn on additional features based on other parts of configure
+  if test "x$INCLUDE_DTRACE" = "xtrue"; then
+    JVM_FEATURES="$JVM_FEATURES dtrace"
+  else
+    if   [[ " $JVM_FEATURES " =~ " dtrace " ]]  ; then
+      as_fn_error $? "To enable dtrace, you must use --enable-dtrace" "$LINENO" 5
+    fi
+  fi
+
+  if test "x$STATIC_BUILD" = "xtrue"; then
+    JVM_FEATURES="$JVM_FEATURES static-build"
+  else
+    if   [[ " $JVM_FEATURES " =~ " static-build " ]]  ; then
+      as_fn_error $? "To enable static-build, you must use --enable-static-build" "$LINENO" 5
+    fi
+  fi
+
+  if !   [[ " $JVM_VARIANTS " =~ " zero " ]]   && !   [[ " $JVM_VARIANTS " =~ " zeroshark " ]]  ; then
+    if   [[ " $JVM_FEATURES " =~ " zero " ]]  ; then
+      as_fn_error $? "To enable zero/zeroshark, you must use --with-jvm-variants=zero/zeroshark" "$LINENO" 5
+    fi
+  fi
+
+  if !   [[ " $JVM_VARIANTS " =~ " zeroshark " ]]  ; then
+    if   [[ " $JVM_FEATURES " =~ " shark " ]]  ; then
+      as_fn_error $? "To enable shark, you must use --with-jvm-variants=zeroshark" "$LINENO" 5
+    fi
+  fi
+
+  # Only enable jvmci on x86_64, sparcv9 and aarch64, and only on server.
+  if test "x$OPENJDK_TARGET_CPU" = "xx86_64" || \
+      test "x$OPENJDK_TARGET_CPU" = "xsparcv9" || \
+      test "x$OPENJDK_TARGET_CPU" = "xaarch64" ; then
+    JVM_FEATURES_jvmci="jvmci"
+  else
+    JVM_FEATURES_jvmci=""
+  fi
+
+  # All variants but minimal (and custom) get these features
+  NON_MINIMAL_FEATURES="$NON_MINIMAL_FEATURES jvmti fprof vm-structs jni-check services management all-gcs nmt cds"
+
+  # Enable features depending on variant.
+  JVM_FEATURES_server="compiler1 compiler2 $NON_MINIMAL_FEATURES $JVM_FEATURES $JVM_FEATURES_jvmci"
+  JVM_FEATURES_client="compiler1 $NON_MINIMAL_FEATURES $JVM_FEATURES"
+  JVM_FEATURES_core="$NON_MINIMAL_FEATURES $JVM_FEATURES"
+  JVM_FEATURES_minimal="compiler1 minimal $JVM_FEATURES"
+  JVM_FEATURES_zero="zero $NON_MINIMAL_FEATURES $JVM_FEATURES"
+  JVM_FEATURES_zeroshark="zero shark $NON_MINIMAL_FEATURES $JVM_FEATURES"
+  JVM_FEATURES_custom="$JVM_FEATURES"
+
+
+
+
+
+
+
+
+
+  # Used for verification of Makefiles by check-jvm-feature
+
+
+  # We don't support --with-jvm-interpreter anymore, use zero instead.
+
+
+# Check whether --with-jvm-interpreter was given.
+if test "${with_jvm_interpreter+set}" = set; then :
+  withval=$with_jvm_interpreter; { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Option --with-jvm-interpreter is deprecated and will be ignored." >&5
+$as_echo "$as_me: WARNING: Option --with-jvm-interpreter is deprecated and will be ignored." >&2;}
+fi
+
+
+
+
 ###############################################################################
 #
 # Check dependencies for external and internal libraries.
@@ -51023,7 +52721,7 @@
   fi
 
   # Check if ffi is needed
-  if test "x$JVM_VARIANT_ZERO" = xtrue || test "x$JVM_VARIANT_ZEROSHARK" = xtrue; then
+  if   [[ " $JVM_VARIANTS " =~ " zero " ]]   ||   [[ " $JVM_VARIANTS " =~ " zeroshark " ]]  ; then
     NEEDS_LIB_FFI=true
   else
     NEEDS_LIB_FFI=false
@@ -51146,14 +52844,26 @@
     # If dynamic wasn't requested, go with static unless it isn't available.
     { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link with libstdc++" >&5
 $as_echo_n "checking how to link with libstdc++... " >&6; }
-    if test "x$with_stdc__lib" = xdynamic || test "x$has_static_libstdcxx" = xno || test "x$JVM_VARIANT_ZEROSHARK" = xtrue; then
+    if test "x$with_stdc__lib" = xdynamic || test "x$has_static_libstdcxx" = xno ||   [[ " $JVM_VARIANTS " =~ " zeroshark " ]]  ; then
       LIBCXX="$LIBCXX -lstdc++"
+      # To help comparisons with old build, put stdc++ first in JVM_LIBS
+      JVM_LIBS="-lstdc++ $JVM_LIBS"
+      # Ideally, we should test stdc++ for the BUILD toolchain separately. For now
+      # just use the same setting as for the TARGET toolchain.
+      OPENJDK_BUILD_JVM_LIBS="-lstdc++ $OPENJDK_BUILD_JVM_LIBS"
       LDCXX="$CXX"
       STATIC_CXX_SETTING="STATIC_CXX=false"
       { $as_echo "$as_me:${as_lineno-$LINENO}: result: dynamic" >&5
 $as_echo "dynamic" >&6; }
     else
       LIBCXX="$LIBCXX $STATIC_STDCXX_FLAGS"
+      JVM_LDFLAGS="$JVM_LDFLAGS -static-libgcc"
+      # To help comparisons with old build, put stdc++ first in JVM_LIBS
+      JVM_LIBS="-Wl,-Bstatic -lstdc++ -Wl,-Bdynamic $JVM_LIBS"
+      # Ideally, we should test stdc++ for the BUILD toolchain separately. For now
+      # just use the same setting as for the TARGET toolchain.
+      OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS -static-libgcc"
+      OPENJDK_BUILD_JVM_LIBS="-Wl,-Bstatic -lstdc++ -Wl,-Bdynamic $OPENJDK_BUILD_JVM_LIBS"
       LDCXX="$CC"
       STATIC_CXX_SETTING="STATIC_CXX=true"
       { $as_echo "$as_me:${as_lineno-$LINENO}: result: static" >&5
@@ -61305,7 +63015,7 @@
 
 
 
-  if test "x$JVM_VARIANT_ZEROSHARK" = xtrue; then
+  if   [[ " $JVM_VARIANTS " =~ " zeroshark " ]]  ; then
     # Extract the first word of "llvm-config", so it can be a program name with args.
 set dummy llvm-config; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
@@ -62031,9 +63741,143 @@
 ###############################################################################
 
 
+  # Check whether --enable-new-hotspot-build was given.
+if test "${enable_new_hotspot_build+set}" = set; then :
+  enableval=$enable_new_hotspot_build;
+fi
+
+
+   if test "x$enable_new_hotspot_build" = "x" || test "x$enable_new_hotspot_build" = "xyes"; then
+     USE_NEW_HOTSPOT_BUILD=true
+   else
+     USE_NEW_HOTSPOT_BUILD=false
+   fi
+
+
+  case $HOTSPOT_DEBUG_LEVEL in
+    product )
+      VARIANT="OPT"
+      FASTDEBUG="false"
+      DEBUG_CLASSFILES="false"
+      ;;
+    fastdebug )
+      VARIANT="DBG"
+      FASTDEBUG="true"
+      DEBUG_CLASSFILES="true"
+      ;;
+    debug )
+      VARIANT="DBG"
+      FASTDEBUG="false"
+      DEBUG_CLASSFILES="true"
+      ;;
+    optimized )
+      VARIANT="OPT"
+      FASTDEBUG="false"
+      DEBUG_CLASSFILES="false"
+      ;;
+  esac
+
+
+
+
+  if test "x$OPENJDK_TARGET_OS" = "xmacosx"; then
+    MACOSX_UNIVERSAL="true"
+  fi
+
+
+
+  # Make sure JVM_VARIANTS_COMMA use minimal1 for backwards compatibility
+  JVM_VARIANTS_COMMA=`$ECHO ,$JVM_VARIANTS_OPT, | $SED -e 's/,minimal,/,minimal1,/'`
+
+  JVM_VARIANT_SERVER=`$ECHO "$JVM_VARIANTS_COMMA" | $SED -e '/,server,/!s/.*/false/g' -e '/,server,/s/.*/true/g'`
+  JVM_VARIANT_CLIENT=`$ECHO "$JVM_VARIANTS_COMMA" | $SED -e '/,client,/!s/.*/false/g' -e '/,client,/s/.*/true/g'`
+  JVM_VARIANT_MINIMAL1=`$ECHO "$JVM_VARIANTS_COMMA" | $SED -e '/,minimal1\?,/!s/.*/false/g' -e '/,minimal1\?,/s/.*/true/g'`
+  JVM_VARIANT_CORE=`$ECHO "$JVM_VARIANTS_COMMA" | $SED -e '/,core,/!s/.*/false/g' -e '/,core,/s/.*/true/g'`
+  JVM_VARIANT_ZERO=`$ECHO "$JVM_VARIANTS_COMMA" | $SED -e '/,zero,/!s/.*/false/g' -e '/,zero,/s/.*/true/g'`
+  JVM_VARIANT_ZEROSHARK=`$ECHO "$JVM_VARIANTS_COMMA" | $SED -e '/,zeroshark,/!s/.*/false/g' -e '/,zeroshark,/s/.*/true/g'`
+  JVM_VARIANT_CUSTOM=`$ECHO "$JVM_VARIANTS_COMMA" | $SED -e '/,custom,/!s/.*/false/g' -e '/,custom,/s/.*/true/g'`
+
+  #####
+  # Generate the legacy makefile targets for hotspot.
+  HOTSPOT_TARGET=""
+
+  if test "x$JVM_VARIANT_SERVER" = xtrue; then
+    HOTSPOT_TARGET="$HOTSPOT_TARGET${HOTSPOT_DEBUG_LEVEL} "
+  fi
+
+  if test "x$JVM_VARIANT_CLIENT" = xtrue; then
+    HOTSPOT_TARGET="$HOTSPOT_TARGET${HOTSPOT_DEBUG_LEVEL}1 "
+  fi
+
+  if test "x$JVM_VARIANT_MINIMAL1" = xtrue; then
+    HOTSPOT_TARGET="$HOTSPOT_TARGET${HOTSPOT_DEBUG_LEVEL}minimal1 "
+  fi
+
+  if test "x$JVM_VARIANT_ZERO" = xtrue; then
+    HOTSPOT_TARGET="$HOTSPOT_TARGET${HOTSPOT_DEBUG_LEVEL}zero "
+  fi
+
+  if test "x$JVM_VARIANT_ZEROSHARK" = xtrue; then
+    HOTSPOT_TARGET="$HOTSPOT_TARGET${HOTSPOT_DEBUG_LEVEL}shark "
+  fi
+
+  if test "x$JVM_VARIANT_CORE" = xtrue; then
+    HOTSPOT_TARGET="$HOTSPOT_TARGET${HOTSPOT_DEBUG_LEVEL}core "
+  fi
+
+  HOTSPOT_TARGET="$HOTSPOT_TARGET docs export_$HOTSPOT_DEBUG_LEVEL"
+
+  # On Macosx universal binaries are produced, but they only contain
+  # 64 bit intel. This invalidates control of which jvms are built
+  # from configure, but only server is valid anyway. Fix this
+  # when hotspot makefiles are rewritten.
+  if test "x$MACOSX_UNIVERSAL" = xtrue; then
+    HOTSPOT_TARGET=universal_${HOTSPOT_DEBUG_LEVEL}
+  fi
+
   HOTSPOT_MAKE_ARGS="$HOTSPOT_TARGET"
 
 
+  # Control wether Hotspot runs Queens test after build.
+  # Check whether --enable-hotspot-test-in-build was given.
+if test "${enable_hotspot_test_in_build+set}" = set; then :
+  enableval=$enable_hotspot_test_in_build;
+else
+  enable_hotspot_test_in_build=no
+fi
+
+  if test "x$enable_hotspot_test_in_build" = "xyes"; then
+    TEST_IN_BUILD=true
+  else
+    TEST_IN_BUILD=false
+  fi
+
+
+  if test "x$USE_NEW_HOTSPOT_BUILD" = xfalse; then
+    if test "x$JVM_VARIANT_CLIENT" = xtrue; then
+      if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then
+        as_fn_error $? "You cannot build a client JVM for a 64-bit machine." "$LINENO" 5
+      fi
+    fi
+    if test "x$JVM_VARIANT_MINIMAL1" = xtrue; then
+      if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then
+        as_fn_error $? "You cannot build a minimal JVM for a 64-bit machine." "$LINENO" 5
+      fi
+    fi
+    if test "x$JVM_VARIANT_CUSTOM" = xtrue; then
+        as_fn_error $? "You cannot build a custom JVM using the old hotspot build system." "$LINENO" 5
+    fi
+  fi
+
+
+
+
+
+
+
+
+
+
 
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking if elliptic curve crypto implementation is present" >&5
 $as_echo_n "checking if elliptic curve crypto implementation is present... " >&6; }
@@ -63322,6 +65166,10 @@
     { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, does not work effectively with icecc" >&5
 $as_echo "no, does not work effectively with icecc" >&6; }
     USE_PRECOMPILED_HEADER=0
+  elif test "x$TOOLCHAIN_TYPE" = xsolstudio; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, does not work with Solaris Studio" >&5
+$as_echo "no, does not work with Solaris Studio" >&6; }
+    USE_PRECOMPILED_HEADER=0
   else
     { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
 $as_echo "yes" >&6; }
@@ -63742,6 +65590,32 @@
 # At the end, call the custom hook. (Dummy macro if no custom sources available)
 
 
+# This needs to be done after CUSTOM_LATE_HOOK since we can setup custom features.
+
+  # Keep feature lists sorted and free of duplicates
+  JVM_FEATURES_server="$($ECHO $($PRINTF '%s\n' $JVM_FEATURES_server | $SORT -u))"
+  JVM_FEATURES_client="$($ECHO $($PRINTF '%s\n' $JVM_FEATURES_client | $SORT -u))"
+  JVM_FEATURES_core="$($ECHO $($PRINTF '%s\n' $JVM_FEATURES_core | $SORT -u))"
+  JVM_FEATURES_minimal="$($ECHO $($PRINTF '%s\n' $JVM_FEATURES_minimal | $SORT -u))"
+  JVM_FEATURES_zero="$($ECHO $($PRINTF '%s\n' $JVM_FEATURES_zero | $SORT -u))"
+  JVM_FEATURES_zeroshark="$($ECHO $($PRINTF '%s\n' $JVM_FEATURES_zeroshark | $SORT -u))"
+  JVM_FEATURES_custom="$($ECHO $($PRINTF '%s\n' $JVM_FEATURES_custom | $SORT -u))"
+
+  # Validate features
+  for variant in $JVM_VARIANTS; do
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking JVM features for JVM variant '$variant'" >&5
+$as_echo_n "checking JVM features for JVM variant '$variant'... " >&6; }
+    features_var_name=JVM_FEATURES_$variant
+    JVM_FEATURES_TO_TEST=${!features_var_name}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $JVM_FEATURES_TO_TEST" >&5
+$as_echo "$JVM_FEATURES_TO_TEST" >&6; }
+    INVALID_FEATURES=`$GREP -Fvx "${VALID_JVM_FEATURES// /$'\n'}" <<< "${JVM_FEATURES_TO_TEST// /$'\n'}"`
+    if test "x$INVALID_FEATURES" != x; then
+      as_fn_error $? "Invalid JVM feature(s): $INVALID_FEATURES" "$LINENO" 5
+    fi
+  done
+
+
 # We're messing a bit with internal autoconf variables to put the config.status
 # in the output directory instead of the current directory.
 CONFIG_STATUS="$CONFIGURESUPPORT_OUTPUTDIR/config.status"
@@ -64965,7 +66839,7 @@
   printf "* Debug level:    $DEBUG_LEVEL\n"
   printf "* HS debug level: $HOTSPOT_DEBUG_LEVEL\n"
   printf "* JDK variant:    $JDK_VARIANT\n"
-  printf "* JVM variants:   $with_jvm_variants\n"
+  printf "* JVM variants:   $JVM_VARIANTS\n"
   printf "* OpenJDK target: OS: $OPENJDK_TARGET_OS, CPU architecture: $OPENJDK_TARGET_CPU_ARCH, address length: $OPENJDK_TARGET_CPU_BITS\n"
   printf "* Version string: $VERSION_STRING ($VERSION_SHORT)\n"
 
@@ -64991,7 +66865,7 @@
   fi
   printf "\n"
 
-  if test "x$BUILDING_MULTIPLE_JVM_VARIANTS" = "xyes"; then
+  if test "x$BUILDING_MULTIPLE_JVM_VARIANTS" = "xtrue"; then
     printf "NOTE: You have requested to build more than one version of the JVM, which\n"
     printf "will result in longer build times.\n"
     printf "\n"
--- a/common/autoconf/help.m4	Thu Apr 21 12:57:17 2016 -0700
+++ b/common/autoconf/help.m4	Wed Jul 05 21:37:42 2017 +0200
@@ -119,6 +119,8 @@
       PKGHANDLER_COMMAND="sudo apt-get install libX11-dev libxext-dev libxrender-dev libxtst-dev libxt-dev" ;;
     ccache)
       PKGHANDLER_COMMAND="sudo apt-get install ccache" ;;
+    dtrace)
+      PKGHANDLER_COMMAND="sudo apt-get install systemtap-sdt-dev" ;;
   esac
 }
 
@@ -170,6 +172,13 @@
       TOOLCHAIN_DESCRIPTION=${!toolchain_var_name}
       $PRINTF "  %-10s  %s\n" $toolchain "$TOOLCHAIN_DESCRIPTION"
     done
+    $PRINTF "\n"
+
+    # Print available jvm features
+    $PRINTF "The following JVM features are available as arguments to --with-jvm-features.\n"
+    $PRINTF "Which are valid to use depends on the target platform.\n  "
+    $PRINTF "%s " $VALID_JVM_FEATURES
+    $PRINTF "\n"
 
     # And now exit directly
     exit 0
@@ -206,7 +215,7 @@
   printf "* Debug level:    $DEBUG_LEVEL\n"
   printf "* HS debug level: $HOTSPOT_DEBUG_LEVEL\n"
   printf "* JDK variant:    $JDK_VARIANT\n"
-  printf "* JVM variants:   $with_jvm_variants\n"
+  printf "* JVM variants:   $JVM_VARIANTS\n"
   printf "* OpenJDK target: OS: $OPENJDK_TARGET_OS, CPU architecture: $OPENJDK_TARGET_CPU_ARCH, address length: $OPENJDK_TARGET_CPU_BITS\n"
   printf "* Version string: $VERSION_STRING ($VERSION_SHORT)\n"
 
@@ -232,7 +241,7 @@
   fi
   printf "\n"
 
-  if test "x$BUILDING_MULTIPLE_JVM_VARIANTS" = "xyes"; then
+  if test "x$BUILDING_MULTIPLE_JVM_VARIANTS" = "xtrue"; then
     printf "NOTE: You have requested to build more than one version of the JVM, which\n"
     printf "will result in longer build times.\n"
     printf "\n"
--- a/common/autoconf/hotspot-spec.gmk.in	Thu Apr 21 12:57:17 2016 -0700
+++ b/common/autoconf/hotspot-spec.gmk.in	Wed Jul 05 21:37:42 2017 +0200
@@ -38,6 +38,16 @@
 # Legacy defines controlled by the SUPPORT_HEADLESS and SUPPORT_HEADFUL options.
 @BUILD_HEADLESS@
 
+JVM_VARIANTS:=@JVM_VARIANTS_COMMA@
+
+JVM_VARIANT_SERVER:=@JVM_VARIANT_SERVER@
+JVM_VARIANT_CLIENT:=@JVM_VARIANT_CLIENT@
+JVM_VARIANT_MINIMAL1:=@JVM_VARIANT_MINIMAL1@
+JVM_VARIANT_CORE:=@JVM_VARIANT_CORE@
+JVM_VARIANT_ZERO:=@JVM_VARIANT_ZERO@
+JVM_VARIANT_ZEROSHARK:=@JVM_VARIANT_ZEROSHARK@
+JVM_VARIANT_CUSTOM:=@JVM_VARIANT_HOTSPOT@
+
 # Legacy setting: OPT or DBG
 VARIANT:=@VARIANT@
 # Legacy setting: true or false
@@ -92,8 +102,7 @@
 ALT_OUTPUTDIR=$(HOTSPOT_OUTPUTDIR)
 ALT_EXPORT_PATH=$(HOTSPOT_DIST)
 
-JVM_INTERPRETER:=@JVM_INTERPRETER@
-ifeq ($(JVM_INTERPRETER), cpp)
+ifeq ($(HOTSPOT_TARGET_CPU), zero)
   CC_INTERP=true
 endif
 
--- a/common/autoconf/hotspot.m4	Thu Apr 21 12:57:17 2016 -0700
+++ b/common/autoconf/hotspot.m4	Wed Jul 05 21:37:42 2017 +0200
@@ -23,170 +23,344 @@
 # questions.
 #
 
-###############################################################################
-# Check which interpreter of the JVM we want to build.
-# Currently we have:
-#    template: Template interpreter (the default)
-#    cpp     : C++ interpreter
-AC_DEFUN_ONCE([HOTSPOT_SETUP_JVM_INTERPRETER],
-[
-  AC_ARG_WITH([jvm-interpreter], [AS_HELP_STRING([--with-jvm-interpreter],
-    [JVM interpreter to build (template, cpp) @<:@template@:>@])])
+# All valid JVM features, regardless of platform
+VALID_JVM_FEATURES="compiler1 compiler2 zero shark minimal dtrace jvmti jvmci \
+    fprof vm-structs jni-check services management all-gcs nmt cds static-build"
+
+# All valid JVM variants
+VALID_JVM_VARIANTS="server client minimal core zero zeroshark custom"
 
-  AC_MSG_CHECKING([which interpreter of the JVM to build])
-  if test "x$with_jvm_interpreter" = x; then
-    JVM_INTERPRETER="template"
-  else
-    JVM_INTERPRETER="$with_jvm_interpreter"
-  fi
-  AC_MSG_RESULT([$JVM_INTERPRETER])
+###############################################################################
+# Check if the specified JVM variant should be built. To be used in shell if
+# constructs, like this:
+# if HOTSPOT_CHECK_JVM_VARIANT(server); then
+#
+# Only valid to use after HOTSPOT_SETUP_JVM_VARIANTS has setup variants.
 
-  if test "x$JVM_INTERPRETER" != xtemplate && test "x$JVM_INTERPRETER" != xcpp; then
-    AC_MSG_ERROR([The available JVM interpreters are: template, cpp])
-  fi
-
-  AC_SUBST(JVM_INTERPRETER)
-])
+# Definition kept in one line to allow inlining in if statements.
+# Additional [] needed to keep m4 from mangling shell constructs.
+AC_DEFUN([HOTSPOT_CHECK_JVM_VARIANT],
+[ [ [[ " $JVM_VARIANTS " =~ " $1 " ]] ] ])
 
 ###############################################################################
-# Check which variants of the JVM that we want to build.
-# Currently we have:
-#    server: normal interpreter and a C2 or tiered C1/C2 compiler
-#    client: normal interpreter and C1 (no C2 compiler) (only 32-bit platforms)
-#    minimal1: reduced form of client with optional VM services and features stripped out
-#    zero: no machine code interpreter, no compiler
-#    zeroshark: zero interpreter and shark/llvm compiler backend
-#    core: interpreter only, no compiler (only works on some platforms)
+# Check if the specified JVM features are explicitly enabled. To be used in
+# shell if constructs, like this:
+# if HOTSPOT_CHECK_JVM_FEATURE(jvmti); then
+#
+# Only valid to use after HOTSPOT_SETUP_JVM_FEATURES has setup features.
+
+# Definition kept in one line to allow inlining in if statements.
+# Additional [] needed to keep m4 from mangling shell constructs.
+AC_DEFUN([HOTSPOT_CHECK_JVM_FEATURE],
+[ [ [[ " $JVM_FEATURES " =~ " $1 " ]] ] ])
+
+###############################################################################
+# Check which variants of the JVM that we want to build. Available variants are:
+#   server: normal interpreter, and a tiered C1/C2 compiler
+#   client: normal interpreter, and C1 (no C2 compiler)
+#   minimal: reduced form of client with optional features stripped out
+#   core: normal interpreter only, no compiler
+#   zero: C++ based interpreter only, no compiler
+#   zeroshark: C++ based interpreter, and a llvm-based compiler
+#   custom: baseline JVM with no default features
+#
 AC_DEFUN_ONCE([HOTSPOT_SETUP_JVM_VARIANTS],
 [
-  AC_MSG_CHECKING([which variants of the JVM to build])
   AC_ARG_WITH([jvm-variants], [AS_HELP_STRING([--with-jvm-variants],
-      [JVM variants (separated by commas) to build (server, client, minimal1, zero, zeroshark, core) @<:@server@:>@])])
+      [JVM variants (separated by commas) to build (server,client,minimal,core,zero,zeroshark,custom) @<:@server@:>@])])
 
   if test "x$with_jvm_variants" = x; then
     with_jvm_variants="server"
   fi
+  JVM_VARIANTS_OPT="$with_jvm_variants"
 
-  JVM_VARIANTS=",$with_jvm_variants,"
-  TEST_VARIANTS=`$ECHO "$JVM_VARIANTS" | $SED -e 's/server,//' -e 's/client,//'  -e 's/minimal1,//' -e 's/zero,//' -e 's/zeroshark,//' -e 's/core,//'`
+  # Has the user listed more than one variant?
+  # Additional [] needed to keep m4 from mangling shell constructs.
+  if [ [[ "$JVM_VARIANTS_OPT" =~ "," ]] ]; then
+    BUILDING_MULTIPLE_JVM_VARIANTS=true
+  else
+    BUILDING_MULTIPLE_JVM_VARIANTS=false
+  fi
+  # Replace the commas with AND for use in the build directory name.
+  JVM_VARIANTS_WITH_AND=`$ECHO "$JVM_VARIANTS_OPT" | $SED -e 's/,/AND/g'`
+
+  AC_MSG_CHECKING([which variants of the JVM to build])
+  # JVM_VARIANTS is a space-separated list.
+  # Also use minimal, not minimal1 (which is kept for backwards compatibility).
+  JVM_VARIANTS=`$ECHO $JVM_VARIANTS_OPT | $SED -e 's/,/ /g' -e 's/minimal1/minimal/'`
+  AC_MSG_RESULT([$JVM_VARIANTS])
+
+  # Check that the selected variants are valid
+
+  # grep filter function inspired by a comment to http://stackoverflow.com/a/1617326
+  INVALID_VARIANTS=`$GREP -Fvx "${VALID_JVM_VARIANTS// /$'\n'}" <<< "${JVM_VARIANTS// /$'\n'}"`
+  if test "x$INVALID_VARIANTS" != x; then
+    AC_MSG_NOTICE([Unknown variant(s) specified: $INVALID_VARIANTS])
+    AC_MSG_ERROR([The available JVM variants are: $VALID_JVM_VARIANTS])
+  fi
+
+  # All "special" variants share the same output directory ("server")
+  VALID_MULTIPLE_JVM_VARIANTS="server client minimal"
+  INVALID_MULTIPLE_VARIANTS=`$GREP -Fvx "${VALID_MULTIPLE_JVM_VARIANTS// /$'\n'}" <<< "${JVM_VARIANTS// /$'\n'}"`
+  if  test "x$INVALID_MULTIPLE_VARIANTS" != x && test "x$BUILDING_MULTIPLE_JVM_VARIANTS" = xtrue; then
+    AC_MSG_ERROR([You cannot build multiple variants with anything else than $VALID_MULTIPLE_JVM_VARIANTS.])
+  fi
 
-  if test "x$TEST_VARIANTS" != "x,"; then
-    AC_MSG_ERROR([The available JVM variants are: server, client, minimal1, zero, zeroshark, core])
+  AC_SUBST(JVM_VARIANTS)
+  AC_SUBST(VALID_JVM_VARIANTS)
+
+  if HOTSPOT_CHECK_JVM_VARIANT(zero) || HOTSPOT_CHECK_JVM_VARIANT(zeroshark); then
+    # zero behaves as a platform and rewrites these values. This is really weird. :(
+    # We are guaranteed that we do not build any other variants when building zero.
+    HOTSPOT_TARGET_CPU=zero
+    HOTSPOT_TARGET_CPU_ARCH=zero
   fi
-  AC_MSG_RESULT([$with_jvm_variants])
+])
+
+###############################################################################
+# Check if dtrace should be enabled and has all prerequisites present.
+#
+AC_DEFUN_ONCE([HOTSPOT_SETUP_DTRACE],
+[
+  # Test for dtrace dependencies
+  AC_ARG_ENABLE([dtrace], [AS_HELP_STRING([--enable-dtrace@<:@=yes/no/auto@:>@],
+      [enable dtrace. Default is auto, where dtrace is enabled if all dependencies
+      are present.])])
+
+  DTRACE_DEP_MISSING=false
+
+  AC_MSG_CHECKING([for dtrace tool])
+  if test "x$DTRACE" != "x" && test -x "$DTRACE"; then
+    AC_MSG_RESULT([$DTRACE])
+  else
+    AC_MSG_RESULT([not found, cannot build dtrace])
+    DTRACE_DEP_MISSING=true
+  fi
+
+  AC_CHECK_HEADERS([sys/sdt.h], [DTRACE_HEADERS_OK=yes],[DTRACE_HEADERS_OK=no])
+  if test "x$DTRACE_HEADERS_OK" != "xyes"; then
+    DTRACE_DEP_MISSING=true
+  fi
 
-  JVM_VARIANT_SERVER=`$ECHO "$JVM_VARIANTS" | $SED -e '/,server,/!s/.*/false/g' -e '/,server,/s/.*/true/g'`
-  JVM_VARIANT_CLIENT=`$ECHO "$JVM_VARIANTS" | $SED -e '/,client,/!s/.*/false/g' -e '/,client,/s/.*/true/g'`
-  JVM_VARIANT_MINIMAL1=`$ECHO "$JVM_VARIANTS" | $SED -e '/,minimal1,/!s/.*/false/g' -e '/,minimal1,/s/.*/true/g'`
-  JVM_VARIANT_ZERO=`$ECHO "$JVM_VARIANTS" | $SED -e '/,zero,/!s/.*/false/g' -e '/,zero,/s/.*/true/g'`
-  JVM_VARIANT_ZEROSHARK=`$ECHO "$JVM_VARIANTS" | $SED -e '/,zeroshark,/!s/.*/false/g' -e '/,zeroshark,/s/.*/true/g'`
-  JVM_VARIANT_CORE=`$ECHO "$JVM_VARIANTS" | $SED -e '/,core,/!s/.*/false/g' -e '/,core,/s/.*/true/g'`
+  AC_MSG_CHECKING([if dtrace should be built])
+  if test "x$enable_dtrace" = "xyes"; then
+    if test "x$DTRACE_DEP_MISSING" = "xtrue"; then
+      AC_MSG_RESULT([no, missing dependencies])
+      HELP_MSG_MISSING_DEPENDENCY([dtrace])
+      AC_MSG_ERROR([Cannot enable dtrace with missing dependencies. See above. $HELP_MSG])
+    else
+      INCLUDE_DTRACE=true
+      AC_MSG_RESULT([yes, forced])
+    fi
+  elif test "x$enable_dtrace" = "xno"; then
+    INCLUDE_DTRACE=false
+    AC_MSG_RESULT([no, forced])
+  elif test "x$enable_dtrace" = "xauto" || test "x$enable_dtrace" = "x"; then
+    if test "x$OPENJDK_TARGET_OS" = "xlinux" && test "x$OPENJDK" != "xtrue"; then
+      INCLUDE_DTRACE=false
+      AC_MSG_RESULT([no, non-open linux build])
+    elif test "x$DTRACE_DEP_MISSING" = "xtrue"; then
+      INCLUDE_DTRACE=false
+      AC_MSG_RESULT([no, missing dependencies])
+    else
+      INCLUDE_DTRACE=true
+      AC_MSG_RESULT([yes, dependencies present])
+    fi
+  else
+    AC_MSG_ERROR([Invalid value for --enable-dtrace: $enable_dtrace])
+  fi
+  AC_SUBST(INCLUDE_DTRACE)
+])
 
-  if test "x$JVM_VARIANT_CLIENT" = xtrue; then
-    if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then
-      AC_MSG_ERROR([You cannot build a client JVM for a 64-bit machine.])
-    fi
+###############################################################################
+# Set up all JVM features for each JVM variant.
+#
+AC_DEFUN_ONCE([HOTSPOT_SETUP_JVM_FEATURES],
+[
+  # The user can in some cases supply additional jvm features. For the custom
+  # variant, this defines the entire variant.
+  AC_ARG_WITH([jvm-features], [AS_HELP_STRING([--with-jvm-features],
+      [additional JVM features to enable (separated by comma),  use '--help' to show possible values @<:@none@:>@])])
+  if test "x$with_jvm_features" != x; then
+    AC_MSG_CHECKING([additional JVM features])
+    JVM_FEATURES=`$ECHO $with_jvm_features | $SED -e 's/,/ /g'`
+    AC_MSG_RESULT([$JVM_FEATURES])
+  fi
+
+  # Verify that dependencies are met for explicitly set features.
+  if HOTSPOT_CHECK_JVM_FEATURE(jvmti) && ! HOTSPOT_CHECK_JVM_FEATURE(services); then
+    AC_MSG_ERROR([Specified JVM feature 'jvmti' requires feature 'services'])
   fi
-  if test "x$JVM_VARIANT_MINIMAL1" = xtrue; then
-    if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then
-      AC_MSG_ERROR([You cannot build a minimal JVM for a 64-bit machine.])
+
+  if HOTSPOT_CHECK_JVM_FEATURE(management) && ! HOTSPOT_CHECK_JVM_FEATURE(nmt); then
+    AC_MSG_ERROR([Specified JVM feature 'management' requires feature 'nmt'])
+  fi
+
+  if HOTSPOT_CHECK_JVM_FEATURE(jvmci) && ! HOTSPOT_CHECK_JVM_FEATURE(compiler2); then
+    AC_MSG_ERROR([Specified JVM feature 'jvmci' requires feature 'compiler2'])
+  fi
+
+  if HOTSPOT_CHECK_JVM_FEATURE(compiler2) && ! HOTSPOT_CHECK_JVM_FEATURE(all-gcs); then
+    AC_MSG_ERROR([Specified JVM feature 'compiler2' requires feature 'all-gcs'])
+  fi
+
+  if HOTSPOT_CHECK_JVM_FEATURE(vm-structs) && ! HOTSPOT_CHECK_JVM_FEATURE(all-gcs); then
+    AC_MSG_ERROR([Specified JVM feature 'vm-structs' requires feature 'all-gcs'])
+  fi
+
+  # Turn on additional features based on other parts of configure
+  if test "x$INCLUDE_DTRACE" = "xtrue"; then
+    JVM_FEATURES="$JVM_FEATURES dtrace"
+  else
+    if HOTSPOT_CHECK_JVM_FEATURE(dtrace); then
+      AC_MSG_ERROR([To enable dtrace, you must use --enable-dtrace])
     fi
   fi
 
-  # Replace the commas with AND for use in the build directory name.
-  ANDED_JVM_VARIANTS=`$ECHO "$JVM_VARIANTS" | $SED -e 's/^,//' -e 's/,$//' -e 's/,/AND/g'`
-  COUNT_VARIANTS=`$ECHO "$JVM_VARIANTS" | $SED -e 's/server,/1/' -e 's/client,/1/' -e 's/minimal1,/1/' -e 's/zero,/1/' -e 's/zeroshark,/1/' -e 's/core,/1/'`
-  if test "x$COUNT_VARIANTS" != "x,1"; then
-    BUILDING_MULTIPLE_JVM_VARIANTS=yes
+  if test "x$STATIC_BUILD" = "xtrue"; then
+    JVM_FEATURES="$JVM_FEATURES static-build"
   else
-    BUILDING_MULTIPLE_JVM_VARIANTS=no
+    if HOTSPOT_CHECK_JVM_FEATURE(static-build); then
+      AC_MSG_ERROR([To enable static-build, you must use --enable-static-build])
+    fi
+  fi
+
+  if ! HOTSPOT_CHECK_JVM_VARIANT(zero) && ! HOTSPOT_CHECK_JVM_VARIANT(zeroshark); then
+    if HOTSPOT_CHECK_JVM_FEATURE(zero); then
+      AC_MSG_ERROR([To enable zero/zeroshark, you must use --with-jvm-variants=zero/zeroshark])
+    fi
+  fi
+
+  if ! HOTSPOT_CHECK_JVM_VARIANT(zeroshark); then
+    if HOTSPOT_CHECK_JVM_FEATURE(shark); then
+      AC_MSG_ERROR([To enable shark, you must use --with-jvm-variants=zeroshark])
+    fi
+  fi
+
+  # Only enable jvmci on x86_64, sparcv9 and aarch64, and only on server.
+  if test "x$OPENJDK_TARGET_CPU" = "xx86_64" || \
+      test "x$OPENJDK_TARGET_CPU" = "xsparcv9" || \
+      test "x$OPENJDK_TARGET_CPU" = "xaarch64" ; then
+    JVM_FEATURES_jvmci="jvmci"
+  else
+    JVM_FEATURES_jvmci=""
   fi
 
-  if test "x$JVM_VARIANT_ZERO" = xtrue && test "x$BUILDING_MULTIPLE_JVM_VARIANTS" = xyes; then
-    AC_MSG_ERROR([You cannot build multiple variants with zero.])
-  fi
+  # All variants but minimal (and custom) get these features
+  NON_MINIMAL_FEATURES="$NON_MINIMAL_FEATURES jvmti fprof vm-structs jni-check services management all-gcs nmt cds"
+
+  # Enable features depending on variant.
+  JVM_FEATURES_server="compiler1 compiler2 $NON_MINIMAL_FEATURES $JVM_FEATURES $JVM_FEATURES_jvmci"
+  JVM_FEATURES_client="compiler1 $NON_MINIMAL_FEATURES $JVM_FEATURES"
+  JVM_FEATURES_core="$NON_MINIMAL_FEATURES $JVM_FEATURES"
+  JVM_FEATURES_minimal="compiler1 minimal $JVM_FEATURES"
+  JVM_FEATURES_zero="zero $NON_MINIMAL_FEATURES $JVM_FEATURES"
+  JVM_FEATURES_zeroshark="zero shark $NON_MINIMAL_FEATURES $JVM_FEATURES"
+  JVM_FEATURES_custom="$JVM_FEATURES"
+
+  AC_SUBST(JVM_FEATURES_server)
+  AC_SUBST(JVM_FEATURES_client)
+  AC_SUBST(JVM_FEATURES_core)
+  AC_SUBST(JVM_FEATURES_minimal)
+  AC_SUBST(JVM_FEATURES_zero)
+  AC_SUBST(JVM_FEATURES_zeroshark)
+  AC_SUBST(JVM_FEATURES_custom)
+
+  # Used for verification of Makefiles by check-jvm-feature
+  AC_SUBST(VALID_JVM_FEATURES)
+
+  # We don't support --with-jvm-interpreter anymore, use zero instead.
+  BASIC_DEPRECATED_ARG_WITH(jvm-interpreter)
+])
+
+###############################################################################
+# Validate JVM features once all setup is complete, including custom setup.
+#
+AC_DEFUN_ONCE([HOTSPOT_VALIDATE_JVM_FEATURES],
+[
+  # Keep feature lists sorted and free of duplicates
+  JVM_FEATURES_server="$($ECHO $($PRINTF '%s\n' $JVM_FEATURES_server | $SORT -u))"
+  JVM_FEATURES_client="$($ECHO $($PRINTF '%s\n' $JVM_FEATURES_client | $SORT -u))"
+  JVM_FEATURES_core="$($ECHO $($PRINTF '%s\n' $JVM_FEATURES_core | $SORT -u))"
+  JVM_FEATURES_minimal="$($ECHO $($PRINTF '%s\n' $JVM_FEATURES_minimal | $SORT -u))"
+  JVM_FEATURES_zero="$($ECHO $($PRINTF '%s\n' $JVM_FEATURES_zero | $SORT -u))"
+  JVM_FEATURES_zeroshark="$($ECHO $($PRINTF '%s\n' $JVM_FEATURES_zeroshark | $SORT -u))"
+  JVM_FEATURES_custom="$($ECHO $($PRINTF '%s\n' $JVM_FEATURES_custom | $SORT -u))"
 
-  AC_SUBST(JVM_VARIANTS)
-  AC_SUBST(JVM_VARIANT_SERVER)
-  AC_SUBST(JVM_VARIANT_CLIENT)
-  AC_SUBST(JVM_VARIANT_MINIMAL1)
-  AC_SUBST(JVM_VARIANT_ZERO)
-  AC_SUBST(JVM_VARIANT_ZEROSHARK)
-  AC_SUBST(JVM_VARIANT_CORE)
+  # Validate features
+  for variant in $JVM_VARIANTS; do
+    AC_MSG_CHECKING([JVM features for JVM variant '$variant'])
+    features_var_name=JVM_FEATURES_$variant
+    JVM_FEATURES_TO_TEST=${!features_var_name}
+    AC_MSG_RESULT([$JVM_FEATURES_TO_TEST])
+    INVALID_FEATURES=`$GREP -Fvx "${VALID_JVM_FEATURES// /$'\n'}" <<< "${JVM_FEATURES_TO_TEST// /$'\n'}"`
+    if test "x$INVALID_FEATURES" != x; then
+      AC_MSG_ERROR([Invalid JVM feature(s): $INVALID_FEATURES])
+    fi
+  done
+])
+
+###############################################################################
+# Support for old hotspot build. Remove once new hotspot build has proven
+# to work satisfactory.
+#
+AC_DEFUN_ONCE([HOTSPOT_SETUP_LEGACY_BUILD],
+[
+  AC_ARG_ENABLE(new-hotspot-build, [AS_HELP_STRING([--disable-new-hotspot-build],
+      [disable the new hotspot build system (use the old) @<:@enabled@:>@])])
+
+   if test "x$enable_new_hotspot_build" = "x" || test "x$enable_new_hotspot_build" = "xyes"; then
+     USE_NEW_HOTSPOT_BUILD=true
+   else
+     USE_NEW_HOTSPOT_BUILD=false
+   fi
+  AC_SUBST(USE_NEW_HOTSPOT_BUILD)
+
+  case $HOTSPOT_DEBUG_LEVEL in
+    product )
+      VARIANT="OPT"
+      FASTDEBUG="false"
+      DEBUG_CLASSFILES="false"
+      ;;
+    fastdebug )
+      VARIANT="DBG"
+      FASTDEBUG="true"
+      DEBUG_CLASSFILES="true"
+      ;;
+    debug )
+      VARIANT="DBG"
+      FASTDEBUG="false"
+      DEBUG_CLASSFILES="true"
+      ;;
+    optimized )
+      VARIANT="OPT"
+      FASTDEBUG="false"
+      DEBUG_CLASSFILES="false"
+      ;;
+  esac
+  AC_SUBST(VARIANT)
+  AC_SUBST(FASTDEBUG)
+  AC_SUBST(DEBUG_CLASSFILES)
 
   if test "x$OPENJDK_TARGET_OS" = "xmacosx"; then
     MACOSX_UNIVERSAL="true"
   fi
 
   AC_SUBST(MACOSX_UNIVERSAL)
-])
 
+  # Make sure JVM_VARIANTS_COMMA use minimal1 for backwards compatibility
+  JVM_VARIANTS_COMMA=`$ECHO ,$JVM_VARIANTS_OPT, | $SED -e 's/,minimal,/,minimal1,/'`
 
-###############################################################################
-# Setup legacy vars/targets and new vars to deal with different debug levels.
-#
-#    release: no debug information, all optimizations, no asserts.
-#    optimized: no debug information, all optimizations, no asserts, HotSpot target is 'optimized'.
-#    fastdebug: debug information (-g), all optimizations, all asserts
-#    slowdebug: debug information (-g), no optimizations, all asserts
-#
-AC_DEFUN_ONCE([HOTSPOT_SETUP_DEBUG_LEVEL],
-[
-  case $DEBUG_LEVEL in
-    release )
-      VARIANT="OPT"
-      FASTDEBUG="false"
-      DEBUG_CLASSFILES="false"
-      BUILD_VARIANT_RELEASE=""
-      HOTSPOT_DEBUG_LEVEL="product"
-      HOTSPOT_EXPORT="product"
-      ;;
-    fastdebug )
-      VARIANT="DBG"
-      FASTDEBUG="true"
-      DEBUG_CLASSFILES="true"
-      BUILD_VARIANT_RELEASE="-fastdebug"
-      HOTSPOT_DEBUG_LEVEL="fastdebug"
-      HOTSPOT_EXPORT="fastdebug"
-      ;;
-    slowdebug )
-      VARIANT="DBG"
-      FASTDEBUG="false"
-      DEBUG_CLASSFILES="true"
-      BUILD_VARIANT_RELEASE="-debug"
-      HOTSPOT_DEBUG_LEVEL="debug"
-      HOTSPOT_EXPORT="debug"
-      ;;
-    optimized )
-      VARIANT="OPT"
-      FASTDEBUG="false"
-      DEBUG_CLASSFILES="false"
-      BUILD_VARIANT_RELEASE="-optimized"
-      HOTSPOT_DEBUG_LEVEL="optimized"
-      HOTSPOT_EXPORT="optimized"
-      ;;
-  esac
-
-  # The debug level 'optimized' is a little special because it is currently only
-  # applicable to the HotSpot build where it means to build a completely
-  # optimized version of the VM without any debugging code (like for the
-  # 'release' debug level which is called 'product' in the HotSpot build) but
-  # with the exception that it can contain additional code which is otherwise
-  # protected by '#ifndef PRODUCT' macros. These 'optimized' builds are used to
-  # test new and/or experimental features which are not intended for customer
-  # shipment. Because these new features need to be tested and benchmarked in
-  # real world scenarios, we want to build the containing JDK at the 'release'
-  # debug level.
-  if test "x$DEBUG_LEVEL" = xoptimized; then
-    DEBUG_LEVEL="release"
-  fi
+  JVM_VARIANT_SERVER=`$ECHO "$JVM_VARIANTS_COMMA" | $SED -e '/,server,/!s/.*/false/g' -e '/,server,/s/.*/true/g'`
+  JVM_VARIANT_CLIENT=`$ECHO "$JVM_VARIANTS_COMMA" | $SED -e '/,client,/!s/.*/false/g' -e '/,client,/s/.*/true/g'`
+  JVM_VARIANT_MINIMAL1=`$ECHO "$JVM_VARIANTS_COMMA" | $SED -e '/,minimal1\?,/!s/.*/false/g' -e '/,minimal1\?,/s/.*/true/g'`
+  JVM_VARIANT_CORE=`$ECHO "$JVM_VARIANTS_COMMA" | $SED -e '/,core,/!s/.*/false/g' -e '/,core,/s/.*/true/g'`
+  JVM_VARIANT_ZERO=`$ECHO "$JVM_VARIANTS_COMMA" | $SED -e '/,zero,/!s/.*/false/g' -e '/,zero,/s/.*/true/g'`
+  JVM_VARIANT_ZEROSHARK=`$ECHO "$JVM_VARIANTS_COMMA" | $SED -e '/,zeroshark,/!s/.*/false/g' -e '/,zeroshark,/s/.*/true/g'`
+  JVM_VARIANT_CUSTOM=`$ECHO "$JVM_VARIANTS_COMMA" | $SED -e '/,custom,/!s/.*/false/g' -e '/,custom,/s/.*/true/g'`
 
   #####
   # Generate the legacy makefile targets for hotspot.
-  # The hotspot api for selecting the build artifacts, really, needs to be improved.
-  # JDK-7195896 will fix this on the hotspot side by using the JVM_VARIANT_* variables to
-  # determine what needs to be built. All we will need to set here is all_product, all_fastdebug etc
-  # But until then ...
   HOTSPOT_TARGET=""
 
   if test "x$JVM_VARIANT_SERVER" = xtrue; then
@@ -213,27 +387,19 @@
     HOTSPOT_TARGET="$HOTSPOT_TARGET${HOTSPOT_DEBUG_LEVEL}core "
   fi
 
-  HOTSPOT_TARGET="$HOTSPOT_TARGET docs export_$HOTSPOT_EXPORT"
+  HOTSPOT_TARGET="$HOTSPOT_TARGET docs export_$HOTSPOT_DEBUG_LEVEL"
 
   # On Macosx universal binaries are produced, but they only contain
   # 64 bit intel. This invalidates control of which jvms are built
   # from configure, but only server is valid anyway. Fix this
   # when hotspot makefiles are rewritten.
   if test "x$MACOSX_UNIVERSAL" = xtrue; then
-    HOTSPOT_TARGET=universal_${HOTSPOT_EXPORT}
+    HOTSPOT_TARGET=universal_${HOTSPOT_DEBUG_LEVEL}
   fi
 
-  #####
+  HOTSPOT_MAKE_ARGS="$HOTSPOT_TARGET"
+  AC_SUBST(HOTSPOT_MAKE_ARGS)
 
-  AC_SUBST(DEBUG_LEVEL)
-  AC_SUBST(VARIANT)
-  AC_SUBST(FASTDEBUG)
-  AC_SUBST(DEBUG_CLASSFILES)
-  AC_SUBST(BUILD_VARIANT_RELEASE)
-])
-
-AC_DEFUN_ONCE([HOTSPOT_SETUP_HOTSPOT_OPTIONS],
-[
   # Control wether Hotspot runs Queens test after build.
   AC_ARG_ENABLE([hotspot-test-in-build], [AS_HELP_STRING([--enable-hotspot-test-in-build],
       [run the Queens test after Hotspot build @<:@disabled@:>@])],,
@@ -244,10 +410,29 @@
     TEST_IN_BUILD=false
   fi
   AC_SUBST(TEST_IN_BUILD)
-])
 
-AC_DEFUN_ONCE([HOTSPOT_SETUP_BUILD_TWEAKS],
-[
-  HOTSPOT_MAKE_ARGS="$HOTSPOT_TARGET"
-  AC_SUBST(HOTSPOT_MAKE_ARGS)
+  if test "x$USE_NEW_HOTSPOT_BUILD" = xfalse; then
+    if test "x$JVM_VARIANT_CLIENT" = xtrue; then
+      if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then
+        AC_MSG_ERROR([You cannot build a client JVM for a 64-bit machine.])
+      fi
+    fi
+    if test "x$JVM_VARIANT_MINIMAL1" = xtrue; then
+      if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then
+        AC_MSG_ERROR([You cannot build a minimal JVM for a 64-bit machine.])
+      fi
+    fi
+    if test "x$JVM_VARIANT_CUSTOM" = xtrue; then
+        AC_MSG_ERROR([You cannot build a custom JVM using the old hotspot build system.])
+    fi
+  fi
+
+  AC_SUBST(JVM_VARIANTS_COMMA)
+  AC_SUBST(JVM_VARIANT_SERVER)
+  AC_SUBST(JVM_VARIANT_CLIENT)
+  AC_SUBST(JVM_VARIANT_MINIMAL1)
+  AC_SUBST(JVM_VARIANT_HOTSPOT)
+  AC_SUBST(JVM_VARIANT_ZERO)
+  AC_SUBST(JVM_VARIANT_ZEROSHARK)
+  AC_SUBST(JVM_VARIANT_CORE)
 ])
--- a/common/autoconf/jdk-options.m4	Thu Apr 21 12:57:17 2016 -0700
+++ b/common/autoconf/jdk-options.m4	Wed Jul 05 21:37:42 2017 +0200
@@ -81,6 +81,31 @@
       test "x$DEBUG_LEVEL" != xslowdebug; then
     AC_MSG_ERROR([Allowed debug levels are: release, fastdebug, slowdebug and optimized])
   fi
+
+  # Translate DEBUG_LEVEL to debug level used by Hotspot
+  HOTSPOT_DEBUG_LEVEL="$DEBUG_LEVEL"
+  if test "x$DEBUG_LEVEL" = xrelease; then
+    HOTSPOT_DEBUG_LEVEL="product"
+  elif test "x$DEBUG_LEVEL" = xslowdebug; then
+    HOTSPOT_DEBUG_LEVEL="debug"
+  fi
+
+  if test "x$DEBUG_LEVEL" = xoptimized; then
+    # The debug level 'optimized' is a little special because it is currently only
+    # applicable to the HotSpot build where it means to build a completely
+    # optimized version of the VM without any debugging code (like for the
+    # 'release' debug level which is called 'product' in the HotSpot build) but
+    # with the exception that it can contain additional code which is otherwise
+    # protected by '#ifndef PRODUCT' macros. These 'optimized' builds are used to
+    # test new and/or experimental features which are not intended for customer
+    # shipment. Because these new features need to be tested and benchmarked in
+    # real world scenarios, we want to build the containing JDK at the 'release'
+    # debug level.
+    DEBUG_LEVEL="release"
+  fi
+
+  AC_SUBST(HOTSPOT_DEBUG_LEVEL)
+  AC_SUBST(DEBUG_LEVEL)
 ])
 
 ###############################################################################
@@ -178,10 +203,7 @@
 
   # Should we build the serviceability agent (SA)?
   INCLUDE_SA=true
-  if test "x$JVM_VARIANT_ZERO" = xtrue ; then
-    INCLUDE_SA=false
-  fi
-  if test "x$JVM_VARIANT_ZEROSHARK" = xtrue ; then
+  if HOTSPOT_CHECK_JVM_VARIANT(zero) || HOTSPOT_CHECK_JVM_VARIANT(zeroshark); then
     INCLUDE_SA=false
   fi
   if test "x$OPENJDK_TARGET_OS" = xaix ; then
--- a/common/autoconf/jdk-version.m4	Thu Apr 21 12:57:17 2016 -0700
+++ b/common/autoconf/jdk-version.m4	Wed Jul 05 21:37:42 2017 +0200
@@ -72,6 +72,7 @@
   AC_SUBST(PRODUCT_SUFFIX)
   AC_SUBST(JDK_RC_PLATFORM_NAME)
   AC_SUBST(COMPANY_NAME)
+  AC_SUBST(HOTSPOT_VM_DISTRO)
   AC_SUBST(MACOSX_BUNDLE_NAME_BASE)
   AC_SUBST(MACOSX_BUNDLE_ID_BASE)
 
--- a/common/autoconf/lib-std.m4	Thu Apr 21 12:57:17 2016 -0700
+++ b/common/autoconf/lib-std.m4	Wed Jul 05 21:37:42 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
@@ -88,13 +88,25 @@
     # If dynamic was requested, it's available since it would fail above otherwise.
     # If dynamic wasn't requested, go with static unless it isn't available.
     AC_MSG_CHECKING([how to link with libstdc++])
-    if test "x$with_stdc__lib" = xdynamic || test "x$has_static_libstdcxx" = xno || test "x$JVM_VARIANT_ZEROSHARK" = xtrue; then
+    if test "x$with_stdc__lib" = xdynamic || test "x$has_static_libstdcxx" = xno || HOTSPOT_CHECK_JVM_VARIANT(zeroshark); then
       LIBCXX="$LIBCXX -lstdc++"
+      # To help comparisons with old build, put stdc++ first in JVM_LIBS
+      JVM_LIBS="-lstdc++ $JVM_LIBS"
+      # Ideally, we should test stdc++ for the BUILD toolchain separately. For now
+      # just use the same setting as for the TARGET toolchain.
+      OPENJDK_BUILD_JVM_LIBS="-lstdc++ $OPENJDK_BUILD_JVM_LIBS"
       LDCXX="$CXX"
       STATIC_CXX_SETTING="STATIC_CXX=false"
       AC_MSG_RESULT([dynamic])
     else
       LIBCXX="$LIBCXX $STATIC_STDCXX_FLAGS"
+      JVM_LDFLAGS="$JVM_LDFLAGS -static-libgcc"
+      # To help comparisons with old build, put stdc++ first in JVM_LIBS
+      JVM_LIBS="-Wl,-Bstatic -lstdc++ -Wl,-Bdynamic $JVM_LIBS"
+      # Ideally, we should test stdc++ for the BUILD toolchain separately. For now
+      # just use the same setting as for the TARGET toolchain.
+      OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS -static-libgcc"
+      OPENJDK_BUILD_JVM_LIBS="-Wl,-Bstatic -lstdc++ -Wl,-Bdynamic $OPENJDK_BUILD_JVM_LIBS"
       LDCXX="$CC"
       STATIC_CXX_SETTING="STATIC_CXX=true"
       AC_MSG_RESULT([static])
--- a/common/autoconf/libraries.m4	Thu Apr 21 12:57:17 2016 -0700
+++ b/common/autoconf/libraries.m4	Wed Jul 05 21:37:42 2017 +0200
@@ -74,7 +74,7 @@
   fi
 
   # Check if ffi is needed
-  if test "x$JVM_VARIANT_ZERO" = xtrue || test "x$JVM_VARIANT_ZEROSHARK" = xtrue; then
+  if HOTSPOT_CHECK_JVM_VARIANT(zero) || HOTSPOT_CHECK_JVM_VARIANT(zeroshark); then
     NEEDS_LIB_FFI=true
   else
     NEEDS_LIB_FFI=false
@@ -102,7 +102,7 @@
 ################################################################################
 AC_DEFUN_ONCE([LIB_SETUP_LLVM],
 [
-  if test "x$JVM_VARIANT_ZEROSHARK" = xtrue; then
+  if HOTSPOT_CHECK_JVM_VARIANT(zeroshark); then
     AC_CHECK_PROG([LLVM_CONFIG], [llvm-config], [llvm-config])
 
     if test "x$LLVM_CONFIG" != xllvm-config; then
--- a/common/autoconf/platform.m4	Thu Apr 21 12:57:17 2016 -0700
+++ b/common/autoconf/platform.m4	Wed Jul 05 21:37:42 2017 +0200
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2011, 2012, 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
@@ -274,168 +274,172 @@
 #
 AC_DEFUN([PLATFORM_SETUP_LEGACY_VARS],
 [
+  PLATFORM_SETUP_LEGACY_VARS_HELPER([TARGET])
+  PLATFORM_SETUP_LEGACY_VARS_HELPER([BUILD])
+
+  # ZERO_ARCHDEF is used to enable architecture-specific code.
+  # This is used in legacy hotspot build.
+  ZERO_ARCHDEF="$HOTSPOT_TARGET_CPU_DEFINE"
+  AC_SUBST(ZERO_ARCHDEF)
+
+])
+
+# $1 - Either TARGET or BUILD to setup the variables for.
+AC_DEFUN([PLATFORM_SETUP_LEGACY_VARS_HELPER],
+[
   # Also store the legacy naming of the cpu.
   # Ie i586 and amd64 instead of x86 and x86_64
-  OPENJDK_TARGET_CPU_LEGACY="$OPENJDK_TARGET_CPU"
-  if test "x$OPENJDK_TARGET_CPU" = xx86; then
-    OPENJDK_TARGET_CPU_LEGACY="i586"
-  elif test "x$OPENJDK_TARGET_OS" != xmacosx && test "x$OPENJDK_TARGET_CPU" = xx86_64; then
+  OPENJDK_$1_CPU_LEGACY="$OPENJDK_$1_CPU"
+  if test "x$OPENJDK_$1_CPU" = xx86; then
+    OPENJDK_$1_CPU_LEGACY="i586"
+  elif test "x$OPENJDK_$1_OS" != xmacosx && test "x$OPENJDK_$1_CPU" = xx86_64; then
     # On all platforms except MacOSX replace x86_64 with amd64.
-    OPENJDK_TARGET_CPU_LEGACY="amd64"
+    OPENJDK_$1_CPU_LEGACY="amd64"
   fi
-  AC_SUBST(OPENJDK_TARGET_CPU_LEGACY)
+  AC_SUBST(OPENJDK_$1_CPU_LEGACY)
 
   # And the second legacy naming of the cpu.
   # Ie i386 and amd64 instead of x86 and x86_64.
-  OPENJDK_TARGET_CPU_LEGACY_LIB="$OPENJDK_TARGET_CPU"
-  if test "x$OPENJDK_TARGET_CPU" = xx86; then
-    OPENJDK_TARGET_CPU_LEGACY_LIB="i386"
-  elif test "x$OPENJDK_TARGET_CPU" = xx86_64; then
-    OPENJDK_TARGET_CPU_LEGACY_LIB="amd64"
-  fi
-  AC_SUBST(OPENJDK_TARGET_CPU_LEGACY_LIB)
-
-  # This is the name of the cpu (but using i386 and amd64 instead of
-  # x86 and x86_64, respectively), preceeded by a /, to be used when
-  # locating libraries. On macosx, it's empty, though.
-  OPENJDK_TARGET_CPU_LIBDIR="/$OPENJDK_TARGET_CPU_LEGACY_LIB"
-  if test "x$OPENJDK_TARGET_OS" = xmacosx; then
-    OPENJDK_TARGET_CPU_LIBDIR=""
+  OPENJDK_$1_CPU_LEGACY_LIB="$OPENJDK_$1_CPU"
+  if test "x$OPENJDK_$1_CPU" = xx86; then
+    OPENJDK_$1_CPU_LEGACY_LIB="i386"
+  elif test "x$OPENJDK_$1_CPU" = xx86_64; then
+    OPENJDK_$1_CPU_LEGACY_LIB="amd64"
   fi
-  AC_SUBST(OPENJDK_TARGET_CPU_LIBDIR)
-
-  # Now do the same for OPENJDK_BUILD_CPU...
-  # Also store the legacy naming of the cpu.
-  # Ie i586 and amd64 instead of x86 and x86_64
-  OPENJDK_BUILD_CPU_LEGACY="$OPENJDK_BUILD_CPU"
-  if test "x$OPENJDK_BUILD_CPU" = xx86; then
-    OPENJDK_BUILD_CPU_LEGACY="i586"
-  elif test "x$OPENJDK_BUILD_OS" != xmacosx && test "x$OPENJDK_BUILD_CPU" = xx86_64; then
-    # On all platforms except MacOSX replace x86_64 with amd64.
-    OPENJDK_BUILD_CPU_LEGACY="amd64"
-  fi
-  AC_SUBST(OPENJDK_BUILD_CPU_LEGACY)
-
-  # And the second legacy naming of the cpu.
-  # Ie i386 and amd64 instead of x86 and x86_64.
-  OPENJDK_BUILD_CPU_LEGACY_LIB="$OPENJDK_BUILD_CPU"
-  if test "x$OPENJDK_BUILD_CPU" = xx86; then
-    OPENJDK_BUILD_CPU_LEGACY_LIB="i386"
-  elif test "x$OPENJDK_BUILD_CPU" = xx86_64; then
-    OPENJDK_BUILD_CPU_LEGACY_LIB="amd64"
-  fi
-  AC_SUBST(OPENJDK_BUILD_CPU_LEGACY_LIB)
+  AC_SUBST(OPENJDK_$1_CPU_LEGACY_LIB)
 
   # This is the name of the cpu (but using i386 and amd64 instead of
   # x86 and x86_64, respectively), preceeded by a /, to be used when
   # locating libraries. On macosx, it's empty, though.
-  OPENJDK_BUILD_CPU_LIBDIR="/$OPENJDK_BUILD_CPU_LEGACY_LIB"
-  if test "x$OPENJDK_BUILD_OS" = xmacosx; then
-    OPENJDK_BUILD_CPU_LIBDIR=""
+  OPENJDK_$1_CPU_LIBDIR="/$OPENJDK_$1_CPU_LEGACY_LIB"
+  if test "x$OPENJDK_$1_OS" = xmacosx; then
+    OPENJDK_$1_CPU_LIBDIR=""
   fi
-  AC_SUBST(OPENJDK_BUILD_CPU_LIBDIR)
+  AC_SUBST(OPENJDK_$1_CPU_LIBDIR)
 
-  # OPENJDK_TARGET_CPU_ISADIR is normally empty. On 64-bit Solaris systems, it is set to
+  # OPENJDK_$1_CPU_ISADIR is normally empty. On 64-bit Solaris systems, it is set to
   # /amd64 or /sparcv9. This string is appended to some library paths, like this:
-  # /usr/lib${OPENJDK_TARGET_CPU_ISADIR}/libexample.so
-  OPENJDK_TARGET_CPU_ISADIR=""
-  if test "x$OPENJDK_TARGET_OS" = xsolaris; then
-    if test "x$OPENJDK_TARGET_CPU" = xx86_64; then
-      OPENJDK_TARGET_CPU_ISADIR="/amd64"
-    elif test "x$OPENJDK_TARGET_CPU" = xsparcv9; then
-      OPENJDK_TARGET_CPU_ISADIR="/sparcv9"
+  # /usr/lib${OPENJDK_$1_CPU_ISADIR}/libexample.so
+  OPENJDK_$1_CPU_ISADIR=""
+  if test "x$OPENJDK_$1_OS" = xsolaris; then
+    if test "x$OPENJDK_$1_CPU" = xx86_64; then
+      OPENJDK_$1_CPU_ISADIR="/amd64"
+    elif test "x$OPENJDK_$1_CPU" = xsparcv9; then
+      OPENJDK_$1_CPU_ISADIR="/sparcv9"
     fi
   fi
-  AC_SUBST(OPENJDK_TARGET_CPU_ISADIR)
+  AC_SUBST(OPENJDK_$1_CPU_ISADIR)
 
-  # Setup OPENJDK_TARGET_CPU_OSARCH, which is used to set the os.arch Java system property
-  OPENJDK_TARGET_CPU_OSARCH="$OPENJDK_TARGET_CPU"
-  if test "x$OPENJDK_TARGET_OS" = xlinux && test "x$OPENJDK_TARGET_CPU" = xx86; then
+  # Setup OPENJDK_$1_CPU_OSARCH, which is used to set the os.arch Java system property
+  OPENJDK_$1_CPU_OSARCH="$OPENJDK_$1_CPU"
+  if test "x$OPENJDK_$1_OS" = xlinux && test "x$OPENJDK_$1_CPU" = xx86; then
     # On linux only, we replace x86 with i386.
-    OPENJDK_TARGET_CPU_OSARCH="i386"
-  elif test "x$OPENJDK_TARGET_OS" != xmacosx && test "x$OPENJDK_TARGET_CPU" = xx86_64; then
+    OPENJDK_$1_CPU_OSARCH="i386"
+  elif test "x$OPENJDK_$1_OS" != xmacosx && test "x$OPENJDK_$1_CPU" = xx86_64; then
     # On all platforms except macosx, we replace x86_64 with amd64.
-    OPENJDK_TARGET_CPU_OSARCH="amd64"
+    OPENJDK_$1_CPU_OSARCH="amd64"
   fi
-  AC_SUBST(OPENJDK_TARGET_CPU_OSARCH)
+  AC_SUBST(OPENJDK_$1_CPU_OSARCH)
 
-  OPENJDK_TARGET_CPU_JLI="$OPENJDK_TARGET_CPU"
-  if test "x$OPENJDK_TARGET_CPU" = xx86; then
-    OPENJDK_TARGET_CPU_JLI="i386"
-  elif test "x$OPENJDK_TARGET_OS" != xmacosx && test "x$OPENJDK_TARGET_CPU" = xx86_64; then
+  OPENJDK_$1_CPU_JLI="$OPENJDK_$1_CPU"
+  if test "x$OPENJDK_$1_CPU" = xx86; then
+    OPENJDK_$1_CPU_JLI="i386"
+  elif test "x$OPENJDK_$1_OS" != xmacosx && test "x$OPENJDK_$1_CPU" = xx86_64; then
     # On all platforms except macosx, we replace x86_64 with amd64.
-    OPENJDK_TARGET_CPU_JLI="amd64"
+    OPENJDK_$1_CPU_JLI="amd64"
   fi
   # Now setup the -D flags for building libjli.
-  OPENJDK_TARGET_CPU_JLI_CFLAGS="-DLIBARCHNAME='\"$OPENJDK_TARGET_CPU_JLI\"'"
-  if test "x$OPENJDK_TARGET_OS" = xsolaris; then
-    if test "x$OPENJDK_TARGET_CPU_ARCH" = xsparc; then
-      OPENJDK_TARGET_CPU_JLI_CFLAGS="$OPENJDK_TARGET_CPU_JLI_CFLAGS -DLIBARCH32NAME='\"sparc\"' -DLIBARCH64NAME='\"sparcv9\"'"
-    elif test "x$OPENJDK_TARGET_CPU_ARCH" = xx86; then
-      OPENJDK_TARGET_CPU_JLI_CFLAGS="$OPENJDK_TARGET_CPU_JLI_CFLAGS -DLIBARCH32NAME='\"i386\"' -DLIBARCH64NAME='\"amd64\"'"
+  OPENJDK_$1_CPU_JLI_CFLAGS="-DLIBARCHNAME='\"$OPENJDK_$1_CPU_JLI\"'"
+  if test "x$OPENJDK_$1_OS" = xsolaris; then
+    if test "x$OPENJDK_$1_CPU_ARCH" = xsparc; then
+      OPENJDK_$1_CPU_JLI_CFLAGS="$OPENJDK_$1_CPU_JLI_CFLAGS -DLIBARCH32NAME='\"sparc\"' -DLIBARCH64NAME='\"sparcv9\"'"
+    elif test "x$OPENJDK_$1_CPU_ARCH" = xx86; then
+      OPENJDK_$1_CPU_JLI_CFLAGS="$OPENJDK_$1_CPU_JLI_CFLAGS -DLIBARCH32NAME='\"i386\"' -DLIBARCH64NAME='\"amd64\"'"
     fi
   fi
-  AC_SUBST(OPENJDK_TARGET_CPU_JLI_CFLAGS)
+  AC_SUBST(OPENJDK_$1_CPU_JLI_CFLAGS)
 
-  OPENJDK_BUILD_CPU_JLI="$OPENJDK_BUILD_CPU"
-  if test "x$OPENJDK_BUILD_CPU" = xx86; then
-    OPENJDK_BUILD_CPU_JLI="i386"
-  elif test "x$OPENJDK_BUILD_OS" != xmacosx && test "x$OPENJDK_BUILD_CPU" = xx86_64; then
-    # On all platforms except macosx, we replace x86_64 with amd64.
-    OPENJDK_BUILD_CPU_JLI="amd64"
+  if test "x$OPENJDK_$1_OS" = xmacosx; then
+      OPENJDK_$1_OS_EXPORT_DIR=macosx
+  else
+      OPENJDK_$1_OS_EXPORT_DIR=${OPENJDK_$1_OS_TYPE}
   fi
-  # Now setup the -D flags for building libjli.
-  OPENJDK_BUILD_CPU_JLI_CFLAGS="-DLIBARCHNAME='\"$OPENJDK_BUILD_CPU_JLI\"'"
-  if test "x$OPENJDK_BUILD_OS" = xsolaris; then
-    if test "x$OPENJDK_BUILD_CPU_ARCH" = xsparc; then
-      OPENJDK_BUILD_CPU_JLI_CFLAGS="$OPENJDK_BUILD_CPU_JLI_CFLAGS -DLIBARCH32NAME='\"sparc\"' -DLIBARCH64NAME='\"sparcv9\"'"
-    elif test "x$OPENJDK_BUILD_CPU_ARCH" = xx86; then
-      OPENJDK_BUILD_CPU_JLI_CFLAGS="$OPENJDK_BUILD_CPU_JLI_CFLAGS -DLIBARCH32NAME='\"i386\"' -DLIBARCH64NAME='\"amd64\"'"
-    fi
-  fi
-  AC_SUBST(OPENJDK_BUILD_CPU_JLI_CFLAGS)
+  AC_SUBST(OPENJDK_$1_OS_EXPORT_DIR)
 
-  if test "x$OPENJDK_TARGET_OS" = xmacosx; then
-      OPENJDK_TARGET_OS_EXPORT_DIR=macosx
-  else
-      OPENJDK_TARGET_OS_EXPORT_DIR=${OPENJDK_TARGET_OS_TYPE}
-  fi
-  AC_SUBST(OPENJDK_TARGET_OS_EXPORT_DIR)
-
-  if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then
+  if test "x$OPENJDK_$1_CPU_BITS" = x64; then
     A_LP64="LP64:="
     # -D_LP64=1 is only set on linux and mac. Setting on windows causes diff in
     # unpack200.exe
-    if test "x$OPENJDK_TARGET_OS" = xlinux || test "x$OPENJDK_TARGET_OS" = xmacosx; then
-      ADD_LP64="-D_LP64=1"
+    if test "x$OPENJDK_$1_OS" = xlinux || test "x$OPENJDK_$1_OS" = xmacosx; then
+      OPENJDK_$1_ADD_LP64="-D_LP64=1"
     fi
   fi
   AC_SUBST(LP64,$A_LP64)
-  if test "x$OPENJDK_BUILD_CPU_BITS" = x64; then
-    if test "x$OPENJDK_BUILD_OS" = xlinux || test "x$OPENJDK_BUILD_OS" = xmacosx; then
-      OPENJDK_BUILD_ADD_LP64="-D_LP64=1"
-    fi
-  fi
 
   if test "x$COMPILE_TYPE" = "xcross"; then
     # FIXME: ... or should this include reduced builds..?
-    DEFINE_CROSS_COMPILE_ARCH="CROSS_COMPILE_ARCH:=$OPENJDK_TARGET_CPU_LEGACY"
+    DEFINE_CROSS_COMPILE_ARCH="CROSS_COMPILE_ARCH:=$OPENJDK_$1_CPU_LEGACY"
   else
     DEFINE_CROSS_COMPILE_ARCH=""
   fi
   AC_SUBST(DEFINE_CROSS_COMPILE_ARCH)
 
-  # ZERO_ARCHDEF is used to enable architecture-specific code
-  case "${OPENJDK_TARGET_CPU}" in
-    ppc)     ZERO_ARCHDEF=PPC32 ;;
-    ppc64)   ZERO_ARCHDEF=PPC64 ;;
-    s390*)   ZERO_ARCHDEF=S390  ;;
-    sparc*)  ZERO_ARCHDEF=SPARC ;;
-    x86_64*) ZERO_ARCHDEF=AMD64 ;;
-    x86)     ZERO_ARCHDEF=IA32  ;;
-    *)      ZERO_ARCHDEF=$(echo "${OPENJDK_TARGET_CPU_LEGACY_LIB}" | tr a-z A-Z)
-  esac
-  AC_SUBST(ZERO_ARCHDEF)
+  # Convert openjdk platform names to hotspot names
+
+  HOTSPOT_$1_OS=${OPENJDK_$1_OS}
+  if test "x$OPENJDK_$1_OS" = xmacosx; then
+    HOTSPOT_$1_OS=bsd
+  fi
+  AC_SUBST(HOTSPOT_$1_OS)
+
+  HOTSPOT_$1_OS_TYPE=${OPENJDK_$1_OS_TYPE}
+  if test "x$OPENJDK_$1_OS_TYPE" = xunix; then
+    HOTSPOT_$1_OS_TYPE=posix
+  fi
+  AC_SUBST(HOTSPOT_$1_OS_TYPE)
+
+  HOTSPOT_$1_CPU=${OPENJDK_$1_CPU}
+  if test "x$OPENJDK_$1_CPU" = xx86; then
+    HOTSPOT_$1_CPU=x86_32
+  elif test "x$OPENJDK_$1_CPU" = xsparcv9; then
+    HOTSPOT_$1_CPU=sparc
+  elif test "x$OPENJDK_$1_CPU" = xppc64; then
+    HOTSPOT_$1_CPU=ppc_64
+  elif test "x$OPENJDK_$1_CPU" = xppc64le; then
+    HOTSPOT_$1_CPU=ppc_64
+  fi
+  AC_SUBST(HOTSPOT_$1_CPU)
+
+  # This is identical with OPENJDK_*, but define anyway for consistency.
+  HOTSPOT_$1_CPU_ARCH=${OPENJDK_$1_CPU_ARCH}
+  AC_SUBST(HOTSPOT_$1_CPU_ARCH)
+
+  # Setup HOTSPOT_$1_CPU_DEFINE
+  if test "x$OPENJDK_$1_CPU" = xx86; then
+    HOTSPOT_$1_CPU_DEFINE=IA32
+  elif test "x$OPENJDK_$1_CPU" = xx86_64; then
+    HOTSPOT_$1_CPU_DEFINE=AMD64
+  elif test "x$OPENJDK_$1_CPU" = xsparcv9; then
+    HOTSPOT_$1_CPU_DEFINE=SPARC
+  elif test "x$OPENJDK_$1_CPU" = xaarch64; then
+    HOTSPOT_$1_CPU_DEFINE=AARCH64
+  elif test "x$OPENJDK_$1_CPU" = xppc64; then
+    HOTSPOT_$1_CPU_DEFINE=PPC64
+  elif test "x$OPENJDK_$1_CPU" = xppc64le; then
+    HOTSPOT_$1_CPU_DEFINE=PPC64
+
+  # The cpu defines below are for zero, we don't support them directly.
+  elif test "x$OPENJDK_$1_CPU" = xsparc; then
+    HOTSPOT_$1_CPU_DEFINE=SPARC
+  elif test "x$OPENJDK_$1_CPU" = xppc; then
+    HOTSPOT_$1_CPU_DEFINE=PPC32
+  elif test "x$OPENJDK_$1_CPU" = xs390; then
+    HOTSPOT_$1_CPU_DEFINE=S390
+  elif test "x$OPENJDK_$1_CPU" = ss390x; then
+    HOTSPOT_$1_CPU_DEFINE=S390
+  fi
+  AC_SUBST(HOTSPOT_$1_CPU_DEFINE)
+
 ])
 
 AC_DEFUN([PLATFORM_SET_RELEASE_FILE_OS_VALUES],
@@ -521,6 +525,10 @@
   CFLAGS_JDK="${CFLAGS_JDK}${ADDED_CFLAGS}"
   CXXFLAGS_JDK="${CXXFLAGS_JDK}${ADDED_CXXFLAGS}"
   LDFLAGS_JDK="${LDFLAGS_JDK}${ADDED_LDFLAGS}"
+
+  JVM_CFLAGS="$JVM_CFLAGS $ADDED_CFLAGS"
+  JVM_LDFLAGS="$JVM_LDFLAGS $ADDED_LDFLAGS"
+  JVM_ASFLAGS="$JVM_ASFLAGS $ADDED_CFLAGS"
 ])
 
 AC_DEFUN_ONCE([PLATFORM_SETUP_OPENJDK_TARGET_BITS],
@@ -542,6 +550,11 @@
       PLATFORM_SET_COMPILER_TARGET_BITS_FLAGS
     fi
   fi
+  if test "x$OPENJDK_TARGET_OS" = xmacosx; then
+    JVM_CFLAGS="$JVM_CFLAGS ${COMPILER_TARGET_BITS_FLAG}${OPENJDK_TARGET_CPU_BITS}"
+    JVM_LDFLAGS="$JVM_LDFLAGS ${COMPILER_TARGET_BITS_FLAG}${OPENJDK_TARGET_CPU_BITS}"
+    JVM_ASFLAGS="$JVM_ASFLAGS ${COMPILER_TARGET_BITS_FLAG}${OPENJDK_TARGET_CPU_BITS}"
+  fi
 
   # Make compilation sanity check
   AC_CHECK_HEADERS([stdio.h], , [
--- a/common/autoconf/spec.gmk.in	Thu Apr 21 12:57:17 2016 -0700
+++ b/common/autoconf/spec.gmk.in	Wed Jul 05 21:37:42 2017 +0200
@@ -82,6 +82,13 @@
 OPENJDK_TARGET_CPU_JLI_CFLAGS:=@OPENJDK_TARGET_CPU_JLI_CFLAGS@
 OPENJDK_TARGET_OS_EXPORT_DIR:=@OPENJDK_TARGET_OS_EXPORT_DIR@
 
+HOTSPOT_TARGET_OS := @HOTSPOT_TARGET_OS@
+HOTSPOT_TARGET_OS_TYPE := @HOTSPOT_TARGET_OS_TYPE@
+
+HOTSPOT_TARGET_CPU := @HOTSPOT_TARGET_CPU@
+HOTSPOT_TARGET_CPU_ARCH := @HOTSPOT_TARGET_CPU_ARCH@
+HOTSPOT_TARGET_CPU_DEFINE := @HOTSPOT_TARGET_CPU_DEFINE@
+
 # We are building on this build system.
 # When not cross-compiling, it is the same as the target.
 OPENJDK_BUILD_OS:=@OPENJDK_BUILD_OS@
@@ -192,6 +199,7 @@
 PRODUCT_SUFFIX:=@PRODUCT_SUFFIX@
 JDK_RC_PLATFORM_NAME:=@JDK_RC_PLATFORM_NAME@
 COMPANY_NAME:=@COMPANY_NAME@
+HOTSPOT_VM_DISTRO:=@HOTSPOT_VM_DISTRO@
 MACOSX_BUNDLE_NAME_BASE=@MACOSX_BUNDLE_NAME_BASE@
 MACOSX_BUNDLE_ID_BASE=@MACOSX_BUNDLE_ID_BASE@
 USERNAME:=@USERNAME@
@@ -201,11 +209,32 @@
 
 # How to compile the code: release, fastdebug or slowdebug
 DEBUG_LEVEL:=@DEBUG_LEVEL@
+HOTSPOT_DEBUG_LEVEL:=@HOTSPOT_DEBUG_LEVEL@
 
 # This is the JDK variant to build.
 # The JDK variant is a name for a specific set of modules to be compiled for the JDK.
 JDK_VARIANT:=@JDK_VARIANT@
 
+# Which JVM variants to build (space-separated list)
+JVM_VARIANTS := @JVM_VARIANTS@
+
+# Lists of features per variant. Only relevant for the variants listed in
+# JVM_VARIANTS.
+JVM_FEATURES_server := @JVM_FEATURES_server@
+JVM_FEATURES_client := @JVM_FEATURES_client@
+JVM_FEATURES_core := @JVM_FEATURES_core@
+JVM_FEATURES_minimal := @JVM_FEATURES_minimal@
+JVM_FEATURES_zero := @JVM_FEATURES_zero@
+JVM_FEATURES_zeroshark := @JVM_FEATURES_zeroshark@
+JVM_FEATURES_custom := @JVM_FEATURES_custom@
+
+# Used for make-time verifications
+VALID_JVM_FEATURES := @VALID_JVM_FEATURES@
+VALID_JVM_VARIANTS := @VALID_JVM_VARIANTS@
+
+# 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@
@@ -213,25 +242,11 @@
 # Legacy defines controlled by the SUPPORT_HEADLESS and SUPPORT_HEADFUL options.
 @BUILD_HEADLESS@
 
-# These are the libjvms that we want to build.
-# The java launcher uses the default.
-# The others can be selected by specifying -client -server -minimal1 -zero or -zeroshark
-# on the java launcher command line.
-JVM_VARIANTS:=@JVM_VARIANTS@
-JVM_VARIANT_SERVER:=@JVM_VARIANT_SERVER@
-JVM_VARIANT_CLIENT:=@JVM_VARIANT_CLIENT@
-JVM_VARIANT_MINIMAL1:=@JVM_VARIANT_MINIMAL1@
-JVM_VARIANT_ZERO:=@JVM_VARIANT_ZERO@
-JVM_VARIANT_ZEROSHARK:=@JVM_VARIANT_ZEROSHARK@
-JVM_VARIANT_CORE:=@JVM_VARIANT_CORE@
+# Legacy support
+USE_NEW_HOTSPOT_BUILD:=@USE_NEW_HOTSPOT_BUILD@
 
-# Universal binaries on macosx
 MACOSX_UNIVERSAL=@MACOSX_UNIVERSAL@
 
-# Legacy setting: -debug or -fastdebug
-# Still used in version string...
-BUILD_VARIANT_RELEASE:=@BUILD_VARIANT_RELEASE@
-
 # JDK_OUTPUTDIR specifies where a working jvm is built.
 # You can run $(JDK_OUTPUTDIR)/bin/java
 # Though the layout of the contents of $(JDK_OUTPUTDIR) is not
@@ -320,6 +335,11 @@
 # Toolchain type: gcc, clang, solstudio, lxc, microsoft...
 TOOLCHAIN_TYPE:=@TOOLCHAIN_TYPE@
 TOOLCHAIN_VERSION := @TOOLCHAIN_VERSION@
+CC_VERSION_NUMBER := @CC_VERSION_NUMBER@
+CXX_VERSION_NUMBER := @CXX_VERSION_NUMBER@
+
+# Legacy support
+HOTSPOT_TOOLCHAIN_TYPE := @HOTSPOT_TOOLCHAIN_TYPE@
 
 # Option used to tell the compiler whether to create 32- or 64-bit executables
 COMPILER_TARGET_BITS_FLAG:=@COMPILER_TARGET_BITS_FLAG@
@@ -338,14 +358,18 @@
 AR_OUT_OPTION:=@AR_OUT_OPTION@
 
 # Flags used for overriding the default opt setting for a C/C++ source file.
+C_O_FLAG_HIGHEST_JVM:=@C_O_FLAG_HIGHEST_JVM@
 C_O_FLAG_HIGHEST:=@C_O_FLAG_HIGHEST@
 C_O_FLAG_HI:=@C_O_FLAG_HI@
 C_O_FLAG_NORM:=@C_O_FLAG_NORM@
 C_O_FLAG_NONE:=@C_O_FLAG_NONE@
+C_O_FLAG_SIZE:=@C_O_FLAG_SIZE@
+CXX_O_FLAG_HIGHEST_JVM:=@CXX_O_FLAG_HIGHEST_JVM@
 CXX_O_FLAG_HIGHEST:=@CXX_O_FLAG_HIGHEST@
 CXX_O_FLAG_HI:=@CXX_O_FLAG_HI@
 CXX_O_FLAG_NORM:=@CXX_O_FLAG_NORM@
 CXX_O_FLAG_NONE:=@CXX_O_FLAG_NONE@
+CXX_O_FLAG_SIZE:=@CXX_O_FLAG_SIZE@
 
 C_FLAG_DEPS:=@C_FLAG_DEPS@
 CXX_FLAG_DEPS:=@CXX_FLAG_DEPS@
@@ -374,6 +398,23 @@
 
 LDFLAGS_HASH_STYLE := @LDFLAGS_HASH_STYLE@
 
+JVM_CFLAGS := @JVM_CFLAGS@
+JVM_CFLAGS_SYMBOLS := @JVM_CFLAGS_SYMBOLS@
+JVM_LDFLAGS := @JVM_LDFLAGS@
+JVM_ASFLAGS := @JVM_ASFLAGS@
+JVM_LIBS := @JVM_LIBS@
+JVM_RCFLAGS := @JVM_RCFLAGS@
+
+# Flags for zeroshark
+LLVM_CFLAGS := @LLVM_CFLAGS@
+LLVM_LIBS := @LLVM_LIBS@
+LLVM_LDFLAGS := @LLVM_LDFLAGS@
+
+# These flags might contain variables set by a custom extension that is included later.
+EXTRA_CFLAGS = @EXTRA_CFLAGS@
+EXTRA_CXXFLAGS = @EXTRA_CXXFLAGS@
+EXTRA_LDFLAGS = @EXTRA_LDFLAGS@
+
 CXX:=@FIXPATH@ @CCACHE@ @ICECC@ @CXX@
 
 CPP:=@FIXPATH@ @CPP@
@@ -630,6 +671,7 @@
 JT_HOME:=@JT_HOME@
 JTREGEXE:=@JTREGEXE@
 XCODEBUILD=@XCODEBUILD@
+DTRACE := @DTRACE@
 FIXPATH:=@FIXPATH@
 
 # Build setup
--- a/common/autoconf/toolchain.m4	Thu Apr 21 12:57:17 2016 -0700
+++ b/common/autoconf/toolchain.m4	Wed Jul 05 21:37:42 2017 +0200
@@ -930,6 +930,17 @@
     rm -rf version-script.map main.c a.out
   fi
   AC_SUBST(USING_BROKEN_SUSE_LD)
+
+  # Setup hotspot lecagy names for toolchains
+  HOTSPOT_TOOLCHAIN_TYPE=$TOOLCHAIN_TYPE
+  if test "x$TOOLCHAIN_TYPE" = xclang; then
+    HOTSPOT_TOOLCHAIN_TYPE=gcc
+  elif test "x$TOOLCHAIN_TYPE" = xsolstudio; then
+    HOTSPOT_TOOLCHAIN_TYPE=sparcWorks
+  elif test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
+    HOTSPOT_TOOLCHAIN_TYPE=visCPP
+  fi
+  AC_SUBST(HOTSPOT_TOOLCHAIN_TYPE)
 ])
 
 # Setup the JTReg Regression Test Harness.
--- a/common/autoconf/version-numbers	Thu Apr 21 12:57:17 2016 -0700
+++ b/common/autoconf/version-numbers	Wed Jul 05 21:37:42 2017 +0200
@@ -32,6 +32,7 @@
 PRODUCT_SUFFIX="Runtime Environment"
 JDK_RC_PLATFORM_NAME=Platform
 COMPANY_NAME=N/A
+HOTSPOT_VM_DISTRO="OpenJDK"
 
 # Might need better names for these
 MACOSX_BUNDLE_NAME_BASE="OpenJDK"
--- a/common/conf/jib-profiles.js	Thu Apr 21 12:57:17 2016 -0700
+++ b/common/conf/jib-profiles.js	Wed Jul 05 21:37:42 2017 +0200
@@ -241,7 +241,7 @@
             target_os: "linux",
             target_cpu: "x64",
             dependencies: concat(common.dependencies, "devkit"),
-            configure_args: concat(common.configure_args, "--with-zlib=system"),
+	    configure_args: concat(common.configure_args, "--with-zlib=system"),
             make_args: common.make_args
         },
 
@@ -259,7 +259,7 @@
             target_os: "macosx",
             target_cpu: "x64",
             dependencies: concat(common.dependencies, "devkit"),
-            configure_args: concat(common.configure_args, "--with-zlib=system"),
+	    configure_args: concat(common.configure_args, "--with-zlib=system"),
             make_args: common.make_args
         },
 
@@ -267,7 +267,7 @@
             target_os: "solaris",
             target_cpu: "x64",
             dependencies: concat(common.dependencies, "devkit", "cups"),
-            configure_args: concat(common.configure_args, "--with-zlib=system"),
+	    configure_args: concat(common.configure_args, "--with-zlib=system"),
             make_args: common.make_args
         },
 
@@ -275,7 +275,7 @@
             target_os: "solaris",
             target_cpu: "sparcv9",
             dependencies: concat(common.dependencies, "devkit", "cups"),
-            configure_args: concat(common.configure_args, "--with-zlib=system"),
+	    configure_args: concat(common.configure_args, "--with-zlib=system"),
             make_args: common.make_args
         },
 
--- a/corba/.hgtags	Thu Apr 21 12:57:17 2016 -0700
+++ b/corba/.hgtags	Wed Jul 05 21:37:42 2017 +0200
@@ -357,3 +357,4 @@
 780d0620add32bf545471cf65038c9ac6d9c036d jdk-9+112
 cc30faa2da498c478e89ab062ff160653ca1b170 jdk-9+113
 10d175b0368c30f54350fc648adc41b94ce357ee jdk-9+114
+7bab1b1b36824924b1c657a8419369ba93d198d3 jdk-9+115
--- a/corba/src/java.corba/share/classes/com/sun/corba/se/impl/corba/RequestImpl.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/corba/src/java.corba/share/classes/com/sun/corba/se/impl/corba/RequestImpl.java	Wed Jul 05 21:37:42 2017 +0200
@@ -255,7 +255,7 @@
     public synchronized void send_deferred()
     {
         AsynchInvoke invokeObject = new AsynchInvoke(_orb, this, false);
-        new sun.misc.ManagedLocalsThread(invokeObject).start();
+        new Thread(null, invokeObject, "Async-Request-Invoker-Thread", 0, false).start();
     }
 
     public synchronized boolean poll_response()
--- a/corba/src/java.corba/share/classes/com/sun/corba/se/impl/javax/rmi/CORBA/Util.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/corba/src/java.corba/share/classes/com/sun/corba/se/impl/javax/rmi/CORBA/Util.java	Wed Jul 05 21:37:42 2017 +0200
@@ -751,12 +751,13 @@
     }
 }
 
-class KeepAlive extends sun.misc.ManagedLocalsThread
+class KeepAlive extends Thread
 {
     boolean quit = false;
 
     public KeepAlive ()
     {
+        super(null, null, "Servant-KeepAlive-Thread", 0, false);
         setDaemon(false);
     }
 
--- a/corba/src/java.corba/share/classes/com/sun/corba/se/impl/oa/poa/POAImpl.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/corba/src/java.corba/share/classes/com/sun/corba/se/impl/oa/poa/POAImpl.java	Wed Jul 05 21:37:42 2017 +0200
@@ -516,7 +516,7 @@
 
     // Converted from anonymous class to local class
     // so that we can call performDestroy() directly.
-    static class DestroyThread extends sun.misc.ManagedLocalsThread {
+    static class DestroyThread extends Thread {
         private boolean wait ;
         private boolean etherealize ;
         private boolean debug ;
@@ -524,6 +524,7 @@
 
         public DestroyThread( boolean etherealize, boolean debug )
         {
+            super(null, null, "POA-Destroy-Thread", 0, false);
             this.etherealize = etherealize ;
             this.debug = debug ;
         }
--- a/corba/src/java.corba/share/classes/com/sun/corba/se/impl/oa/poa/POAManagerImpl.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/corba/src/java.corba/share/classes/com/sun/corba/se/impl/oa/poa/POAManagerImpl.java	Wed Jul 05 21:37:42 2017 +0200
@@ -357,7 +357,7 @@
             if (wait_for_completion)
                 deactivator.run() ;
             else {
-                Thread thr = new sun.misc.ManagedLocalsThread(deactivator) ;
+                Thread thr = new Thread(null, deactivator, "POA-Deactivator-Thread", 0, false) ;
                 thr.start() ;
             }
         } finally {
--- a/corba/src/java.corba/share/classes/com/sun/corba/se/impl/oa/poa/POAPolicyMediatorImpl_R_USM.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/corba/src/java.corba/share/classes/com/sun/corba/se/impl/oa/poa/POAPolicyMediatorImpl_R_USM.java	Wed Jul 05 21:37:42 2017 +0200
@@ -302,7 +302,7 @@
         throw new WrongPolicy();
     }
 
-    class Etherealizer extends sun.misc.ManagedLocalsThread {
+    class Etherealizer extends Thread {
         private POAPolicyMediatorImpl_R_USM mediator ;
         private ActiveObjectMap.Key key ;
         private AOMEntry entry ;
@@ -314,6 +314,7 @@
             ActiveObjectMap.Key key, AOMEntry entry, Servant servant,
             boolean debug )
         {
+            super(null, null, "PAO-Etherealizer-Thread", 0, false);
             this.mediator = mediator ;
             this.key = key ;
             this.entry = entry;
--- a/corba/src/java.corba/share/classes/com/sun/corba/se/impl/orb/ORBImpl.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/corba/src/java.corba/share/classes/com/sun/corba/se/impl/orb/ORBImpl.java	Wed Jul 05 21:37:42 2017 +0200
@@ -691,7 +691,7 @@
         for (int i = 0; i < req.length; i++) {
             AsynchInvoke invokeObject = new AsynchInvoke( this,
                 (com.sun.corba.se.impl.corba.RequestImpl)req[i], true);
-            new sun.misc.ManagedLocalsThread(invokeObject).start();
+            new Thread(null, invokeObject, "ORB-Request-Thread", 0, false).start();
         }
     }
 
--- a/corba/src/java.corba/share/classes/com/sun/corba/se/impl/orbutil/threadpool/ThreadPoolImpl.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/corba/src/java.corba/share/classes/com/sun/corba/se/impl/orbutil/threadpool/ThreadPoolImpl.java	Wed Jul 05 21:37:42 2017 +0200
@@ -459,7 +459,7 @@
     }
 
 
-    private class WorkerThread extends sun.misc.ManagedLocalsThread implements Closeable
+    private class WorkerThread extends Thread implements Closeable
     {
         private Work currentWork;
         private int threadId = 0; // unique id for the thread
@@ -469,7 +469,7 @@
         private StringBuffer workerThreadName = new StringBuffer();
 
         WorkerThread(ThreadGroup tg, String threadPoolName) {
-            super(tg, "Idle");
+            super(tg, null, "Idle", 0, false);
             this.threadId = ThreadPoolImpl.getUniqueThreadId();
             this.threadPoolName = threadPoolName;
             setName(composeWorkerThreadName(threadPoolName, "Idle"));
--- a/corba/src/java.corba/share/classes/com/sun/corba/se/impl/transport/SelectorImpl.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/corba/src/java.corba/share/classes/com/sun/corba/se/impl/transport/SelectorImpl.java	Wed Jul 05 21:37:42 2017 +0200
@@ -61,7 +61,7 @@
  */
 class SelectorImpl
     extends
-        sun.misc.ManagedLocalsThread
+        Thread
     implements
         com.sun.corba.se.pept.transport.Selector
 {
@@ -79,6 +79,7 @@
 
     public SelectorImpl(ORB orb)
     {
+        super(null, null, "ORB-Selector-Thread", 0, false);
         this.orb = orb;
         selector = null;
         selectorStarted = false;
@@ -277,7 +278,6 @@
 
     public void run()
     {
-        setName("SelectorThread");
         while (!closed) {
             try {
                 int n = 0;
--- a/corba/src/java.corba/share/classes/module-info.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/corba/src/java.corba/share/classes/module-info.java	Wed Jul 05 21:37:42 2017 +0200
@@ -29,8 +29,6 @@
     requires java.logging;
     requires java.naming;
     requires java.transaction;
-    // 8148863
-    requires jdk.unsupported;
 
     exports javax.activity;
     exports javax.rmi;
--- a/hotspot/.hgtags	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/.hgtags	Wed Jul 05 21:37:42 2017 +0200
@@ -517,3 +517,4 @@
 76582e8dc9e6374e4f99ab797c8d364b6e9449b4 jdk-9+112
 c569f8d89269fb6205b90f727581eb8cc04132f9 jdk-9+113
 b64432bae5271735fd53300b2005b713e98ef411 jdk-9+114
+88dd08d7be0fe7fb9f1914b1628f0aae9bf56e25 jdk-9+115
--- a/hotspot/make/Makefile	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/make/Makefile	Wed Jul 05 21:37:42 2017 +0200
@@ -237,19 +237,21 @@
 		      $(MAKE_ARGS) $(VM_TARGET)
 endif
 
+# NOTE: Changes in this file was just to facilitate comparison when 
+# developing the new build, and should not be integrated.
 generic_buildcore: $(HOTSPOT_SCRIPT)
-ifeq ($(HS_ARCH),ppc)
-  ifeq ($(ARCH_DATA_MODEL),64)
+#ifeq ($(HS_ARCH),ppc)
+#  ifeq ($(ARCH_DATA_MODEL),64)
 	$(MKDIR) -p $(OUTPUTDIR)
 	$(CD) $(OUTPUTDIR); \
 		$(MAKE) -f $(ABS_OS_MAKEFILE) \
 			$(MAKE_ARGS) $(VM_TARGET)
-  else
-	@$(ECHO) "No ($(VM_TARGET)) for ppc ARCH_DATA_MODEL=$(ARCH_DATA_MODEL)"
-  endif
-else
-	@$(ECHO) "No ($(VM_TARGET)) for $(HS_ARCH)"
-endif
+#  else
+#	@$(ECHO) "No ($(VM_TARGET)) for ppc ARCH_DATA_MODEL=$(ARCH_DATA_MODEL)"
+#  endif
+#else
+#	@$(ECHO) "No ($(VM_TARGET)) for $(HS_ARCH)"
+#endif
 
 generic_buildzero: $(HOTSPOT_SCRIPT)
 	$(MKDIR) -p $(OUTPUTDIR)
--- a/hotspot/make/aix/makefiles/trace.make	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/make/aix/makefiles/trace.make	Wed Jul 05 21:37:42 2017 +0200
@@ -53,13 +53,13 @@
 
 TraceGeneratedNames =     \
     traceEventClasses.hpp \
-    traceEventIds.hpp     \
-    traceTypes.hpp
+	traceEventIds.hpp     \
+	traceTypes.hpp
 
 ifeq ($(HAS_ALT_SRC), true)
-  TraceGeneratedNames +=  \
-      traceRequestables.hpp \
-      traceEventControl.hpp
+TraceGeneratedNames +=  \
+	traceRequestables.hpp \
+    traceEventControl.hpp
 endif
 
 TraceGeneratedFiles = $(TraceGeneratedNames:%=$(TraceOutDir)/%)
--- a/hotspot/make/bsd/makefiles/trace.make	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/make/bsd/makefiles/trace.make	Wed Jul 05 21:37:42 2017 +0200
@@ -53,13 +53,13 @@
 
 TraceGeneratedNames =     \
     traceEventClasses.hpp \
-    traceEventIds.hpp     \
-    traceTypes.hpp
+	traceEventIds.hpp     \
+	traceTypes.hpp
 
 ifeq ($(HAS_ALT_SRC), true)
-  TraceGeneratedNames +=  \
-      traceRequestables.hpp \
-      traceEventControl.hpp
+TraceGeneratedNames +=  \
+	traceRequestables.hpp \
+    traceEventControl.hpp
 endif
 
 TraceGeneratedFiles = $(TraceGeneratedNames:%=$(TraceOutDir)/%)
--- a/hotspot/make/linux/makefiles/gcc.make	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/make/linux/makefiles/gcc.make	Wed Jul 05 21:37:42 2017 +0200
@@ -221,7 +221,7 @@
   ifeq "$(shell expr \( $(CC_VER_MAJOR) \> 4 \) \| \( \( $(CC_VER_MAJOR) = 4 \) \& \( $(CC_VER_MINOR) \>= 3 \) \))" "0"
     # GCC < 4.3
     WARNING_FLAGS += -Wconversion
-  endif  
+  endif
   ifeq "$(shell expr \( $(CC_VER_MAJOR) \> 4 \) \| \( \( $(CC_VER_MAJOR) = 4 \) \& \( $(CC_VER_MINOR) \>= 8 \) \))" "1"
     # GCC >= 4.8
     # This flag is only known since GCC 4.3. Gcc 4.8 contains a fix so that with templates no
@@ -260,7 +260,7 @@
 
 OPT_CFLAGS = $(OPT_CFLAGS/$(OPT_CFLAGS_DEFAULT)) $(OPT_EXTRAS)
 
-# Variable tracking size limit exceeded for VMStructs::init() 
+# Variable tracking size limit exceeded for VMStructs::init()
 ifeq "$(shell expr \( $(CC_VER_MAJOR) \> 4 \) \| \( \( $(CC_VER_MAJOR) = 4 \) \& \( $(CC_VER_MINOR) \>= 3 \) \))" "1"
   # GCC >= 4.3
   # Gcc 4.1.2 does not support this flag, nor does it have problems compiling the file.
--- a/hotspot/make/linux/makefiles/trace.make	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/make/linux/makefiles/trace.make	Wed Jul 05 21:37:42 2017 +0200
@@ -53,13 +53,13 @@
 
 TraceGeneratedNames =     \
     traceEventClasses.hpp \
-    traceEventIds.hpp     \
-    traceTypes.hpp
+	traceEventIds.hpp     \
+	traceTypes.hpp
 
 ifeq ($(HAS_ALT_SRC), true)
-  TraceGeneratedNames +=  \
-      traceRequestables.hpp \
-      traceEventControl.hpp
+TraceGeneratedNames +=  \
+	traceRequestables.hpp \
+    traceEventControl.hpp
 endif
 
 TraceGeneratedFiles = $(TraceGeneratedNames:%=$(TraceOutDir)/%)
--- a/hotspot/make/linux/makefiles/zero.make	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/make/linux/makefiles/zero.make	Wed Jul 05 21:37:42 2017 +0200
@@ -30,3 +30,8 @@
 
 # Install libjvm.so, etc in in server directory.
 VM_SUBDIR = server
+
+# Disable trace for zero builds
+# NOTE: This is used for simple comparison with the new build system, and
+# should not be merged into mainline with build-infra.
+INCLUDE_TRACE := false
--- a/hotspot/make/share/makefiles/mapfile-vers	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/make/share/makefiles/mapfile-vers	Wed Jul 05 21:37:42 2017 +0200
@@ -41,7 +41,6 @@
                 JVM_DumpAllStacks;
                 JVM_DumpThreads;
                 JVM_FillInStackTrace;
-                JVM_FillStackFrames;
                 JVM_FindClassFromCaller;
                 JVM_FindClassFromClass;
                 JVM_FindClassFromBootLoader;
@@ -157,13 +156,13 @@
                 JVM_SetClassSigners;
                 JVM_SetNativeThreadName;
                 JVM_SetPrimitiveArrayElement;
-                JVM_SetMethodInfo;
                 JVM_SetThreadPriority;
                 JVM_Sleep;
                 JVM_StartThread;
                 JVM_StopThread;
                 JVM_SuspendThread;
                 JVM_SupportsCX8;
+                JVM_ToStackTraceElement;
                 JVM_TotalMemory;
                 JVM_UnloadLibrary;
                 JVM_Yield;
--- a/hotspot/make/solaris/makefiles/dtrace.make	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/make/solaris/makefiles/dtrace.make	Wed Jul 05 21:37:42 2017 +0200
@@ -270,7 +270,7 @@
 	@echo $(LOG_INFO) Compiling $(DTRACE).d
 
 	$(QUIETLY) $(DTRACE_PROG) $(DTRACE_OPTS) -C -I. -G -xlazyload -o $@ -s $(DTRACE).d \
-     $(DTraced_Files) ||\
+     $(sort $(DTraced_Files)) ||\
   STATUS=$$?;\
   if [ x"$$STATUS" = x"1" ]; then \
       if [ x`uname -r` = x"5.10" -a \
--- a/hotspot/make/solaris/makefiles/trace.make	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/make/solaris/makefiles/trace.make	Wed Jul 05 21:37:42 2017 +0200
@@ -53,13 +53,13 @@
 
 TraceGeneratedNames =     \
     traceEventClasses.hpp \
-    traceEventIds.hpp     \
-    traceTypes.hpp
+	traceEventIds.hpp     \
+	traceTypes.hpp
 
 ifeq ($(HAS_ALT_SRC), true)
-  TraceGeneratedNames +=  \
-      traceRequestables.hpp \
-      traceEventControl.hpp
+TraceGeneratedNames +=  \
+	traceRequestables.hpp \
+    traceEventControl.hpp
 endif
 
 TraceGeneratedFiles = $(TraceGeneratedNames:%=$(TraceOutDir)/%)
--- a/hotspot/make/test/JtregNative.gmk	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/make/test/JtregNative.gmk	Wed Jul 05 21:37:42 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
@@ -47,6 +47,7 @@
     $(HOTSPOT_TOPDIR)/test/runtime/jni/ToStringInInterfaceTest \
     $(HOTSPOT_TOPDIR)/test/runtime/modules/getModuleJNI \
     $(HOTSPOT_TOPDIR)/test/runtime/SameObject \
+    $(HOTSPOT_TOPDIR)/test/runtime/BoolReturn \
     $(HOTSPOT_TOPDIR)/test/compiler/floatingpoint/ \
     $(HOTSPOT_TOPDIR)/test/compiler/calls \
     $(HOTSPOT_TOPDIR)/test/compiler/native \
--- a/hotspot/make/windows/makefiles/debug.make	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/make/windows/makefiles/debug.make	Wed Jul 05 21:37:42 2017 +0200
@@ -48,10 +48,10 @@
 # Force resources to be rebuilt every time
 $(Res_Files): FORCE
 
+# NOTE: Changes in this file was just to give a proper command line when linking
+# for use when developing the new build, and should not be integrated.
 $(AOUT): $(Res_Files) $(Obj_Files) vm.def
-	$(LD) @<<
-  $(LD_FLAGS) /out:$@ /implib:$*.lib /def:vm.def $(Obj_Files) $(Res_Files)
-<<
+	$(LD) $(LD_FLAGS) /out:$@ /implib:$*.lib /def:vm.def $(Obj_Files) $(Res_Files)
 !if "$(MT)" != ""
 # The previous link command created a .manifest file that we want to
 # insert into the linked artifact so we do not need to track it
--- a/hotspot/make/windows/makefiles/fastdebug.make	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/make/windows/makefiles/fastdebug.make	Wed Jul 05 21:37:42 2017 +0200
@@ -47,10 +47,10 @@
 # Force resources to be rebuilt every time
 $(Res_Files): FORCE
 
+# NOTE: Changes in this file was just to give a proper command line when linking
+# for use when developing the new build, and should not be integrated.
 $(AOUT): $(Res_Files) $(Obj_Files) vm.def
-	$(LD) @<<
-  $(LD_FLAGS) /out:$@ /implib:$*.lib /def:vm.def $(Obj_Files) $(Res_Files)
-<<
+	$(LD) $(LD_FLAGS) /out:$@ /implib:$*.lib /def:vm.def $(Obj_Files) $(Res_Files)
 !if "$(MT)" != ""
 # The previous link command created a .manifest file that we want to
 # insert into the linked artifact so we do not need to track it
--- a/hotspot/make/windows/makefiles/product.make	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/make/windows/makefiles/product.make	Wed Jul 05 21:37:42 2017 +0200
@@ -51,10 +51,11 @@
 # Force resources to be rebuilt every time
 $(Res_Files): FORCE
 
+# NOTE: Changes in this file was just to give a proper command line when linking
+# for use when developing the new build, and should not be integrated.
 $(AOUT): $(Res_Files) $(Obj_Files) vm.def
-	$(LD) @<<
-  $(LD_FLAGS) /out:$@ /implib:$*.lib /def:vm.def $(Obj_Files) $(Res_Files)
-<<
+	$(LD) $(LD_FLAGS) /out:$@ /implib:$*.lib /def:vm.def $(Obj_Files) $(Res_Files)
+
 !if "$(MT)" != ""
 # The previous link command created a .manifest file that we want to
 # insert into the linked artifact so we do not need to track it
--- a/hotspot/make/windows/makefiles/trace.make	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/make/windows/makefiles/trace.make	Wed Jul 05 21:37:42 2017 +0200
@@ -41,6 +41,12 @@
 !endif
 !endif
 
+!ifndef OPENJDK
+!if EXISTS($(TraceAltSrcDir))
+HAS_ALT_SRC = true
+!endif
+!endif
+
 TraceGeneratedNames =     \
     traceEventClasses.hpp \
     traceEventIds.hpp     \
--- a/hotspot/make/windows/makefiles/vm.make	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/make/windows/makefiles/vm.make	Wed Jul 05 21:37:42 2017 +0200
@@ -305,8 +305,10 @@
 
 # This guy should remain a single colon rule because
 # otherwise we can't specify the output filename.
+# NOTE: Changes in this file was just to give a proper command line when linking
+# for use when developing the new build, and should not be integrated.
 {$(COMMONSRC)\os\windows\vm}.rc.res:
-        @$(RC) $(RC_FLAGS) /fo"$@" $<
+        $(RC) $(RC_FLAGS) /fo"$@" $<
 
 {$(COMMONSRC)\cpu\$(Platform_arch)\vm}.cpp.obj::
         $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $<
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/makefiles/BuildHotspot.gmk	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,54 @@
+#
+# 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
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.  Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+# This must be the first rule
+default: all
+
+include $(SPEC)
+include MakeBase.gmk
+
+VARIANT_TARGETS := $(foreach v, $(JVM_VARIANTS), variant-$v)
+VARIANT_GENSRC_TARGETS := $(addsuffix -gensrc, $(VARIANT_TARGETS))
+VARIANT_LIBS_TARGETS := $(addsuffix -libs, $(VARIANT_TARGETS))
+
+$(VARIANT_GENSRC_TARGETS): variant-%-gensrc:
+	$(call LogWarn, Building JVM variant '$*' with features '$(JVM_FEATURES_$*)')
+	+$(MAKE) -f gensrc/GenerateSources.gmk JVM_VARIANT=$*
+
+$(VARIANT_LIBS_TARGETS): variant-%-libs: variant-%-gensrc
+	+$(MAKE) -f lib/CompileLibraries.gmk JVM_VARIANT=$*
+
+$(VARIANT_TARGETS): variant-%: variant-%-gensrc variant-%-libs
+
+jsig:
+	+$(MAKE) -f lib/CompileLibjsig.gmk
+
+dist: $(VARIANT_TARGETS) jsig
+	+$(MAKE) -f Dist.gmk
+
+all: dist
+
+.PHONY: $(VARIANT_TARGETS) $(VARIANT_GENSRC_TARGETS) $(VARIANT_LIBS_TARGETS) \
+    jsig dist all
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/makefiles/Dist.gmk	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,239 @@
+#
+# 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
+# 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.
+#
+
+################################################################################
+# Copy the generated output into well-defined places in the dist directory.
+
+# This must be the first rule
+default: all
+
+include $(SPEC)
+include MakeBase.gmk
+
+$(eval $(call IncludeCustomExtension, hotspot, Dist.gmk))
+
+DIST_OUTPUTDIR := $(HOTSPOT_OUTPUTDIR)/dist
+
+# Unfortunately, all platforms have different target subdirs.
+ifeq ($(OPENJDK_TARGET_OS), windows)
+  LIB_SUBDIR := bin
+else ifeq ($(OPENJDK_TARGET_OS), macosx)
+  LIB_SUBDIR := lib
+else
+  LIB_SUBDIR := lib$(OPENJDK_TARGET_CPU_LIBDIR)
+endif
+
+################################################################################
+# Functions to setup copying of files for variants
+
+# Support macro for SetupDistLibFile
+define macosx_universalize
+	$(MKDIR) -p $(@D)
+	$(LIPO) -create -output $@ $<
+endef
+
+################################################################################
+# Setup make rules to copy a native library and associated data.
+#
+# Parameter 1 is the name of the rule. This name is used as variable prefix,
+# and the targets generated are listed in a variable by that name.
+#
+# Remaining parameters are named arguments. These include:
+#   NAME -- The base name of the native library (e.g. 'jvm')
+#   VARIANT -- The variant to copy from
+#   VARIANT_TARGET_DIR -- The variant target sub dir, with trailing slash, optional
+SetupDistLibFile = $(NamedParamsMacroTemplate)
+define SetupDistLibFileBody
+  ifneq ($$($1_VARIANT), )
+    $1_SRC_DIR := $$(HOTSPOT_OUTPUTDIR)/variant-$$($1_VARIANT)/lib$$($1_NAME)
+  else
+    $1_SRC_DIR := $$(HOTSPOT_OUTPUTDIR)/lib$$($1_NAME)
+  endif
+  $1_LIB_NAME := $(LIBRARY_PREFIX)$$($1_NAME)
+  $1_TARGET_DIR := $$(DIST_OUTPUTDIR)/$$(LIB_SUBDIR)/$$($1_VARIANT_TARGET_DIR)
+
+  ifeq ($(OPENJDK_TARGET_OS), macosx)
+    # We must use the 'universalize' macro to run lipo on shared libraries, at
+    # least until JDK-8069540 is fixed.
+    $1_MACRO := macosx_universalize
+  endif
+
+  # Copy the the native library.
+  $$(eval $$(call SetupCopyFiles, $1_COPY_LIB, \
+      DEST := $$($1_TARGET_DIR), \
+      MACRO := $$($1_MACRO), \
+      FILES := $$(wildcard \
+          $$($1_SRC_DIR)/$$($1_LIB_NAME)$(SHARED_LIBRARY_SUFFIX)), \
+  ))
+
+  TARGETS += $$($1_COPY_LIB)
+
+  # Copy related data (debug symbols, static-build symbols file etc)
+  $$(eval $$(call SetupCopyFiles, $1_COPY_FILES, \
+      DEST := $$($1_TARGET_DIR), \
+      FILES := $$(wildcard \
+          $$(addprefix $$($1_SRC_DIR)/$$($1_LIB_NAME), \
+          .diz .debuginfo .pdb .map .symbols)), \
+  ))
+
+  TARGETS += $$($1_COPY_FILES)
+
+  ifeq ($(OPENJDK_TARGET_OS), macosx)
+    # Debug symbols on macosx is a directory, not a single file, per library.
+    $1_DSYM_SRC := $$($1_SRC_DIR)/$$($1_LIB_NAME)$(SHARED_LIBRARY_SUFFIX).dSYM)
+    ifneq ($$(wildcard $$($1_DSYM_SRC)), )
+      $$(eval $$(call SetupCopyFiles, $1_COPY_DSYM_DIR, \
+          DEST := $$($1_TARGET_DIR), \
+          SRC := $$($1_SRC_DIR), \
+          FILES := $$(shell $(FIND) $$($1_DSYM_SRC) -type f), \
+       ))
+       TARGETS += $$($1_COPY_DSYM_DIR)
+    endif
+  endif
+endef
+
+################################################################################
+# Copy common files, which are independent on the jvm variant(s) being built.
+# For files that were generated during the build, we assume all versions of
+# these files are identical, and just pick one arbitrarily to use as source.
+
+ANY_JVM_VARIANT := $(firstword $(JVM_VARIANTS))
+JVM_VARIANT_OUTPUTDIR := $(HOTSPOT_OUTPUTDIR)/variant-$(ANY_JVM_VARIANT)
+
+### Copy platform-independent .h files
+INCLUDE_FILES_SRC_DIR := $(HOTSPOT_TOPDIR)/src/share/vm
+$(eval $(call SetupCopyFiles, COPY_INCLUDE, \
+    SRC := $(INCLUDE_FILES_SRC_DIR), \
+    DEST := $(DIST_OUTPUTDIR)/include, \
+    FLATTEN := true, \
+    FILES := $(INCLUDE_FILES_SRC_DIR)/prims/jni.h \
+        $(INCLUDE_FILES_SRC_DIR)/code/jvmticmlr.h \
+        $(INCLUDE_FILES_SRC_DIR)/services/jmm.h))
+
+TARGETS += $(COPY_INCLUDE)
+
+### Copy jni_md.h
+
+# This might have been defined in a custom extension
+ifeq ($(JNI_MD_H_SRC), )
+  JNI_MD_H_SRC := $(HOTSPOT_TOPDIR)/src/cpu/$(HOTSPOT_TARGET_CPU_ARCH)/vm/jni_$(HOTSPOT_TARGET_CPU_ARCH).h
+endif
+
+ifeq ($(OPENJDK_TARGET_OS), macosx)
+  # NOTE: This should most likely be darwin, but the old hotspot build uses bsd
+  JNI_MD_SUBDIR := bsd
+else ifeq ($(OPENJDK_TARGET_OS), windows)
+  JNI_MD_SUBDIR := win32
+else
+  JNI_MD_SUBDIR := $(OPENJDK_TARGET_OS)
+endif
+
+# SetupCopyFiles is not used here since it's non-trivial to copy a single
+# file with a different target name.
+$(DIST_OUTPUTDIR)/include/$(JNI_MD_SUBDIR)/jni_md.h: $(JNI_MD_H_SRC)
+	$(call LogInfo, Copying hotspot/dist/include/$(JNI_MD_SUBDIR)/jni_md.h)
+	$(install-file)
+
+TARGETS += $(DIST_OUTPUTDIR)/include/$(JNI_MD_SUBDIR)/jni_md.h
+
+$(eval $(call SetupCopyFiles, COPY_JVMTI_H, \
+    DEST := $(DIST_OUTPUTDIR)/include, \
+    FLATTEN := true, \
+    FILES := $(JVM_VARIANT_OUTPUTDIR)/gensrc/jvmtifiles/jvmti.h))
+
+TARGETS += $(COPY_JVMTI_H)
+
+# NOTE: In the old build, this file was not copied on Windows.
+ifneq ($(OPENJDK_TARGET_OS), windows)
+  $(eval $(call SetupCopyFiles, COPY_JVMTI_HTML, \
+      DEST := $(DIST_OUTPUTDIR)/docs/platform/jvmti, \
+      FILES := $(JVM_VARIANT_OUTPUTDIR)/gensrc/jvmtifiles/jvmti.html))
+endif
+
+TARGETS += $(COPY_JVMTI_HTML)
+
+ifeq ($(OPENJDK_TARGET_OS), windows)
+  $(eval $(call SetupCopyFiles, COPY_JVM_LIB, \
+      DEST := $(DIST_OUTPUTDIR)/lib, \
+      FILES :=$(JVM_VARIANT_OUTPUTDIR)/libjvm/objs/jvm.lib))
+
+  TARGETS += $(COPY_JVM_LIB)
+endif
+
+# Copy libjsig, if it exists
+$(eval $(call SetupDistLibFile, DIST_jsig, \
+    NAME := jsig, \
+))
+
+################################################################################
+# Copy variant-specific files
+
+# Setup make rules to copy a single variant to dist.
+# $1: The name of the variant
+define SetupDistForVariant
+  ifneq ($$(filter client minimal, $1), )
+    VARIANT_TARGET_DIR := $1
+  else
+    # Use 'server' as default target directory name for all other variants.
+    VARIANT_TARGET_DIR := server
+  endif
+
+  $$(eval $$(call SetupDistLibFile, DIST_$(strip $1)_jvm, \
+      NAME := jvm, \
+      VARIANT := $1, \
+      VARIANT_TARGET_DIR := $$(VARIANT_TARGET_DIR)/, \
+  ))
+
+  # Copy the dtrace libraries, if they exist
+  $$(eval $$(call SetupDistLibFile, DIST_$(strip $1)_jvm_db, \
+      NAME := jvm_db, \
+      VARIANT := $1, \
+      VARIANT_TARGET_DIR := $$(VARIANT_TARGET_DIR)/, \
+  ))
+
+  $$(eval $$(call SetupDistLibFile, DIST_$(strip $1)_jvm_dtrace, \
+      NAME := jvm_dtrace, \
+      VARIANT := $1, \
+      VARIANT_TARGET_DIR := $$(VARIANT_TARGET_DIR)/, \
+  ))
+
+  # Copy the Xusage.txt file
+  $$(eval $$(call SetupCopyFiles, DIST_$(strip $1)_Xusage, \
+      DEST := $$(DIST_OUTPUTDIR)/$$(LIB_SUBDIR)/$(strip $1), \
+      FILES := $$(HOTSPOT_OUTPUTDIR)/variant-$(strip $1)/support/misc/Xusage.txt, \
+  ))
+
+  TARGETS += $$(DIST_$(strip $1)_Xusage)
+endef
+
+$(foreach variant, $(JVM_VARIANTS), \
+  $(eval $(call SetupDistForVariant, $(variant))) \
+)
+
+################################################################################
+
+all: $(TARGETS)
+
+.PHONY: all
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/makefiles/HotspotCommon.gmk	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,45 @@
+#
+# 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.
+#
+
+ifeq ($(JVM_VARIANT), )
+  $(error This makefile must be called with JVM_VARIANT set)
+endif
+
+JVM_VARIANT_OUTPUTDIR := $(HOTSPOT_OUTPUTDIR)/variant-$(JVM_VARIANT)
+JVM_OUTPUTDIR := $(JVM_VARIANT_OUTPUTDIR)/libjvm
+JVM_SUPPORT_DIR := $(JVM_VARIANT_OUTPUTDIR)/support
+
+DTRACE_SUPPORT_DIR := $(JVM_SUPPORT_DIR)/dtrace
+
+################################################################################
+
+# Test if a feature is available in the present build of JVM_VARIANT. Will return
+# 'true' or 'false'.
+# $1 - the feature to test for
+check-jvm-feature = \
+  $(strip \
+    $(if $(filter-out $(VALID_JVM_FEATURES), $1), \
+      $(error Internal error: Invalid feature tested: $1)) \
+    $(if $(filter $1, $(JVM_FEATURES_$(JVM_VARIANT))), true, false))
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/makefiles/gensrc/GenerateSources.gmk	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,75 @@
+#
+# 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
+# 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.
+#
+
+default: all
+
+include $(SPEC)
+include MakeBase.gmk
+include JavaCompilation.gmk
+include NativeCompilation.gmk
+include TextFileProcessing.gmk
+
+include HotspotCommon.gmk
+
+# The real work is done in these files
+
+include gensrc/GensrcAdlc.gmk
+include gensrc/GensrcDtrace.gmk
+include gensrc/GensrcJvmti.gmk
+
+$(eval $(call IncludeCustomExtension, hotspot, gensrc/GenerateSources.gmk))
+
+# While technically the rules below are "gendata" which can be done in parallel
+# with native compilation, let's keep it here for simplicity.
+
+# The Xusage.txt file needs to have platform specific path separator
+$(eval $(call SetupTextFileProcessing, CREATE_XUSAGE, \
+    SOURCE_FILES := $(HOTSPOT_TOPDIR)/src/share/vm/Xusage.txt, \
+    OUTPUT_FILE := $(JVM_SUPPORT_DIR)/misc/Xusage.txt, \
+    REPLACEMENTS := separated by ;> => separated by $(PATH_SEP)> ; , \
+))
+
+TARGETS += $(CREATE_XUSAGE)
+
+# Setup the hotspot launcher script for developer use
+$(eval $(call SetupTextFileProcessing, CREATE_HOTSPOT_LAUNCHER, \
+    SOURCE_FILES := $(HOTSPOT_TOPDIR)/make/hotspot.script, \
+    OUTPUT_FILE := $(JVM_OUTPUTDIR)/hotspot, \
+    REPLACEMENTS := \
+        @@LIBARCH@@ => $(OPENJDK_TARGET_CPU_LEGACY_LIB) ; \
+        @@JDK_IMPORT_PATH@@ => $(JDK_OUTPUTDIR) ; , \
+))
+
+CHMOD_HOTSPOT_LAUNCHER := $(JVM_VARIANT_OUTPUTDIR)/libjvm/_hotspot-script-chmod.marker
+
+$(CHMOD_HOTSPOT_LAUNCHER): $(CREATE_HOTSPOT_LAUNCHER)
+	$(CHMOD) +x $<
+	$(TOUCH) $@
+
+TARGETS += $(CREATE_HOTSPOT_LAUNCHER) $(CHMOD_HOTSPOT_LAUNCHER)
+
+all: $(TARGETS)
+
+.PHONY: all
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/makefiles/gensrc/GensrcAdlc.gmk	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,191 @@
+#
+# 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
+# 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.
+#
+
+$(eval $(call IncludeCustomExtension, hotspot, gensrc/GensrcAdlc.gmk))
+
+ifeq ($(call check-jvm-feature, compiler2), true)
+
+  ADLC_SUPPORT_DIR := $(JVM_SUPPORT_DIR)/adlc
+
+  ##############################################################################
+  # Build the ad compiler (the adlc build tool)
+
+  # Flags depending on the build platform/tool chain
+  # NOTE: No optimization or debug flags set here
+  ifeq ($(OPENJDK_BUILD_OS), linux)
+    ADLC_CFLAGS := -fno-exceptions -DLINUX
+  else ifeq ($(OPENJDK_BUILD_OS), solaris)
+    ADLC_LDFLAGS := -m64
+    ADLC_CFLAGS := -m64
+    ADLC_CFLAGS_WARNINGS := +w
+  else ifeq ($(OPENJDK_BUILD_OS), aix)
+    ADLC_LDFLAGS := -q64
+    ADLC_CFLAGS := -qnortti -qeh -q64 -DAIX
+  else ifeq ($(OPENJDK_BUILD_OS), windows)
+    ADLC_LDFLAGS := -nologo
+    ADLC_CFLAGS := -nologo -EHsc
+    # NOTE: The old build also have -D_CRT_SECURE_NO_DEPRECATE but it doesn't
+    # seem needed any more.
+    ADLC_CFLAGS_WARNINGS := -W3 -D_CRT_SECURE_NO_WARNINGS
+  endif
+
+  # NOTE: The old build didn't set -DASSERT for windows but it doesn't seem to
+  # hurt.
+  ADLC_CFLAGS += -DASSERT
+
+  ADLC_CFLAGS += -D$(HOTSPOT_TARGET_CPU_DEFINE)
+
+  ADLC_CFLAGS += -I$(HOTSPOT_TOPDIR)/src/share/vm
+
+  $(eval $(call SetupNativeCompilation, BUILD_ADLC, \
+      TOOLCHAIN := TOOLCHAIN_BUILD_LINK_CXX, \
+      SRC := $(HOTSPOT_TOPDIR)/src/share/vm/adlc, \
+      EXTRA_FILES := $(HOTSPOT_TOPDIR)/src/share/vm/opto/opcodes.cpp, \
+      CFLAGS := $(ADLC_CFLAGS) $(ADLC_CFLAGS_WARNINGS), \
+      LDFLAGS := $(ADLC_LDFLAGS), \
+      LIBS := $(ADLC_LIBS), \
+      OBJECT_DIR := $(JVM_VARIANT_OUTPUTDIR)/tools/adlc/objs, \
+      OUTPUT_DIR := $(JVM_VARIANT_OUTPUTDIR)/tools/adlc, \
+      PROGRAM := adlc, \
+      DEBUG_SYMBOLS := false, \
+      DISABLED_WARNINGS_clang := parentheses tautological-compare, \
+      DISABLED_WARNINGS_solstudio := notemsource, \
+  ))
+
+  ADLC_TOOL := $(BUILD_ADLC_TARGET)
+
+  ##############################################################################
+  # Transform the ad source files into C++ source files using adlc
+
+  # Setup flags for the adlc build tool (ADLCFLAGS).
+  ADLCFLAGS += -q -T
+
+  # ADLC flags depending on target OS
+  ifeq ($(OPENJDK_TARGET_OS), linux)
+    ADLCFLAGS += -DLINUX=1 -D_GNU_SOURCE=1
+  else ifeq ($(OPENJDK_TARGET_OS), solaris)
+    ADLCFLAGS += -DSOLARIS=1 -DSPARC_WORKS=1
+  else ifeq ($(OPENJDK_TARGET_OS), aix)
+    ADLCFLAGS += -DAIX=1
+  else ifeq ($(OPENJDK_TARGET_OS), macosx)
+    ADLCFLAGS += -D_ALLBSD_SOURCE=1 -D_GNU_SOURCE=1
+  endif
+
+  ifneq ($(OPENJDK_TARGET_OS), windows)
+    # NOTE: Windows adlc flags was different in the old build. Is this really
+    # correct?
+
+    # -g makes #line directives in the generated C++ files.
+    ADLCFLAGS += -g
+
+    ADLCFLAGS += -D$(HOTSPOT_TARGET_CPU_DEFINE)=1
+  endif
+
+  # This generates checks in the generated C++ files that _LP64 is correctly
+  # (un)defined when compiling them.
+  ifeq ($(OPENJDK_TARGET_CPU_BITS), 64)
+    ADLCFLAGS += -D_LP64=1
+  else
+    ADLCFLAGS += -U_LP64
+  endif
+
+  ##############################################################################
+  # Concatenate all ad source files into a single file, which will be fed to
+  # adlc. Also include a #line directive at the start of every included file
+  # (after the initial header block), stating the original source file name.
+  #
+  # Normally, debugging is done directly on the ad_<arch>*.cpp files, but the
+  # #line directives in those files will be pointing back to <arch>.ad.
+
+  # AD_SRC_ROOTS might have been added to by a custom extension
+  AD_SRC_ROOTS += $(HOTSPOT_TOPDIR)/src
+
+  AD_SRC_FILES := $(call uniq, $(wildcard $(foreach d, $(AD_SRC_ROOTS), \
+      $d/cpu/$(HOTSPOT_TARGET_CPU_ARCH)/vm/$(HOTSPOT_TARGET_CPU).ad \
+      $d/cpu/$(HOTSPOT_TARGET_CPU_ARCH)/vm/$(HOTSPOT_TARGET_CPU_ARCH).ad \
+      $d/os_cpu/$(HOTSPOT_TARGET_OS)_$(HOTSPOT_TARGET_CPU_ARCH)/vm/$(HOTSPOT_TARGET_OS)_$(HOTSPOT_TARGET_CPU_ARCH).ad \
+    )))
+
+  SINGLE_AD_SRCFILE := $(ADLC_SUPPORT_DIR)/all-ad-src.ad
+
+  INSERT_FILENAME_AWK_SCRIPT := \
+      '{ \
+         if (CUR_FN != FILENAME) { CUR_FN=FILENAME; NR_BASE=NR-1; need_lineno=1 } \
+         if (need_lineno && $$0 !~ /\/\//) \
+           { print "\n\n\#line " (NR-NR_BASE) " \"" FILENAME "\""; need_lineno=0 }; \
+         print \
+       }'
+
+  $(SINGLE_AD_SRCFILE): $(AD_SRC_FILES)
+	$(call LogInfo, Preprocessing adlc files $(^F))
+	$(call MakeDir, $(@D))
+	$(NAWK) $(INSERT_FILENAME_AWK_SCRIPT) $^ > $@
+
+  ##############################################################################
+  # Run the adlc tool on the single concatenated ad source file, and store the
+  # output in support/adlc for further processing.
+  ADLC_RUN_MARKER := $(ADLC_SUPPORT_DIR)/_adlc_run.marker
+
+  $(ADLC_RUN_MARKER): $(BUILD_ADLC) $(SINGLE_AD_SRCFILE)
+	$(call LogInfo, Generating adlc files)
+	$(call MakeDir, $(@D))
+	$(call ExecuteWithLog, $(ADLC_SUPPORT_DIR)/adlc_run, \
+	    $(FIXPATH) $(ADLC_TOOL) $(ADLCFLAGS) $(SINGLE_AD_SRCFILE) \
+	        -c$(ADLC_SUPPORT_DIR)/ad_$(HOTSPOT_TARGET_CPU).cpp \
+	        -h$(ADLC_SUPPORT_DIR)/ad_$(HOTSPOT_TARGET_CPU).hpp \
+	        -a$(ADLC_SUPPORT_DIR)/dfa_$(HOTSPOT_TARGET_CPU).cpp \
+	        -v$(ADLC_SUPPORT_DIR)/adGlobals_$(HOTSPOT_TARGET_CPU).hpp)
+	$(TOUCH) $@
+
+  ##############################################################################
+  # Finally copy the generated files from support/adlc into gensrc/adfiles,
+  # and postprocess them by fixing dummy #line directives.
+
+  ADLC_GENERATED_FILES := $(addprefix $(JVM_VARIANT_OUTPUTDIR)/gensrc/adfiles/, \
+      ad_$(HOTSPOT_TARGET_CPU).cpp \
+      ad_$(HOTSPOT_TARGET_CPU).hpp \
+      ad_$(HOTSPOT_TARGET_CPU)_clone.cpp \
+      ad_$(HOTSPOT_TARGET_CPU)_expand.cpp \
+      ad_$(HOTSPOT_TARGET_CPU)_format.cpp \
+      ad_$(HOTSPOT_TARGET_CPU)_gen.cpp \
+      ad_$(HOTSPOT_TARGET_CPU)_misc.cpp \
+      ad_$(HOTSPOT_TARGET_CPU)_peephole.cpp \
+      ad_$(HOTSPOT_TARGET_CPU)_pipeline.cpp \
+      adGlobals_$(HOTSPOT_TARGET_CPU).hpp \
+      dfa_$(HOTSPOT_TARGET_CPU).cpp \
+  )
+
+  $(JVM_VARIANT_OUTPUTDIR)/gensrc/adfiles/%: $(ADLC_RUN_MARKER)
+	$(call LogInfo, Postprocessing adlc file $*)
+	$(call MakeDir, $(@D))
+	$(NAWK) \
+	    'BEGIN { print "#line 1 \"$*\""; } \
+	     /^#line 999999$$/ {print "#line " (NR+1) " \"$*\""; next} \
+	     {print}' \
+	    < $(ADLC_SUPPORT_DIR)/$* > $@
+
+  TARGETS := $(ADLC_GENERATED_FILES)
+
+endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/makefiles/gensrc/GensrcDtrace.gmk	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,56 @@
+#
+# 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
+# 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.
+#
+
+################################################################################
+# Gensrc support for dtrace. The files generated here are included by dtrace.hpp
+
+ifeq ($(call check-jvm-feature, dtrace), true)
+
+  ifeq ($(OPENJDK_TARGET_OS), solaris)
+    DTRACE_FLAGS := -64
+    DTRACE_CPP_FLAGS := -D_LP64
+  else ifeq ($(OPENJDK_TARGET_OS), macosx)
+    DTRACE_CPP_FLAGS := -D_LP64 -x c
+  else ifeq ($(OPENJDK_TARGET_OS), linux)
+    DTRACE_CPP_FLAGS := -x c
+  endif
+
+  DTRACE_SOURCE_DIR := $(HOTSPOT_TOPDIR)/src/os/posix/dtrace
+  DTRACE_GENSRC_DIR := $(JVM_VARIANT_OUTPUTDIR)/gensrc/dtracefiles
+
+  # Make sure we run our selected compiler for preprocessing instead of letting
+  # the dtrace tool pick it on it's own.
+  $(DTRACE_GENSRC_DIR)/%.h: $(DTRACE_SOURCE_DIR)/%.d
+	$(call LogInfo, Generating dtrace header file $(@F))
+	$(call MakeDir, $(@D) $(DTRACE_SUPPORT_DIR))
+	$(call ExecuteWithLog, $(DTRACE_SUPPORT_DIR)/$(@F).d, $(CC) -E $(DTRACE_CPP_FLAGS) $< > $(DTRACE_SUPPORT_DIR)/$(@F).d)
+	$(call ExecuteWithLog, $@, $(DTRACE) $(DTRACE_FLAGS) -h -o $@ -s $(DTRACE_SUPPORT_DIR)/$(@F).d)
+
+  # Process all .d files in DTRACE_SOURCE_DIR. They are:
+  # hotspot_jni.d hotspot.d hs_private.d
+  TARGETS += $(patsubst $(DTRACE_SOURCE_DIR)/%.d, \
+      $(DTRACE_GENSRC_DIR)/%.h, $(wildcard $(DTRACE_SOURCE_DIR)/*.d))
+
+endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/makefiles/gensrc/GensrcJvmti.gmk	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,174 @@
+#
+# 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
+# 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.
+#
+
+$(eval $(call IncludeCustomExtension, hotspot, gensrc/GensrcJvmti.gmk))
+
+################################################################################
+# Build tools needed for the JVMTI source code generation
+
+JVMTI_TOOLS_SRCDIR := $(HOTSPOT_TOPDIR)/src/share/vm/prims
+JVMTI_TOOLS_OUTPUTDIR := $(JVM_VARIANT_OUTPUTDIR)/tools/jvmti
+
+$(eval $(call SetupJavaCompiler, GENERATE_OLDBYTECODE, \
+    JAVAC := $(JAVAC), \
+    FLAGS := $(DISABLE_WARNINGS), \
+    SERVER_DIR := $(SJAVAC_SERVER_DIR), \
+    SERVER_JVM := $(SJAVAC_SERVER_JAVA), \
+    DISABLE_SJAVAC := true, \
+))
+
+$(eval $(call SetupJavaCompilation, BUILD_JVMTI_TOOLS, \
+    SETUP := GENERATE_OLDBYTECODE, \
+    SRC := $(JVMTI_TOOLS_SRCDIR), \
+    INCLUDE_FILES := jvmtiGen.java jvmtiEnvFill.java, \
+    BIN := $(JVMTI_TOOLS_OUTPUTDIR), \
+))
+
+TOOL_JVMTI_GEN := $(JAVA_SMALL) -cp $(JVMTI_TOOLS_OUTPUTDIR) jvmtiGen
+TOOL_JVMTI_ENV_FILL := $(JAVA_SMALL) -cp $(JVMTI_TOOLS_OUTPUTDIR) jvmtiEnvFill
+
+################################################################################
+# Setup make rules for an xml transform for jvmti/trace file generation.
+#
+# Parameter 1 is the name of the rule. This name is used as variable prefix,
+# and the targets generated are listed in a variable by that name. This name is
+# also used as the name of the output file.
+#
+# Remaining parameters are named arguments. These include:
+#   XML_FILE -- The input source file to use
+#   XSL_FILE -- The xsl file to use
+#   OUTPUT_DIR -- The directory to put the generated file in
+#   ARGS -- Additional arguments to the jvmtiGen tool
+#   DEPS -- Additional dependencies
+SetupXslTransform = $(NamedParamsMacroTemplate)
+define SetupXslTransformBody
+  $$($1_OUTPUT_DIR)/$1: $$($1_XML_FILE) $$($1_XSL_FILE) $$($1_DEPS) $$(BUILD_JVMTI_TOOLS)
+	$$(call LogInfo, Generating $$(@F))
+	$$(call MakeDir, $$(@D))
+	$$(call ExecuteWithLog, $$@, $$(TOOL_JVMTI_GEN) -IN $$($1_XML_FILE) -XSL $$($1_XSL_FILE) -OUT $$@ $$($1_ARGS))
+        # jvmtiGen does not return error code properly on fail.
+        # NOTE: We should really fix jvmtiGen.java instead.
+	test -f $$@
+
+  TARGETS += $$($1_OUTPUT_DIR)/$1
+endef
+
+################################################################################
+# Create JVMTI files in gensrc/jvmtifiles
+
+JVMTI_SRCDIR := $(HOTSPOT_TOPDIR)/src/share/vm/prims
+JVMTI_OUTPUTDIR := $(JVM_VARIANT_OUTPUTDIR)/gensrc/jvmtifiles
+
+# Setup rule for generating a jvmti file
+#
+# $1 is generated source file name in $(JVMTI_OUTPUTDIR)
+# $2 is XSL file to use in $(JVMTI_SRCDIR)
+# $3 is optional extra arguments to jvmtiGen
+define SetupJvmtiGeneration
+  $$(eval $$(call SetupXslTransform, $1, \
+      XML_FILE := $$(JVMTI_SRCDIR)/jvmti.xml, \
+      XSL_FILE := $$(JVMTI_SRCDIR)/$(strip $2), \
+      OUTPUT_DIR := $$(JVMTI_OUTPUTDIR), \
+      ARGS := $3, \
+      DEPS := $$(JVMTI_SRCDIR)/jvmtiLib.xsl, \
+  ))
+endef
+
+$(eval $(call SetupJvmtiGeneration, jvmtiEnter.cpp, jvmtiEnter.xsl, \
+    -PARAM interface jvmti))
+$(eval $(call SetupJvmtiGeneration, jvmtiEnterTrace.cpp, jvmtiEnter.xsl, \
+    -PARAM interface jvmti -PARAM trace Trace))
+$(eval $(call SetupJvmtiGeneration, jvmtiEnv.hpp, jvmtiHpp.xsl))
+$(eval $(call SetupJvmtiGeneration, jvmti.h, jvmtiH.xsl))
+$(eval $(call SetupJvmtiGeneration, jvmti.html, jvmti.xsl))
+$(eval $(call SetupJvmtiGeneration, jvmtiEnvStub.cpp, jvmtiEnv.xsl))
+
+JVMTI_BC_SRCDIR := $(HOTSPOT_TOPDIR)/src/share/vm/interpreter
+
+$(eval $(call SetupXslTransform, bytecodeInterpreterWithChecks.cpp, \
+    XML_FILE := $(JVMTI_BC_SRCDIR)/bytecodeInterpreterWithChecks.xml, \
+    XSL_FILE := $(JVMTI_BC_SRCDIR)/bytecodeInterpreterWithChecks.xsl, \
+    OUTPUT_DIR := $(JVMTI_OUTPUTDIR), \
+    DEPS := $(JVMTI_BC_SRCDIR)/bytecodeInterpreter.cpp, \
+))
+
+# We need $(JVMTI_OUTPUTDIR)/jvmtiEnvStub.cpp (generated above) as input
+$(JVMTI_OUTPUTDIR)/jvmtiEnvRecommended.cpp: $(JVMTI_SRCDIR)/jvmtiEnv.cpp \
+    $(JVMTI_OUTPUTDIR)/jvmtiEnvStub.cpp $(BUILD_JVMTI_TOOLS)
+	$(call LogInfo, Generating $(@F))
+	$(call MakeDir, $(@D))
+	$(call ExecuteWithLog, $@, $(TOOL_JVMTI_ENV_FILL) $(JVMTI_SRCDIR)/jvmtiEnv.cpp \
+	    $(JVMTI_OUTPUTDIR)/jvmtiEnvStub.cpp \
+	    $(JVMTI_OUTPUTDIR)/jvmtiEnvRecommended.cpp)
+        # jvmtiEnvFill does not necessarily return an error code on failure.
+        # NOTE: We should really fix jvmtiEnvFill.java instead.
+	test -f $@
+
+TARGETS += $(JVMTI_OUTPUTDIR)/jvmtiEnvRecommended.cpp
+
+################################################################################
+# Create trace files in gensrc/tracefiles
+
+TRACE_OUTPUTDIR := $(JVM_VARIANT_OUTPUTDIR)/gensrc/tracefiles
+TRACE_SRCDIR := $(HOTSPOT_TOPDIR)/src/share/vm/trace
+
+# Append directories to search (might have been set by custom extensions)
+TRACE_SEARCH_DIRS += $(TRACE_SRCDIR)
+
+TRACE_XML ?= $(TRACE_SRCDIR)/trace.xml
+
+# Changing these will trigger a rebuild of generated trace files.
+TRACE_DEPS += \
+    $(TRACE_XML) \
+    $(TRACE_SRCDIR)/tracetypes.xml \
+    $(TRACE_SRCDIR)/tracerelationdecls.xml \
+    $(TRACE_SRCDIR)/traceevents.xml \
+    $(TRACE_SRCDIR)/trace.dtd \
+    $(TRACE_SRCDIR)/xinclude.mod \
+    #
+
+# Setup rule for generating a trace file
+#
+# $1 is generated source file name in $(TRACE_OUTPUTDIR)
+define SetupTraceGeneration
+  $$(eval $$(call SetupXslTransform, $1, \
+      XML_FILE := $$(TRACE_XML), \
+      XSL_FILE := $$(firstword $$(wildcard $$(addsuffix /$$(basename $1).xsl, $$(TRACE_SEARCH_DIRS)))), \
+      OUTPUT_DIR := $$(TRACE_OUTPUTDIR), \
+      DEPS := $$(TRACE_DEPS), \
+  ))
+endef
+
+# Append files to generated (might have been set by custom extensions)
+TRACE_GENSRC_FILES += \
+    traceEventClasses.hpp \
+    traceEventIds.hpp \
+    traceTypes.hpp \
+    #
+
+# Call SetupTraceGeneration for all trace gensrc files
+$(foreach tracefile, $(TRACE_GENSRC_FILES), \
+  $(eval $(call SetupTraceGeneration, $(tracefile))) \
+)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/makefiles/ide/CreateVSProject.gmk	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,153 @@
+#
+# 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.
+#
+
+# This must be the first rule
+default: all
+
+include $(SPEC)
+include MakeBase.gmk
+include JavaCompilation.gmk
+include SetupJavaCompilers.gmk
+
+ifeq ($(OPENJDK_TARGET_OS), windows)
+  # The next part is a bit hacky. We include the CompileJvm.gmk to be
+  # able to extact flags, but we do not wish to execute the rules.
+
+  # Use client as base for defines and includes
+  JVM_VARIANT=client
+
+  include HotspotCommon.gmk
+  include lib/CompileJvm.gmk
+
+  # Reset targets so we don't build libjvm.
+  TARGETS :=
+
+  # Helper macro to convert a unix path to a Windows path, suitable for
+  # inclusion in a command line.
+  FixPath = \
+    $(strip $(subst \,\\,$(shell $(CYGPATH) -w $1)))
+
+  JVM_DEFINES_client := $(patsubst -D%,%, $(filter -D%, $(JVM_CFLAGS)))
+  EXTRACTED_DEFINES_client := $(addprefix -define , $(JVM_DEFINES_client))
+
+  JVM_INCLUDES_client := $(patsubst -I%,%, $(filter -I%, $(JVM_CFLAGS)))
+  EXTRACTED_INCLUDES_client := $(foreach path, $(JVM_INCLUDES_client), -absoluteInclude $(call FixPath, $(path)))
+
+  # Hand-code variant-specific arguments, based on the fact that we use
+  # client for general arguments. Not optimal but other solutions require
+  # major changes in ProjectCreator.
+  ADDITIONAL_VARIANT_ARGS := \
+      -define_server COMPILER2 \
+      -ignorePath_client adfiles \
+      -ignorePath_client c2_ \
+      -ignorePath_client runtime_ \
+      -ignorePath_client libadt \
+      -ignorePath_client opto \
+      #
+
+  IGNORED_PLATFORMS_ARGS := \
+    -ignorePath aarch64 \
+    -ignorePath aix \
+    -ignorePath arm \
+    -ignorePath bsd \
+    -ignorePath linux \
+    -ignorePath posix \
+    -ignorePath ppc \
+    -ignorePath shark \
+    -ignorePath solaris \
+    -ignorePath sparc \
+    -ignorePath x86_32 \
+    -ignorePath zero \
+      #
+
+  ################################################################################
+  # Build the ProjectCreator java tool.
+
+  TOOLS_OUTPUTDIR := $(HOTSPOT_OUTPUTDIR)/support/tools_classes
+
+  $(eval $(call SetupJavaCompilation, BUILD_PROJECT_CREATOR, \
+      SETUP := GENERATE_OLDBYTECODE, \
+      ADD_JAVAC_FLAGS := -Xlint:-auxiliaryclass, \
+      SRC := $(HOTSPOT_TOPDIR)/makefiles/src/classes, \
+      BIN := $(TOOLS_OUTPUTDIR), \
+  ))
+
+  TARGETS += $(BUILD_PROJECT_CREATOR)
+
+  # Run the ProjectCreator tool
+  PROJECT_CREATOR_TOOL := $(JAVA_SMALL) -cp $(TOOLS_OUTPUTDIR) build.tools.projectcreator.ProjectCreator
+
+  IDE_OUTPUTDIR := $(BUILD_OUTPUT)/ide/hotspot-visualstudio
+
+  VCPROJ_FILE := $(IDE_OUTPUTDIR)/jvm.vcxproj
+
+  PROJECT_CREATOR_CLASS := build.tools.projectcreator.WinGammaPlatformVC10
+
+  # We hard-code gensrc dir to server (since this includes adfiles)
+  PROJECT_CREATOR_ARGS := \
+      -sourceBase $(call FixPath, $(HOTSPOT_TOPDIR)) \
+      -startAt src \
+      -relativeSrcInclude src \
+      -hidePath .hg \
+      -hidePath .jcheck \
+      -hidePath jdk.hotspot.agent \
+      -hidePath jdk.vm.ci \
+      -hidePath jdk.jfr \
+      -compiler VC10 \
+      -jdkTargetRoot $(call FixPath, $(JDK_OUTPUTDIR)) \
+      -platformName x64 \
+      -buildBase $(call FixPath, $(IDE_OUTPUTDIR)/vs-output) \
+      -buildSpace $(call FixPath, $(IDE_OUTPUTDIR)) \
+      -makeBinary $(call FixPath, $(MAKE)) \
+      -makeOutput $(call FixPath, $(HOTSPOT_OUTPUTDIR)/variant-%f/libjvm) \
+      -absoluteInclude $(call FixPath, $(HOTSPOT_OUTPUTDIR)/variant-server/gensrc) \
+      -absoluteSrcInclude $(call FixPath, $(HOTSPOT_OUTPUTDIR)/variant-server/gensrc) \
+      $(EXTRACTED_DEFINES_client) \
+      $(EXTRACTED_INCLUDES_client) \
+      $(ADDITIONAL_VARIANT_ARGS) \
+      $(IGNORED_PLATFORMS_ARGS) \
+      #
+
+  VCPROJ_VARDEPS := $(PROJECT_CREATOR_CLASS) $(PROJECT_CREATOR_ARGS)
+  VCPROJ_VARDEPS_FILE := $(call DependOnVariable, VCPROJ_VARDEPS, \
+    $(VCPROJ_FILE).vardeps)
+
+  $(VCPROJ_FILE): $(BUILD_PROJECT_CREATOR) $(VCPROJ_VARDEPS_FILE)
+	$(call MakeDir, $(@D))
+	$(call ExecuteWithLog, $@, \
+	    $(PROJECT_CREATOR_TOOL) $(PROJECT_CREATOR_CLASS) \
+	    $(PROJECT_CREATOR_ARGS) -projectFileName $(call FixPath, $@)) \
+	    $(LOG_INFO)
+
+  TARGETS += $(VCPROJ_FILE)
+
+  all: $(TARGETS)
+
+else
+  all:
+	$(info Hotspot Visual Studio generation only supported on Windows)
+endif
+
+.PHONY: all
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/makefiles/lib/CompileDtracePostJvm.gmk	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,217 @@
+#
+# 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
+# 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.
+#
+
+################################################################################
+# Support for dtrace integration with libjvm, and stand-alone dtrace library
+# compilation.
+
+ifeq ($(call check-jvm-feature, dtrace), true)
+  ##############################################################################
+
+  ifeq ($(OPENJDK_TARGET_OS), solaris)
+    ############################################################################
+    # Integrate with libjvm. Here we generate three object files which are
+    # linked with libjvm.so. This step is complicated from a dependency
+    # perspective, since it needs the rest of the compiled object files from the
+    # libjvm compilation, but the output is object files that are to be included
+    # when linking libjvm.so. So this generation must happen as a part of the
+    # libjvm compilation.
+
+    # First we need to generate the dtraceGenOffsets tool. When run, this will
+    # produce more header files and a C++ file.
+
+    # Note that generateJvmOffsets.cpp must be compiled as if it were a file
+    # in the libjvm.so, using JVM_CFLAGS as setup in CompileJvm.gmk. Otherwise
+    # this would preferrably have been done as a part of GensrcDtrace.gmk.
+    $(eval $(call SetupNativeCompilation, BUILD_DTRACE_GEN_OFFSETS, \
+        SRC := $(HOTSPOT_TOPDIR)/src/os/$(OPENJDK_TARGET_OS)/dtrace, \
+        INCLUDE_FILES := generateJvmOffsets.cpp generateJvmOffsetsMain.c, \
+        CC := $(BUILD_CXX), \
+        CXX := $(BUILD_CXX), \
+        LDEXE := $(BUILD_CXX), \
+        generateJvmOffsets.cpp_CXXFLAGS := $(JVM_CFLAGS) -mt -xnolib -norunpath, \
+        generateJvmOffsetsMain.c_CFLAGS := -library=%none -mt -m64 -norunpath -z nodefs, \
+        LDFLAGS := -m64, \
+        LIBS := -lc, \
+        OBJECT_DIR := $(JVM_VARIANT_OUTPUTDIR)/tools/dtrace-gen-offsets/objs, \
+        OUTPUT_DIR := $(JVM_VARIANT_OUTPUTDIR)/tools/dtrace-gen-offsets, \
+        PROGRAM := dtraceGenOffsets, \
+    ))
+
+    DTRACE_GEN_OFFSETS_TOOL := $(BUILD_DTRACE_GEN_OFFSETS_TARGET)
+
+    # Argument 1: Output filename
+    # Argument 2: dtrace-gen-offset tool command line option
+    define SetupDtraceOffsetsGeneration
+      $1: $$(BUILD_DTRACE_GEN_OFFSETS)
+	$$(call LogInfo, Generating dtrace $2 file $$(@F))
+	$$(call MakeDir, $$(@D))
+	$$(call ExecuteWithLog, $$@, $$(DTRACE_GEN_OFFSETS_TOOL) -$$(strip $2) > $$@)
+
+      TARGETS += $1
+    endef
+
+    JVM_OFFSETS_H := $(DTRACE_SUPPORT_DIR)/JvmOffsets.h
+    JVM_OFFSETS_CPP := $(DTRACE_SUPPORT_DIR)/JvmOffsets.cpp
+    JVM_OFFSETS_INDEX_H := $(DTRACE_SUPPORT_DIR)/JvmOffsetsIndex.h
+
+    # Run the dtrace-gen-offset tool to generate these three files.
+    $(eval $(call SetupDtraceOffsetsGeneration, $(JVM_OFFSETS_H), header))
+    $(eval $(call SetupDtraceOffsetsGeneration, $(JVM_OFFSETS_INDEX_H), index))
+    $(eval $(call SetupDtraceOffsetsGeneration, $(JVM_OFFSETS_CPP), table))
+
+    ############################################################################
+    # Compile JVM_OFFSETS_OBJ which is linked with libjvm.so.
+
+    # JvmOffsets.cpp is compiled without the common JVM_CFLAGS. Otherwise, the
+    # natural way would have been to included this source code in BUILD_LIBJVM.
+    JVM_OFFSETS_CFLAGS := -m64
+    ifeq ($(OPENJDK_TARGET_CPU), sparcv9)
+      JVM_OFFSETS_CFLAGS += -xarch=sparc
+    endif
+
+    $(JVM_OFFSETS_OBJ): $(JVM_OFFSETS_CPP) $(JVM_OFFSETS_H)
+	$(call LogInfo, Compiling dtrace file JvmOffsets.cpp (for libjvm.so))
+	$(call ExecuteWithLog, $@, $(CXX) -c -I$(<D) -o $@ $(JVM_OFFSETS_CFLAGS) $<)
+
+    ############################################################################
+    # Generate DTRACE_OBJ which is linked with libjvm.so.
+
+    # Concatenate all *.d files into a single file
+    DTRACE_SOURCE_FILES := $(addprefix $(HOTSPOT_TOPDIR)/src/os/posix/dtrace/, \
+        hotspot_jni.d \
+        hotspot.d \
+        hs_private.d \
+    )
+
+    $(JVM_OUTPUTDIR)/objs/dtrace.d: $(DTRACE_SOURCE_FILES)
+	$(call LogInfo, Generating $(@F))
+	$(call MakeDir, $(@D))
+	$(CAT) $^ > $@
+
+    DTRACE_INSTRUMENTED_OBJS := $(addprefix $(JVM_OUTPUTDIR)/objs/, \
+        ciEnv.o \
+        classLoadingService.o \
+        compileBroker.o \
+        hashtable.o \
+        instanceKlass.o \
+        java.o \
+        jni.o \
+        jvm.o \
+        memoryManager.o \
+        nmethod.o \
+        objectMonitor.o \
+        runtimeService.o \
+        sharedRuntime.o \
+        synchronizer.o \
+        thread.o \
+        unsafe.o \
+        vmThread.o \
+        vmGCOperations.o \
+    )
+
+    ifeq ($(call check-jvm-feature, all-gcs), true)
+      DTRACE_INSTRUMENTED_OBJS += $(addprefix $(JVM_OUTPUTDIR)/objs/, \
+          vmCMSOperations.o \
+          vmPSOperations.o \
+      )
+    endif
+
+    DTRACE_FLAGS := -64 -G
+    DTRACE_CPP_FLAGS := -D_LP64
+
+    # Make sure we run our selected compiler for preprocessing instead of letting
+    # the dtrace tool pick it on it's own.
+    $(DTRACE_OBJ): $(JVM_OUTPUTDIR)/objs/dtrace.d $(DTRACE_INSTRUMENTED_OBJS)
+	$(call LogInfo, Generating $(@F) from $(<F) and object files)
+	$(call MakeDir, $(DTRACE_SUPPORT_DIR))
+	$(call ExecuteWithLog, $(DTRACE_SUPPORT_DIR)/$(@F).d, $(CC) -E \
+	    $(DTRACE_CPP_FLAGS) $< > $(DTRACE_SUPPORT_DIR)/$(@F).d)
+	$(call ExecuteWithLog, $@, $(DTRACE) $(DTRACE_FLAGS) -xlazyload -o $@ \
+	    -s $(DTRACE_SUPPORT_DIR)/$(@F).d $(sort $(DTRACE_INSTRUMENTED_OBJS)))
+
+    ############################################################################
+    # Generate DTRACE_JHELPER_OBJ which is linked with libjvm.so.
+
+    # Unfortunately dtrace generates incorrect types for some symbols in
+    # dtrace_jhelper.o, resulting in "warning: symbol X has differing types"
+    # This is tracked in JDK-6890703.
+    $(DTRACE_JHELPER_OBJ): $(HOTSPOT_TOPDIR)/src/os/solaris/dtrace/jhelper.d \
+        $(JVM_OFFSETS_INDEX_H)
+	$(call LogInfo, Running dtrace for $(<F))
+	$(call ExecuteWithLog, $@, $(DTRACE) $(DTRACE_FLAGS) $(DTRACE_CPP_FLAGS) -C \
+	    -I$(DTRACE_SUPPORT_DIR) -o $@ -s $<)
+
+    # NOTE: We should really do something like this, but unfortunately this
+    # results in a compilation error. :-(
+    # $(call MakeDir, $(DTRACE_SUPPORT_DIR))
+    # $(call ExecuteWithLog, $(DTRACE_SUPPORT_DIR)/$(@F).d, $(CC) -E \
+    #     $(DTRACE_CPP_FLAGS) -I$(DTRACE_SUPPORT_DIR) $^ \
+    #     > $(DTRACE_SUPPORT_DIR)/$(@F).d)
+    # $(call ExecuteWithLog, $@, $(DTRACE) $(DTRACE_FLAGS) -o $@ \
+    #     -s $(DTRACE_SUPPORT_DIR)/$(@F).d)
+
+    ############################################################################
+    # Build the stand-alone dtrace libraries
+
+    LIBJVM_DTRACE_OUTPUTDIR := $(JVM_VARIANT_OUTPUTDIR)/libjvm_dtrace
+
+    $(eval $(call SetupNativeCompilation, BUILD_LIBJVM_DTRACE, \
+        LIBRARY := jvm_dtrace, \
+        OUTPUT_DIR := $(LIBJVM_DTRACE_OUTPUTDIR), \
+        SRC := $(HOTSPOT_TOPDIR)/src/os/solaris/dtrace, \
+        INCLUDE_FILES := jvm_dtrace.c, \
+        CFLAGS := -m64 -G -mt -KPIC, \
+        LDFLAGS := -m64 -mt -xnolib $(SHARED_LIBRARY_FLAGS), \
+        LIBS := $(LIBDL) -lc -lthread -ldoor, \
+        MAPFILE := $(HOTSPOT_TOPDIR)/makefiles/mapfiles/libjvm_dtrace/mapfile-vers, \
+        OBJECT_DIR := $(LIBJVM_DTRACE_OUTPUTDIR)/objs, \
+        STRIP_SYMBOLS := true, \
+    ))
+
+    LIBJVM_DB_OUTPUTDIR := $(JVM_VARIANT_OUTPUTDIR)/libjvm_db
+
+    # Note that libjvm_db.c has tests for COMPILER2, but this was never set by
+    # the old build.
+    $(eval $(call SetupNativeCompilation, BUILD_LIBJVM_DB, \
+        LIBRARY := jvm_db, \
+        OUTPUT_DIR := $(LIBJVM_DB_OUTPUTDIR), \
+        SRC := $(HOTSPOT_TOPDIR)/src/os/solaris/dtrace, \
+        INCLUDE_FILES := libjvm_db.c, \
+        CFLAGS := -I$(JVM_VARIANT_OUTPUTDIR)/gensrc -I$(DTRACE_SUPPORT_DIR) \
+            -m64 -G -mt -KPIC, \
+        LDFLAGS := -m64 -mt -xnolib $(SHARED_LIBRARY_FLAGS), \
+        LIBS := -lc, \
+        MAPFILE := $(HOTSPOT_TOPDIR)/makefiles/mapfiles/libjvm_db/mapfile-vers, \
+        OBJECT_DIR := $(LIBJVM_DB_OUTPUTDIR)/objs, \
+        STRIP_SYMBOLS := true, \
+    ))
+
+    # We need the generated JvmOffsets.h before we can compile the libjvm_db source code.
+    $(BUILD_LIBJVM_DB_ALL_OBJS): $(JVM_OFFSETS_H)
+
+    TARGETS += $(BUILD_LIBJVM_DTRACE) $(BUILD_LIBJVM_DB)
+  endif
+endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/makefiles/lib/CompileDtracePreJvm.gmk	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,36 @@
+#
+# 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.
+#
+
+ifeq ($(call check-jvm-feature, dtrace), true)
+  ifeq ($(OPENJDK_TARGET_OS), solaris)
+    # These files are are generated by CompileDtrace.gmk but consumed by
+    # CompileJvm.gmk
+    DTRACE_OBJ := $(JVM_OUTPUTDIR)/objs/dtrace.o
+    DTRACE_JHELPER_OBJ := $(JVM_OUTPUTDIR)/objs/dtrace_jhelper.o
+    JVM_OFFSETS_OBJ := $(JVM_OUTPUTDIR)/objs/JvmOffsets.o
+
+    DTRACE_EXTRA_OBJECT_FILES := $(DTRACE_OBJ) $(DTRACE_JHELPER_OBJ) $(JVM_OFFSETS_OBJ)
+  endif
+endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/makefiles/lib/CompileJvm.gmk	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,242 @@
+#
+# 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
+# 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.
+#
+
+# Include support files that will setup compiler flags due to the selected
+# jvm feature set, and specific file overrides.
+include lib/JvmFeatures.gmk
+include lib/JvmOverrideFiles.gmk
+
+$(eval $(call IncludeCustomExtension, hotspot, lib/CompileJvm.gmk))
+
+################################################################################
+# Setup compilation of the main Hotspot native library (libjvm).
+
+JVM_OUTPUTDIR := $(JVM_VARIANT_OUTPUTDIR)/libjvm
+JVM_MAPFILE := $(JVM_OUTPUTDIR)/mapfile
+
+################################################################################
+# Platform independent setup
+
+# This variable may be added to by a custom extension
+JVM_SRC_ROOTS += $(HOTSPOT_TOPDIR)/src
+
+JVM_SRC_DIRS += $(call uniq, $(wildcard $(foreach d, $(JVM_SRC_ROOTS), \
+        $d/share/vm \
+        $d/os/$(HOTSPOT_TARGET_OS)/vm \
+        $d/os/$(HOTSPOT_TARGET_OS_TYPE)/vm \
+        $d/cpu/$(HOTSPOT_TARGET_CPU_ARCH)/vm \
+        $d/os_cpu/$(HOTSPOT_TARGET_OS)_$(HOTSPOT_TARGET_CPU_ARCH)/vm \
+    ))) \
+    $(JVM_VARIANT_OUTPUTDIR)/gensrc/jvmtifiles \
+    $(JVM_VARIANT_OUTPUTDIR)/gensrc/tracefiles \
+    #
+
+JVM_CFLAGS_INCLUDES += \
+    $(patsubst %,-I%,$(filter-out $(JVM_VARIANT_OUTPUTDIR)/gensrc/%, $(JVM_SRC_DIRS))) \
+    -I$(JVM_VARIANT_OUTPUTDIR)/gensrc \
+    -I$(HOTSPOT_TOPDIR)/src/share/vm/precompiled \
+    -I$(HOTSPOT_TOPDIR)/src/share/vm/prims \
+    #
+
+JVM_CFLAGS_TARGET_DEFINES += \
+    -DTARGET_OS_FAMILY_$(HOTSPOT_TARGET_OS) \
+    -DTARGET_ARCH_MODEL_$(HOTSPOT_TARGET_CPU) \
+    -DTARGET_ARCH_$(HOTSPOT_TARGET_CPU_ARCH) \
+    -DTARGET_OS_ARCH_MODEL_$(HOTSPOT_TARGET_OS)_$(HOTSPOT_TARGET_CPU) \
+    -DTARGET_OS_ARCH_$(HOTSPOT_TARGET_OS)_$(HOTSPOT_TARGET_CPU_ARCH) \
+    -DTARGET_COMPILER_$(HOTSPOT_TOOLCHAIN_TYPE) \
+    -D$(HOTSPOT_TARGET_CPU_DEFINE) \
+    -DHOTSPOT_LIB_ARCH='"$(OPENJDK_TARGET_CPU_LEGACY_LIB)"' \
+    #
+
+ifeq ($(DEBUG_LEVEL), release)
+  # For hotspot, release builds differ internally between "optimized" and "product"
+  # in that "optimize" does not define PRODUCT.
+  ifneq ($(HOTSPOT_DEBUG_LEVEL), optimized)
+    JVM_CFLAGS_DEBUGLEVEL := -DPRODUCT
+  endif
+else ifeq ($(DEBUG_LEVEL), fastdebug)
+  JVM_CFLAGS_DEBUGLEVEL := -DASSERT
+  ifeq ($(filter $(OPENJDK_TARGET_OS), windows aix), )
+    # NOTE: Old build did not define CHECK_UNHANDLED_OOPS on Windows and AIX.
+    JVM_CFLAGS_DEBUGLEVEL += -DCHECK_UNHANDLED_OOPS
+  endif
+else ifeq ($(DEBUG_LEVEL), slowdebug)
+  # _NMT_NOINLINE_ informs NMT that no inlining is done by the compiler
+  JVM_CFLAGS_DEBUGLEVEL := -DASSERT -D_NMT_NOINLINE_
+endif
+
+JVM_CFLAGS += \
+    $(JVM_CFLAGS_DEBUGLEVEL) \
+    $(JVM_CFLAGS_TARGET_DEFINES) \
+    $(JVM_CFLAGS_FEATURES) \
+    $(JVM_CFLAGS_INCLUDES) \
+    $(EXTRA_CFLAGS) \
+    #
+
+JVM_LDFLAGS += \
+    $(SHARED_LIBRARY_FLAGS) \
+    $(JVM_LDFLAGS_FEATURES) \
+    $(EXTRA_LDFLAGS) \
+    #
+
+JVM_LIBS += \
+    $(JVM_LIBS_FEATURES) \
+    #
+
+# These files and directories are always excluded
+JVM_EXCLUDE_FILES += jsig.c jvmtiEnvRecommended.cpp jvmtiEnvStub.cpp args.cc
+JVM_EXCLUDES += adlc
+
+# Needed by vm_version.cpp
+ifeq ($(OPENJDK_TARGET_CPU), x86_64)
+  OPENJDK_TARGET_CPU_VM_VERSION := amd64
+else ifeq ($(OPENJDK_TARGET_CPU), sparcv9)
+  OPENJDK_TARGET_CPU_VM_VERSION := sparc
+else
+  OPENJDK_TARGET_CPU_VM_VERSION := $(OPENJDK_TARGET_CPU)
+endif
+
+CFLAGS_VM_VERSION := \
+    $(VERSION_CFLAGS) \
+    -DHOTSPOT_VERSION_STRING='"$(VERSION_STRING)"' \
+    -DDEBUG_LEVEL='"$(DEBUG_LEVEL)"' \
+    -DHOTSPOT_BUILD_USER='"$(USERNAME)"' \
+    -DHOTSPOT_VM_DISTRO='"$(HOTSPOT_VM_DISTRO)"' \
+    -DCPU='"$(OPENJDK_TARGET_CPU_VM_VERSION)"' \
+    #
+
+# -DDONT_USE_PRECOMPILED_HEADER will exclude all includes in precompiled.hpp.
+ifeq ($(USE_PRECOMPILED_HEADER), 0)
+  JVM_CFLAGS += -DDONT_USE_PRECOMPILED_HEADER
+endif
+
+################################################################################
+# Platform specific setup
+
+ifneq ($(filter $(OPENJDK_TARGET_OS), linux macosx windows), )
+  JVM_PRECOMPILED_HEADER := $(HOTSPOT_TOPDIR)/src/share/vm/precompiled/precompiled.hpp
+endif
+
+ifneq ($(filter $(OPENJDK_TARGET_OS), macosx aix solaris), )
+  # On macosx, aix and solaris we have to link with the C++ compiler
+  JVM_TOOLCHAIN := TOOLCHAIN_LINK_CXX
+else
+  JVM_TOOLCHAIN := TOOLCHAIN_DEFAULT
+endif
+
+ifeq ($(OPENJDK_TARGET_CPU), x86)
+  JVM_EXCLUDE_PATTERNS += x86_64
+else ifeq ($(OPENJDK_TARGET_CPU), x86_64)
+  JVM_EXCLUDE_PATTERNS += x86_32
+endif
+
+# Inline assembly for solaris
+ifeq ($(OPENJDK_TARGET_OS), solaris)
+  ifeq ($(OPENJDK_TARGET_CPU), x86_64)
+    JVM_CFLAGS += $(HOTSPOT_TOPDIR)/src/os_cpu/solaris_x86/vm/solaris_x86_64.il
+  else ifeq ($(OPENJDK_TARGET_CPU), sparcv9)
+    JVM_CFLAGS += $(HOTSPOT_TOPDIR)/src/os_cpu/solaris_sparc/vm/solaris_sparc.il
+  endif
+endif
+
+ifeq ($(OPENJDK_TARGET_OS)-$(OPENJDK_TARGET_CPU), solaris-sparcv9)
+  ifeq ($(COMPILE_WITH_DEBUG_SYMBOLS), false)
+    # NOTE: In the old build, we weirdly enough set -g/-g0 always, regardless
+    # of if debug symbols were needed. Without it, compilation fails on
+    # sparc! :-(
+    JVM_CFLAGS += -g0
+  endif
+endif
+
+ifeq ($(OPENJDK_TARGET_OS), windows)
+  ifeq ($(OPENJDK_TARGET_CPU_BITS), 64)
+    RC_DESC := 64-Bit$(SPACE)
+  endif
+  JVM_RCFLAGS += -D"HS_FILEDESC=$(HOTSPOT_VM_DISTRO) $(RC_DESC)$(JVM_VARIANT) VM"
+endif
+
+ifeq ($(OPENJDK_TARGET_OS), macosx)
+  # NOTE: The old build did not strip binaries on macosx.
+  JVM_STRIP_SYMBOLS := false
+else
+  JVM_STRIP_SYMBOLS := true
+endif
+
+JVM_OPTIMIZATION ?= HIGHEST_JVM
+
+################################################################################
+# Now set up the actual compilation of the main hotspot native library
+
+$(eval $(call SetupNativeCompilation, BUILD_LIBJVM, \
+    TOOLCHAIN := $(JVM_TOOLCHAIN), \
+    LIBRARY := jvm, \
+    OUTPUT_DIR := $(JVM_OUTPUTDIR), \
+    SRC := $(JVM_SRC_DIRS), \
+    EXCLUDES := $(JVM_EXCLUDES), \
+    EXCLUDE_FILES := $(JVM_EXCLUDE_FILES), \
+    EXCLUDE_PATTERNS := $(JVM_EXCLUDE_PATTERNS), \
+    EXTRA_OBJECT_FILES := $(DTRACE_EXTRA_OBJECT_FILES), \
+    CFLAGS := $(JVM_CFLAGS), \
+    CFLAGS_DEBUG_SYMBOLS := $(JVM_CFLAGS_SYMBOLS), \
+    CXXFLAGS_DEBUG_SYMBOLS := $(JVM_CFLAGS_SYMBOLS), \
+    vm_version.cpp_CXXFLAGS := $(CFLAGS_VM_VERSION), \
+    DISABLED_WARNINGS_clang := delete-non-virtual-dtor dynamic-class-memaccess \
+        empty-body format logical-op-parentheses parentheses \
+        parentheses-equality switch tautological-compare, \
+    DISABLED_WARNINGS_xlc := 1540-0216 1540-0198 1540-1090 1540-1639 \
+        1540-1088 1500-010, \
+    ASFLAGS := $(JVM_ASFLAGS), \
+    LDFLAGS := $(JVM_LDFLAGS), \
+    LIBS := $(JVM_LIBS), \
+    OPTIMIZATION := $(JVM_OPTIMIZATION), \
+    OBJECT_DIR := $(JVM_OUTPUTDIR)/objs, \
+    MAPFILE := $(JVM_MAPFILE), \
+    USE_MAPFILE_FOR_SYMBOLS := true, \
+    STRIP_SYMBOLS := $(JVM_STRIP_SYMBOLS), \
+    EMBED_MANIFEST := true, \
+    RC_FLAGS := $(JVM_RCFLAGS), \
+    VERSIONINFO_RESOURCE := $(HOTSPOT_TOPDIR)/src/os/windows/vm/version.rc, \
+    PRECOMPILED_HEADER := $(JVM_PRECOMPILED_HEADER), \
+    PRECOMPILED_HEADER_EXCLUDE := $(JVM_PRECOMPILED_HEADER_EXCLUDE), \
+))
+
+# AIX warning explanation:
+# 1500-010  : (W) WARNING in ...: Infinite loop.  Program may not stop.
+#             There are several infinite loops in the vm, so better suppress.
+# 1540-0198 : (W) The omitted keyword "private" is assumed for base class "...".
+# 1540-0216 : (W) An expression of type .. cannot be converted to type ..
+#             In hotspot this fires for functionpointer to pointer conversions
+# 1540-1088 : (W) The exception specification is being ignored.
+#             In hotspot this is caused by throw() in declaration of new() in nmethod.hpp.
+# 1540-1090 : (I) The destructor of "..." might not be called.
+# 1540-1639 : (I) The behavior of long type bit fields has changed ...
+
+# Include mapfile generation. It relies on BUILD_LIBJVM_ALL_OBJS which is only
+# defined after the above call to BUILD_LIBJVM. Mapfile will be generated
+# after all object files are built, but before the jvm library is linked.
+include lib/JvmMapfile.gmk
+
+TARGETS += $(BUILD_LIBJVM)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/makefiles/lib/CompileLibjsig.gmk	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,106 @@
+#
+# 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
+# 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.
+#
+
+################################################################################
+# Create the libjsig.so shared library
+
+default: all
+
+include $(SPEC)
+include MakeBase.gmk
+include NativeCompilation.gmk
+
+ifneq ($(OPENJDK_TARGET_OS), windows)
+  ifeq ($(STATIC_BUILD), false)
+    LIBJSIG_STRIP_SYMBOLS := true
+    ifeq ($(OPENJDK_TARGET_OS), linux)
+      LIBJSIG_CFLAGS := -fPIC -D_GNU_SOURCE -D_REENTRANT $(EXTRA_CFLAGS)
+      LIBJSIG_LDFLAGS := $(LDFLAGS_HASH_STYLE) $(EXTRA_CFLAGS)
+      LIBJSIG_LIBS := $(LIBDL)
+
+      # NOTE: The old build compiled this library without -soname.
+      # To emulate this, we need to clear out SET_SHARED_LIBRARY_NAME.
+      SET_SHARED_LIBRARY_NAME :=
+
+      # Flags for other CPUs can be provided in EXTRA_CFLAGS
+      ifeq ($(OPENJDK_TARGET_CPU), x86_64)
+        LIBJSIG_CPU_FLAGS := -m64
+      else ifeq ($(OPENJDK_TARGET_CPU), x86)
+        LIBJSIG_CPU_FLAGS := -m32 -march=i586
+      endif
+
+    else ifeq ($(OPENJDK_TARGET_OS), solaris)
+      LIBJSIG_CFLAGS := -m64 -KPIC -mt
+      LIBJSIG_LDFLAGS := -m64 -mt -xnolib
+      LIBJSIG_LIBS := $(LIBDL)
+
+      # NOTE: The old build compiled this library without -soname.
+      # To emulate this, we need to clear out SET_SHARED_LIBRARY_NAME.
+      SET_SHARED_LIBRARY_NAME :=
+
+    else ifeq ($(OPENJDK_TARGET_OS), aix)
+      LIBJSIG_CFLAGS := -q64 -D_GNU_SOURCE -D_REENTRANT -qpic=large
+      LIBJSIG_LDFLAGS := -b64 -bexpall -G -bnoentry -qmkshrobj -brtl -bnolibpath -bernotok
+      LIBJSIG_LIBS := $(LIBDL)
+
+      # NOTE: The old build compiled this library without -soname.
+      # To emulate this, we need to clear out SET_SHARED_LIBRARY_NAME.
+      SET_SHARED_LIBRARY_NAME :=
+
+    else ifeq ($(OPENJDK_TARGET_OS), macosx)
+      LIBJSIG_CFLAGS := -m64 -D_GNU_SOURCE -pthread -mno-omit-leaf-frame-pointer -mstack-alignment=16 -fPIC
+      LIBJSIG_LDFLAGS := $(LDFLAGS_HASH_STYLE)
+      # NOTE: This lib is not stripped on macosx in old build. Looks like a mistake.
+      LIBJSIG_STRIP_SYMBOLS := false
+    else
+      $(error Unknown target OS $(OPENJDK_TARGET_OS) in CompileLibjsig.gmk)
+    endif
+
+    LIBJSIG_SRC_FILE := $(HOTSPOT_TOPDIR)/src/os/$(HOTSPOT_TARGET_OS)/vm/jsig.c
+    LIBJSIG_MAPFILE := $(wildcard $(HOTSPOT_TOPDIR)/makefiles/mapfiles/libjsig/mapfile-vers-$(OPENJDK_TARGET_OS))
+    LIBJSIG_OUTPUTDIR := $(HOTSPOT_OUTPUTDIR)/libjsig
+
+    LIBJSIG_LDFLAGS += $(SHARED_LIBRARY_FLAGS)
+
+    $(eval $(call SetupNativeCompilation, BUILD_LIBJSIG, \
+        LIBRARY := jsig, \
+        EXTRA_FILES := $(LIBJSIG_SRC_FILE), \
+        OUTPUT_DIR := $(LIBJSIG_OUTPUTDIR), \
+        LANG := C, \
+        CFLAGS := $(LIBJSIG_CFLAGS) $(LIBJSIG_CPU_FLAGS), \
+        LDFLAGS := $(LIBJSIG_LDFLAGS) $(LIBJSIG_CPU_FLAGS), \
+        LIBS := $(LIBJSIG_LIBS), \
+        MAPFILE := $(LIBJSIG_MAPFILE), \
+        OBJECT_DIR := $(LIBJSIG_OUTPUTDIR)/objs, \
+        STRIP_SYMBOLS := $(LIBJSIG_STRIP_SYMBOLS), \
+    ))
+
+    TARGETS += $(BUILD_LIBJSIG)
+  endif
+endif
+
+all: $(TARGETS)
+
+.PHONY: all
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/makefiles/lib/CompileLibraries.gmk	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,42 @@
+#
+# 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
+# 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.
+#
+
+default: all
+
+include $(SPEC)
+include MakeBase.gmk
+include NativeCompilation.gmk
+
+include HotspotCommon.gmk
+
+# The dtrace setup must be done both before and after CompileJvm.gmk, due to
+# intricate dependencies.
+include lib/CompileDtracePreJvm.gmk
+include lib/CompileJvm.gmk
+include lib/CompileDtracePostJvm.gmk
+
+all: $(TARGETS)
+
+.PHONY: all
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/makefiles/lib/JvmFeatures.gmk	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,144 @@
+#
+# 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
+# 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.
+#
+
+$(eval $(call IncludeCustomExtension, hotspot, lib/JvmFeatures.gmk))
+
+################################################################################
+# Setup CFLAGS and EXCLUDES for the libjvm compilation, depending on which
+# jvm features are selected for this jvm variant.
+
+ifeq ($(call check-jvm-feature, compiler1), true)
+  JVM_CFLAGS_FEATURES += -DCOMPILER1
+else
+  JVM_EXCLUDE_PATTERNS += c1_
+endif
+
+ifeq ($(call check-jvm-feature, compiler2), true)
+  JVM_CFLAGS_FEATURES += -DCOMPILER2
+  JVM_SRC_DIRS += $(JVM_VARIANT_OUTPUTDIR)/gensrc/adfiles
+else
+  JVM_EXCLUDES += opto libadt
+  JVM_EXCLUDE_FILES += bcEscapeAnalyzer.cpp ciTypeFlow.cpp
+  JVM_EXCLUDE_PATTERNS += c2_ runtime_
+endif
+
+ifeq ($(call check-jvm-feature, zero), true)
+  JVM_CFLAGS_FEATURES += -DZERO -DCC_INTERP -DZERO_LIBARCH='"$(OPENJDK_TARGET_CPU_LEGACY_LIB)"' $(LIBFFI_CFLAGS)
+  JVM_LIBS_FEATURES += $(LIBFFI_LIBS)
+endif
+
+ifeq ($(call check-jvm-feature, shark), true)
+  JVM_CFLAGS_FEATURES += -DSHARK $(LLVM_CFLAGS)
+  JVM_LDFLAGS_FEATURES += $(LLVM_LDFLAGS)
+  JVM_LIBS_FEATURES += $(LLVM_LIBS)
+else
+  JVM_EXCLUDES += shark
+endif
+
+ifeq ($(call check-jvm-feature, minimal), true)
+  JVM_CFLAGS_FEATURES += -DMINIMAL_JVM -DVMTYPE=\"Minimal\"
+endif
+
+ifeq ($(call check-jvm-feature, dtrace), true)
+  JVM_CFLAGS_FEATURES += -DDTRACE_ENABLED
+endif
+
+ifeq ($(call check-jvm-feature, static-build), true)
+  JVM_CFLAGS_FEATURES += -DSTATIC_BUILD=1
+endif
+
+ifneq ($(call check-jvm-feature, jvmti), true)
+  JVM_CFLAGS_FEATURES += -DINCLUDE_JVMTI=0
+  JVM_EXCLUDE_FILES += jvmtiGetLoadedClasses.cpp jvmtiThreadState.cpp jvmtiExtensions.cpp \
+      jvmtiImpl.cpp jvmtiManageCapabilities.cpp jvmtiRawMonitor.cpp jvmtiUtil.cpp jvmtiTrace.cpp \
+      jvmtiCodeBlobEvents.cpp jvmtiEnv.cpp jvmtiRedefineClasses.cpp jvmtiEnvBase.cpp jvmtiEnvThreadState.cpp \
+      jvmtiTagMap.cpp jvmtiEventController.cpp evmCompat.cpp jvmtiEnter.xsl jvmtiExport.cpp \
+      jvmtiClassFileReconstituter.cpp
+endif
+
+ifneq ($(call check-jvm-feature, jvmci), true)
+  JVM_CFLAGS_FEATURES += -DINCLUDE_JVMCI=0
+  JVM_EXCLUDES += jvmci
+  JVM_EXCLUDE_FILES += jvmciCodeInstaller_$(HOTSPOT_TARGET_CPU_ARCH).cpp
+endif
+
+ifneq ($(call check-jvm-feature, fprof), true)
+  JVM_CFLAGS_FEATURES += -DINCLUDE_FPROF=0
+  JVM_EXCLUDE_FILES += fprofiler.cpp
+endif
+
+ifneq ($(call check-jvm-feature, vm-structs), true)
+  JVM_CFLAGS_FEATURES += -DINCLUDE_VM_STRUCTS=0
+  JVM_EXCLUDE_FILES += vmStructs.cpp
+endif
+
+ifneq ($(call check-jvm-feature, jni-check), true)
+  JVM_CFLAGS_FEATURES += -DINCLUDE_JNI_CHECK=0
+  JVM_EXCLUDE_FILES += jniCheck.cpp
+endif
+
+ifneq ($(call check-jvm-feature, services), true)
+  JVM_CFLAGS_FEATURES += -DINCLUDE_SERVICES=0
+  JVM_EXCLUDE_FILES += heapDumper.cpp heapInspection.cpp \
+      attachListener_$(HOTSPOT_TARGET_OS).cpp attachListener.cpp
+endif
+
+ifneq ($(call check-jvm-feature, management), true)
+  JVM_CFLAGS_FEATURES += -DINCLUDE_MANAGEMENT=0
+endif
+
+ifneq ($(call check-jvm-feature, cds), true)
+  JVM_CFLAGS_FEATURES += -DINCLUDE_CDS=0
+  JVM_EXCLUDE_FILES += \
+      classListParser.cpp \
+      classLoaderExt.cpp \
+      filemap.cpp \
+      metaspaceShared.cpp \
+      metaspaceShared_$(HOTSPOT_TARGET_CPU).cpp \
+      metaspaceShared_$(HOTSPOT_TARGET_CPU_ARCH).cpp \
+      sharedClassUtil.cpp \
+      sharedPathsMiscInfo.cpp \
+      systemDictionaryShared.cpp \
+      #
+endif
+
+ifneq ($(call check-jvm-feature, all-gcs), true)
+  JVM_CFLAGS_FEATURES += -DINCLUDE_ALL_GCS=0
+  JVM_EXCLUDE_PATTERNS += \
+      cms/ g1/ parallel/
+  JVM_EXCLUDE_FILES += \
+      concurrentGCThread.cpp \
+      plab.cpp
+  JVM_EXCLUDE_FILES += \
+      g1MemoryPool.cpp \
+      psMemoryPool.cpp
+endif
+
+ifneq ($(call check-jvm-feature, nmt), true)
+  JVM_CFLAGS_FEATURES += -DINCLUDE_NMT=0
+  JVM_EXCLUDE_FILES += \
+      memBaseline.cpp memReporter.cpp mallocTracker.cpp virtualMemoryTracker.cpp nmtCommon.cpp \
+      memTracker.cpp nmtDCmd.cpp mallocSiteTable.cpp
+endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/makefiles/lib/JvmMapfile.gmk	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,172 @@
+#
+# 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
+# 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.
+#
+
+$(eval $(call IncludeCustomExtension, hotspot, lib/JvmMapfile.gmk))
+
+################################################################################
+# Combine a list of static symbols
+
+ifneq ($(OPENJDK_TARGET_OS)-$(OPENJDK_TARGET_CPU), windows-x86_64)
+  # On Windows x86_64, we should not have any symbols at all, since that
+  # results in duplicate warnings from the linker (JDK-8043491).
+  SYMBOLS_SRC += $(HOTSPOT_TOPDIR)/makefiles/symbols/symbols-shared
+endif
+
+ifeq ($(OPENJDK_TARGET_OS_TYPE), unix)
+  SYMBOLS_SRC += $(HOTSPOT_TOPDIR)/makefiles/symbols/symbols-unix
+endif
+
+ifneq ($(wildcard $(HOTSPOT_TOPDIR)/makefiles/symbols/symbols-$(OPENJDK_TARGET_OS)), )
+  SYMBOLS_SRC += $(HOTSPOT_TOPDIR)/makefiles/symbols/symbols-$(OPENJDK_TARGET_OS)
+endif
+
+ifneq ($(findstring debug, $(DEBUG_LEVEL)), )
+  ifneq ($(wildcard $(HOTSPOT_TOPDIR)/makefiles/symbols/symbols-$(OPENJDK_TARGET_OS)-debug), )
+    SYMBOLS_SRC += $(HOTSPOT_TOPDIR)/makefiles/symbols/symbols-$(OPENJDK_TARGET_OS)-debug
+  endif
+endif
+
+ifeq ($(OPENJDK_TARGET_OS), solaris)
+  ifeq ($(call check-jvm-feature, dtrace), true)
+    # Additional mapfiles that are only used when dtrace is enabled
+    ifeq ($(call check-jvm-feature, compiler2), true)
+      # This also covers the case of compiler1+compiler2.
+      SYMBOLS_SRC += $(HOTSPOT_TOPDIR)/makefiles/symbols/symbols-solaris-dtrace-compiler2
+    else ifeq ($(call check-jvm-feature, compiler1), true)
+      SYMBOLS_SRC += $(HOTSPOT_TOPDIR)/makefiles/symbols/symbols-solaris-dtrace-compiler1
+    endif
+  endif
+endif
+
+################################################################################
+# Create a dynamic list of symbols from the built object files. This is highly
+# platform dependent.
+
+ifeq ($(OPENJDK_TARGET_OS), linux)
+  DUMP_SYMBOLS_CMD := $(NM) --defined-only *.o
+  ifneq ($(FILTER_SYMBOLS_PATTERN), )
+    FILTER_SYMBOLS_PATTERN := $(FILTER_SYMBOLS_PATTERN)|
+  endif
+  FILTER_SYMBOLS_PATTERN := $(FILTER_SYMBOLS_PATTERN)^_ZTV|^gHotSpotVM|^UseSharedSpaces$$
+  FILTER_SYMBOLS_PATTERN := $(FILTER_SYMBOLS_PATTERN)|^_ZN9Arguments17SharedArchivePathE$$
+  FILTER_SYMBOLS_AWK_SCRIPT := \
+      '{ \
+        if ($$3 ~ /$(FILTER_SYMBOLS_PATTERN)/) print $$3; \
+      }'
+
+else ifeq ($(OPENJDK_TARGET_OS), solaris)
+  DUMP_SYMBOLS_CMD := $(NM) -p *.o
+  ifneq ($(FILTER_SYMBOLS_PATTERN), )
+    FILTER_SYMBOLS_PATTERN := $(FILTER_SYMBOLS_PATTERN)|
+  endif
+  FILTER_SYMBOLS_PATTERN := $(FILTER_SYMBOLS_PATTERN)^__1c.*__vtbl_$$|^gHotSpotVM
+  FILTER_SYMBOLS_PATTERN := $(FILTER_SYMBOLS_PATTERN)|^UseSharedSpaces$$
+  FILTER_SYMBOLS_PATTERN := $(FILTER_SYMBOLS_PATTERN)|^__1cJArgumentsRSharedArchivePath_$$
+  FILTER_SYMBOLS_AWK_SCRIPT := \
+      '{ \
+        if ($$2 == "U") next; \
+        if ($$3 ~ /$(FILTER_SYMBOLS_PATTERN)/) print $$3; \
+      }'
+
+else ifeq ($(OPENJDK_TARGET_OS), macosx)
+  # nm on macosx prints out "warning: nm: no name list" to stderr for
+  # files without symbols. Hide this, even at the expense of hiding real errors.
+  DUMP_SYMBOLS_CMD := $(NM) -Uj *.o 2> /dev/null
+  ifneq ($(FILTER_SYMBOLS_PATTERN), )
+    FILTER_SYMBOLS_PATTERN := $(FILTER_SYMBOLS_PATTERN)|
+  endif
+  FILTER_SYMBOLS_PATTERN := $(FILTER_SYMBOLS_PATTERN)^_ZTV|^gHotSpotVM
+  FILTER_SYMBOLS_AWK_SCRIPT := \
+      '{ \
+        if ($$3 ~ /$(FILTER_SYMBOLS_PATTERN)/) print $$3; \
+      }'
+
+# NOTE: The script is from the old build. It is broken and finds no symbols.
+# The script below might be what was intended, but it failes to link with tons
+# of 'cannot export hidden symbol vtable for X'.
+#  '{ if ($$1 ~ /^__ZTV/ || $$1 ~ /^_gHotSpotVM/) print substr($$1, 2) }'
+else ifeq ($(OPENJDK_TARGET_OS), aix)
+  # NOTE: The old build had the solution below. This should to be fixed in
+  # configure instead.
+
+  # On AIX we have to prevent that we pick up the 'nm' version from the GNU binutils
+  # which may be installed under /opt/freeware/bin. So better use an absolute path here!
+  # NM=/usr/bin/nm
+
+  DUMP_SYMBOLS_CMD := $(NM) -X64 -B -C *.o
+  FILTER_SYMBOLS_AWK_SCRIPT := \
+      '{ \
+        if (($$2="d" || $$2="D") && ($$3 ~ /^__vft/ || $$3 ~ /^gHotSpotVM/)) print $$3; \
+        if ($$3 ~ /^UseSharedSpaces$$/) print $$3; \
+        if ($$3 ~ /^SharedArchivePath__9Arguments$$/) print $$3; \
+       }'
+
+else ifeq ($(OPENJDK_TARGET_OS), windows)
+  DUMP_SYMBOLS_CMD := $(DUMPBIN) -symbols *.obj
+  FILTER_SYMBOLS_AWK_SCRIPT := \
+      '{ \
+        if ($$7 ~ /??_7.*@@6B@/ && $$7 !~ /type_info/) print $$7; \
+      }'
+
+else
+  $(error Unknown target OS $(OPENJDK_TARGET_OS) in JvmMapfile.gmk)
+endif
+
+# A more correct solution would be to send BUILD_LIBJVM_ALL_OBJS instead of
+# cd && *.o, but this will result in very long command lines, which is
+# problematic on some platforms.
+$(JVM_OUTPUTDIR)/symbols-objects: $(BUILD_LIBJVM_ALL_OBJS)
+	$(call LogInfo, Generating symbol list from object files)
+	$(CD) $(JVM_OUTPUTDIR)/objs && \
+	  $(DUMP_SYMBOLS_CMD) | $(NAWK) $(FILTER_SYMBOLS_AWK_SCRIPT) | $(SORT) -u > $@
+
+SYMBOLS_SRC += $(JVM_OUTPUTDIR)/symbols-objects
+
+################################################################################
+# Now concatenate all symbol lists into a single file and remove comments.
+
+$(JVM_OUTPUTDIR)/symbols: $(SYMBOLS_SRC)
+	$(SED) -e '/^#/d' $^ > $@
+
+################################################################################
+# Finally convert the symbol list into a platform-specific mapfile
+
+$(JVM_MAPFILE): $(JVM_OUTPUTDIR)/symbols
+	$(call LogInfo, Creating mapfile)
+	$(RM) $@
+        ifeq ($(OPENJDK_TARGET_OS), macosx)
+          # On macosx, we need to add a leading underscore
+	  $(AWK) '{ if ($$0 ~ ".") { print "  _" $$0 } }'  < $^ > $@.tmp
+        else ifeq ($(OPENJDK_TARGET_OS), windows)
+          # On windows, add an 'EXPORTS' header
+	  $(ECHO) "EXPORTS" > $@.tmp
+	  $(AWK) '{ if ($$0 ~ ".") { print "  " $$0 } }'  < $^ >> $@.tmp
+        else
+          # Assume standard linker script
+	  $(PRINTF) "SUNWprivate_1.1 { \n  global: \n" > $@.tmp
+	  $(AWK) '{ if ($$0 ~ ".") { print "    " $$0 ";" } }' < $^ >> $@.tmp
+	  $(PRINTF) "  local: \n    *; \n }; \n" >> $@.tmp
+        endif
+	$(MV) $@.tmp $@
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/makefiles/lib/JvmOverrideFiles.gmk	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,168 @@
+#
+# 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
+# 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.
+#
+
+$(eval $(call IncludeCustomExtension, hotspot, lib/JvmOverrideFiles.gmk))
+
+################################################################################
+# This file contains explicit overrides of CFLAGS and/or precompiled header
+# status for individual files on specific platforms.
+
+ifeq ($(TOOLCHAIN_TYPE), gcc)
+  BUILD_LIBJVM_vmStructs.cpp_CXXFLAGS := -fno-var-tracking-assignments -O0
+endif
+
+ifeq ($(OPENJDK_TARGET_OS), linux)
+  BUILD_LIBJVM_ostream.cpp_CXXFLAGS := -D_FILE_OFFSET_BITS=64
+
+  ifeq ($(OPENJDK_TARGET_CPU_ARCH), x86)
+    BUILD_LIBJVM_sharedRuntimeTrig.cpp_CXXFLAGS := -DNO_PCH $(CXX_O_FLAG_NONE)
+    BUILD_LIBJVM_sharedRuntimeTrans.cpp_CXXFLAGS := -DNO_PCH $(CXX_O_FLAG_NONE)
+
+    ifeq ($(TOOLCHAIN_TYPE), clang)
+      JVM_PRECOMPILED_HEADER_EXCLUDE := \
+          sharedRuntimeTrig.cpp \
+          sharedRuntimeTrans.cpp \
+          #
+    endif
+  endif
+
+  ifeq ($(OPENJDK_TARGET_CPU), x86)
+    # Performance measurements show that by compiling GC related code, we could
+    # significantly reduce the GC pause time on 32 bit Linux/Unix platforms by
+    # compiling without the PIC flag (-fPIC on linux).
+    # See 6454213 for more details.
+    ALL_SRC := $(filter %.cpp, $(call CacheFind, $(HOTSPOT_TOPDIR)/src/share/vm))
+    NONPIC_FILTER := $(addsuffix %, $(addprefix $(HOTSPOT_TOPDIR)/src/share/vm/, \
+        memory oops gc))
+    # Due to what looks like a bug in the old build implementation of this, add a
+    # couple of more files that were accidentally matched as substrings of GC related
+    # files.
+    NONPIC_SRC := $(filter $(NONPIC_FILTER), $(ALL_SRC)) globals.cpp location.cpp
+    # Declare variables for each source file that needs the pic flag like this:
+    # BUILD_JVM_<srcfile>_CXXFLAGS := -fno-PIC
+    # This will get implicitly picked up by SetupNativeCompilation below.
+    $(foreach s, $(NONPIC_SRC), $(eval BUILD_LIBJVM_$(notdir $s)_CXXFLAGS := -fno-PIC))
+  endif
+
+else ifeq ($(OPENJDK_TARGET_OS), solaris)
+  ifneq ($(DEBUG_LEVEL), slowdebug)
+    # Workaround for a bug in dtrace.  If ciEnv::post_compiled_method_load_event()
+    # is inlined, the resulting dtrace object file needs a reference to this
+    # function, whose symbol name is too long for dtrace.  So disable inlining
+    # for this method for now. (fix this when dtrace bug 6258412 is fixed)
+    BUILD_LIBJVM_ciEnv.cpp_CXXFLAGS := \
+        -xinline=no%__1cFciEnvbFpost_compiled_method_load_event6MpnHnmethod__v_
+    # dtrace cannot handle tail call optimization (6672627, 6693876)
+    BUILD_LIBJVM_jni.cpp_CXXFLAGS := -Qoption ube -O~yz
+    BUILD_LIBJVM_stubGenerator_$(HOTSPOT_TARGET_CPU).cpp_CXXFLAGS := -xspace
+
+    ifeq ($(OPENJDK_TARGET_CPU), x86_64)
+      # Temporary until SS10 C++ compiler is fixed
+      BUILD_LIBJVM_generateOptoStub.cpp_CXXFLAGS := -xO2
+      # Temporary util SS12u1 C++ compiler is fixed
+      BUILD_LIBJVM_c1_LinearScan.cpp_CXXFLAGS := -xO2
+    endif
+  endif
+
+  # Need extra inlining to get oop_ps_push_contents functions to perform well enough.
+  ifeq ($(DEBUG_LEVEL),release)
+    BUILD_LIBJVM_psPromotionManager.cpp_CXXFLAGS := -W2,-Ainline:inc=1000
+  endif
+
+  ifeq ($(DEBUG_LEVEL), fastdebug)
+    # this hangs in iropt now (7113504)
+    BUILD_LIBJVM_compileBroker.cpp_CXXFLAGS := -xO2
+
+    # Frame size > 100k  if we allow inlining via -g0!
+    BUILD_LIBJVM_bytecodeInterpreter.cpp_CXXFLAGS := +d
+    BUILD_LIBJVM_bytecodeInterpreterWithChecks.cpp_CXXFLAGS := +d
+
+    ifeq ($(OPENJDK_TARGET_CPU_ARCH), x86)
+      # ube explodes on x86
+      BUILD_LIBJVM_bytecodeInterpreter.cpp_CXXFLAGS += -xO1
+      BUILD_LIBJVM_bytecodeInterpreterWithChecks.cpp_CXXFLAGS += -xO1
+    endif
+
+  endif
+
+else ifeq ($(OPENJDK_TARGET_OS), macosx)
+  # The copied fdlibm routines in these files must not be optimized
+  BUILD_LIBJVM_sharedRuntimeTrans.cpp_CXXFLAGS := $(CXX_O_FLAG_NONE)
+  BUILD_LIBJVM_sharedRuntimeTrig.cpp_CXXFLAGS := $(CXX_O_FLAG_NONE)
+  ifeq ($(TOOLCHAIN_TYPE), clang)
+    # NOTE: The old build tested clang version to make sure this workaround
+    # for the clang bug was still needed.
+    BUILD_LIBJVM_loopTransform.cpp_CXXFLAGS := $(CXX_O_FLAG_NONE)
+    ifneq ($(DEBUG_LEVEL), slowdebug)
+      BUILD_LIBJVM_unsafe.cpp_CXXFLAGS := -O1
+    endif
+
+    # The following files are compiled at various optimization
+    # levels due to optimization issues encountered at the
+    # default level. The Clang compiler issues a compile
+    # time error if there is an optimization level specification
+    # skew between the PCH file and the C++ file.  Especially if the
+    # PCH file is compiled at a higher optimization level than
+    # the C++ file.  One solution might be to prepare extra optimization
+    # level specific PCH files for the opt build and use them here, but
+    # it's probably not worth the effort as long as only a few files
+    # need this special handling.
+    JVM_PRECOMPILED_HEADER_EXCLUDE := \
+        sharedRuntimeTrig.cpp \
+        sharedRuntimeTrans.cpp \
+        loopTransform.cpp \
+        unsafe.cpp \
+        jvmciCompilerToVM.cpp \
+        #
+  endif
+
+else ifeq ($(OPENJDK_TARGET_OS), aix)
+  BUILD_LIBJVM_synchronizer.cpp_CXXFLAGS := -qnoinline
+  BUILD_LIBJVM_sharedRuntimeTrans.cpp_CXXFLAGS := $(CXX_O_FLAG_NONE)
+  # Disable aggressive optimizations for functions in sharedRuntimeTrig.cpp
+  # and sharedRuntimeTrans.cpp on ppc64.
+  # -qstrict turns off the following optimizations:
+  #   * Performing code motion and scheduling on computations such as loads
+  #     and floating-point computations that may trigger an exception.
+  #   * Relaxing conformance to IEEE rules.
+  #   * Reassociating floating-point expressions.
+  # When using '-qstrict' there still remains one problem
+  # in javasoft.sqe.tests.api.java.lang.Math.sin5Tests when run in compile-all
+  # mode, so don't optimize sharedRuntimeTrig.cpp at all.
+  BUILD_LIBJVM_sharedRuntimeTrig.cpp_CXXFLAGS := $(CXX_O_FLAG_NONE)
+
+  # Disable ELF decoder on AIX (AIX uses XCOFF).
+  JVM_EXCLUDE_PATTERNS += elf
+
+else ifeq ($(OPENJDK_TARGET_OS), windows)
+  JVM_PRECOMPILED_HEADER_EXCLUDE := \
+      bytecodeInterpreter.cpp \
+      bytecodeInterpreterWithChecks.cpp \
+      opcodes.cpp \
+      os_windows.cpp \
+      os_windows_x86.cpp \
+      osThread_windows.cpp \
+      #
+endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/makefiles/mapfiles/libjsig/mapfile-vers-solaris	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,38 @@
+#
+# Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# 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.
+#  
+#
+
+# Define library interface.
+
+SUNWprivate_1.1 {
+        global:
+            JVM_begin_signal_setting;
+            JVM_end_signal_setting;
+            JVM_get_libjsig_version;
+            JVM_get_signal_action;
+            sigaction;
+            signal;
+            sigset;
+        local:
+                *;
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/makefiles/mapfiles/libjvm_db/mapfile-vers	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,38 @@
+#
+
+#
+# Copyright (c) 2005, 2008, 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.
+#  
+#
+
+# Define library interface.
+
+SUNWprivate_1.1 {
+        global:
+            Jagent_create;
+	    Jagent_destroy;
+	    Jframe_iter;
+	    #Jget_vframe;
+	    #Jlookup_by_regs;
+        local:
+                *;
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/makefiles/mapfiles/libjvm_dtrace/mapfile-vers	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,37 @@
+#
+
+#
+# Copyright (c) 2006, 2008, 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.
+#  
+#
+
+# Define library interface for JVM-DTrace interface
+
+SUNWprivate_1.1 {
+        global:
+            jvm_attach;
+            jvm_get_last_error;
+            jvm_enable_dtprobes;
+            jvm_detach;
+        local:
+                *;
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/makefiles/symbols/symbols-aix	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,27 @@
+#
+# 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.
+#
+
+JVM_handle_linux_signal
+numa_error
+numa_warn
+sysThreadAvailableStackWithSlack
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/makefiles/symbols/symbols-aix-debug	Wed Jul 05 21:37:42 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.
+#
+
+JVM_AccessVMBooleanFlag
+JVM_AccessVMIntFlag
+JVM_VMBreakPoint
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/makefiles/symbols/symbols-linux	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,27 @@
+#
+# 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.
+#
+
+JVM_handle_linux_signal
+numa_error
+numa_warn
+sysThreadAvailableStackWithSlack
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/makefiles/symbols/symbols-macosx	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,24 @@
+#
+# 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.
+#
+
+JVM_handle_bsd_signal
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/makefiles/symbols/symbols-shared	Wed Jul 05 21:37:42 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.
+#
+
+AsyncGetCallTrace
+jio_fprintf
+jio_printf
+jio_snprintf
+jio_vfprintf
+jio_vsnprintf
+JNI_CreateJavaVM
+JNI_GetCreatedJavaVMs
+JNI_GetDefaultJavaVMInitArgs
+JVM_FindClassFromBootLoader
+JVM_GetVersionInfo
+JVM_InitAgentProperties
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/makefiles/symbols/symbols-solaris	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,25 @@
+#
+# 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.
+#
+
+JVM_handle_solaris_signal
+sysThreadAvailableStackWithSlack
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/makefiles/symbols/symbols-solaris-dtrace-compiler1	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,34 @@
+#
+# 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.
+#
+
+__1cGMethodG__vtbl_
+__1cHnmethodG__vtbl_
+__1cICodeBlobG__vtbl_
+__1cIUniverseO_collectedHeap_
+__1cJCodeCacheG_heaps_
+__1cKBufferBlobG__vtbl_
+__1cLRuntimeStubG__vtbl_
+__1cNSafepointBlobG__vtbl_
+__1cSDeoptimizationBlobG__vtbl_
+
+__JvmOffsets
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/makefiles/symbols/symbols-solaris-dtrace-compiler2	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,36 @@
+#
+# 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.
+#
+
+__1cGMethodG__vtbl_
+__1cHnmethodG__vtbl_
+__1cICodeBlobG__vtbl_
+__1cIUniverseO_collectedHeap_
+__1cJCodeCacheG_heaps_
+__1cKBufferBlobG__vtbl_
+__1cLRuntimeStubG__vtbl_
+__1cNSafepointBlobG__vtbl_
+__1cSDeoptimizationBlobG__vtbl_
+__1cNExceptionBlobG__vtbl_
+__1cQUncommonTrapBlobG__vtbl_
+
+__JvmOffsets
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/makefiles/symbols/symbols-unix	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,194 @@
+#
+# 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.
+#
+
+JVM_ActiveProcessorCount
+JVM_ArrayCopy
+JVM_AssertionStatusDirectives
+JVM_CallStackWalk
+JVM_ClassDepth
+JVM_ClassLoaderDepth
+JVM_Clone
+JVM_ConstantPoolGetClassAt
+JVM_ConstantPoolGetClassAtIfLoaded
+JVM_ConstantPoolGetClassRefIndexAt
+JVM_ConstantPoolGetDoubleAt
+JVM_ConstantPoolGetFieldAt
+JVM_ConstantPoolGetFieldAtIfLoaded
+JVM_ConstantPoolGetFloatAt
+JVM_ConstantPoolGetIntAt
+JVM_ConstantPoolGetLongAt
+JVM_ConstantPoolGetMemberRefInfoAt
+JVM_ConstantPoolGetMethodAt
+JVM_ConstantPoolGetMethodAtIfLoaded
+JVM_ConstantPoolGetNameAndTypeRefIndexAt
+JVM_ConstantPoolGetNameAndTypeRefInfoAt
+JVM_ConstantPoolGetSize
+JVM_ConstantPoolGetStringAt
+JVM_ConstantPoolGetTagAt
+JVM_ConstantPoolGetUTF8At
+JVM_CountStackFrames
+JVM_CurrentClassLoader
+JVM_CurrentLoadedClass
+JVM_CurrentThread
+JVM_CurrentTimeMillis
+JVM_DefineClass
+JVM_DefineClassWithSource
+JVM_DesiredAssertionStatus
+JVM_DoPrivileged
+JVM_DumpAllStacks
+JVM_DumpThreads
+JVM_FillInStackTrace
+JVM_FindClassFromCaller
+JVM_FindClassFromClass
+JVM_FindLibraryEntry
+JVM_FindLoadedClass
+JVM_FindPrimitiveClass
+JVM_FindSignal
+JVM_FreeMemory
+JVM_GC
+JVM_GetAllThreads
+JVM_GetArrayElement
+JVM_GetArrayLength
+JVM_GetCallerClass
+JVM_GetClassAccessFlags
+JVM_GetClassAnnotations
+JVM_GetClassConstantPool
+JVM_GetClassContext
+JVM_GetClassCPEntriesCount
+JVM_GetClassCPTypes
+JVM_GetClassDeclaredConstructors
+JVM_GetClassDeclaredFields
+JVM_GetClassDeclaredMethods
+JVM_GetClassFieldsCount
+JVM_GetClassInterfaces
+JVM_GetClassMethodsCount
+JVM_GetClassModifiers
+JVM_GetClassName
+JVM_GetClassNameUTF
+JVM_GetClassSignature
+JVM_GetClassSigners
+JVM_GetClassTypeAnnotations
+JVM_GetCPClassNameUTF
+JVM_GetCPFieldClassNameUTF
+JVM_GetCPFieldModifiers
+JVM_GetCPFieldNameUTF
+JVM_GetCPFieldSignatureUTF
+JVM_GetCPMethodClassNameUTF
+JVM_GetCPMethodModifiers
+JVM_GetCPMethodNameUTF
+JVM_GetCPMethodSignatureUTF
+JVM_GetDeclaredClasses
+JVM_GetDeclaringClass
+JVM_GetEnclosingMethodInfo
+JVM_GetFieldIxModifiers
+JVM_GetFieldTypeAnnotations
+JVM_GetInheritedAccessControlContext
+JVM_GetInterfaceVersion
+JVM_GetManagement
+JVM_GetMethodIxArgsSize
+JVM_GetMethodIxByteCode
+JVM_GetMethodIxByteCodeLength
+JVM_GetMethodIxExceptionIndexes
+JVM_GetMethodIxExceptionsCount
+JVM_GetMethodIxExceptionTableEntry
+JVM_GetMethodIxExceptionTableLength
+JVM_GetMethodIxLocalsCount
+JVM_GetMethodIxMaxStack
+JVM_GetMethodIxModifiers
+JVM_GetMethodIxNameUTF
+JVM_GetMethodIxSignatureUTF
+JVM_GetMethodParameters
+JVM_GetMethodTypeAnnotations
+JVM_GetNanoTimeAdjustment
+JVM_GetPrimitiveArrayElement
+JVM_GetProtectionDomain
+JVM_GetSimpleBinaryName
+JVM_GetStackAccessControlContext
+JVM_GetStackTraceElements
+JVM_GetSystemPackage
+JVM_GetSystemPackages
+JVM_GetTemporaryDirectory
+JVM_GetVmArguments
+JVM_Halt
+JVM_HoldsLock
+JVM_IHashCode
+JVM_InitProperties
+JVM_InternString
+JVM_Interrupt
+JVM_InvokeMethod
+JVM_IsArrayClass
+JVM_IsConstructorIx
+JVM_IsInterface
+JVM_IsInterrupted
+JVM_IsPrimitiveClass
+JVM_IsSameClassPackage
+JVM_IsSupportedJNIVersion
+JVM_IsThreadAlive
+JVM_IsVMGeneratedMethodIx
+JVM_LatestUserDefinedLoader
+JVM_LoadLibrary
+JVM_MaxMemory
+JVM_MaxObjectInspectionAge
+JVM_MonitorNotify
+JVM_MonitorNotifyAll
+JVM_MonitorWait
+JVM_MoreStackWalk
+JVM_NanoTime
+JVM_NativePath
+JVM_NewArray
+JVM_NewInstanceFromConstructor
+JVM_NewMultiArray
+JVM_RaiseSignal
+JVM_RawMonitorCreate
+JVM_RawMonitorDestroy
+JVM_RawMonitorEnter
+JVM_RawMonitorExit
+JVM_RegisterSignal
+JVM_ReleaseUTF
+JVM_ResumeThread
+JVM_SetArrayElement
+JVM_SetClassSigners
+JVM_SetNativeThreadName
+JVM_SetPrimitiveArrayElement
+JVM_SetThreadPriority
+JVM_Sleep
+JVM_StartThread
+JVM_StopThread
+JVM_SupportsCX8
+JVM_SuspendThread
+JVM_ToStackTraceElement
+JVM_TotalMemory
+JVM_UnloadLibrary
+JVM_Yield
+
+# Module related API's
+JVM_AddModuleExports
+JVM_AddModuleExportsToAll
+JVM_AddModuleExportsToAllUnnamed
+JVM_AddModulePackage
+JVM_AddReadsModule
+JVM_CanReadModule
+JVM_DefineModule
+JVM_IsExportedToModule
+JVM_SetBootLoaderUnnamedModule
+JVM_GetModuleByPackageName
--- a/hotspot/src/cpu/aarch64/vm/debug_aarch64.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/cpu/aarch64/vm/debug_aarch64.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -30,6 +30,5 @@
 #include "runtime/init.hpp"
 #include "runtime/os.hpp"
 #include "utilities/debug.hpp"
-#include "utilities/top.hpp"
 
 void pd_ps(frame f) {}
--- a/hotspot/src/cpu/aarch64/vm/frame_aarch64.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/cpu/aarch64/vm/frame_aarch64.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -27,7 +27,6 @@
 #define CPU_AARCH64_VM_FRAME_AARCH64_HPP
 
 #include "runtime/synchronizer.hpp"
-#include "utilities/top.hpp"
 
 // A frame represents a physical stack frame (an activation).  Frames can be
 // C or Java frames, and the Java frames can be interpreted or compiled.
--- a/hotspot/src/cpu/aarch64/vm/nativeInst_aarch64.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/cpu/aarch64/vm/nativeInst_aarch64.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -30,7 +30,6 @@
 #include "memory/allocation.hpp"
 #include "runtime/icache.hpp"
 #include "runtime/os.hpp"
-#include "utilities/top.hpp"
 
 // We have interfaces for the following instructions:
 // - NativeInstruction
--- a/hotspot/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -198,6 +198,16 @@
 bool SharedRuntime::is_wide_vector(int size) {
   return size > 8;
 }
+
+size_t SharedRuntime::trampoline_size() {
+  return 16;
+}
+
+void SharedRuntime::generate_trampoline(MacroAssembler *masm, address destination) {
+  __ mov(rscratch1, destination);
+  __ br(rscratch1);
+}
+
 // The java_calling_convention describes stack locations as ideal slots on
 // a frame with no abi restrictions. Since we must observe abi restrictions
 // (like the placement of the register window) the slots must be biased by
--- a/hotspot/src/cpu/aarch64/vm/stubGenerator_aarch64.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/cpu/aarch64/vm/stubGenerator_aarch64.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -39,7 +39,6 @@
 #include "runtime/stubCodeGenerator.hpp"
 #include "runtime/stubRoutines.hpp"
 #include "runtime/thread.inline.hpp"
-#include "utilities/top.hpp"
 #ifdef COMPILER2
 #include "opto/runtime.hpp"
 #endif
--- a/hotspot/src/cpu/ppc/vm/c1_LIRGenerator_ppc.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/cpu/ppc/vm/c1_LIRGenerator_ppc.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -360,7 +360,7 @@
     length.set_instruction(x->length());
     length.load_item();
   }
-  if (needs_store_check) {
+  if (needs_store_check || x->check_boolean()) {
     value.load_item();
   } else {
     value.load_for_store(x->elt_type());
@@ -407,7 +407,8 @@
     pre_barrier(LIR_OprFact::address(array_addr), LIR_OprFact::illegalOpr /* pre_val */,
                 true /* do_load */, false /* patch */, NULL);
   }
-  __ move(value.result(), array_addr, null_check_info);
+  LIR_Opr result = maybe_mask_boolean(x, array.result(), value.result(), null_check_info);
+  __ move(result, array_addr, null_check_info);
   if (obj_store) {
     // Precise card mark.
     post_barrier(LIR_OprFact::address(array_addr), value.result());
--- a/hotspot/src/cpu/ppc/vm/debug_ppc.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/cpu/ppc/vm/debug_ppc.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -30,6 +30,5 @@
 #include "runtime/init.hpp"
 #include "runtime/os.hpp"
 #include "utilities/debug.hpp"
-#include "utilities/top.hpp"
 
 void pd_ps(frame f) {}
--- a/hotspot/src/cpu/ppc/vm/frame_ppc.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/cpu/ppc/vm/frame_ppc.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -27,7 +27,6 @@
 #define CPU_PPC_VM_FRAME_PPC_HPP
 
 #include "runtime/synchronizer.hpp"
-#include "utilities/top.hpp"
 
   //  C frame layout on PPC-64.
   //
--- a/hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -169,6 +169,7 @@
     case ltos: ld(R17_tos, in_bytes(JvmtiThreadState::earlyret_value_offset()), RjvmtiState);
                break;
     case btos: // fall through
+    case ztos: // fall through
     case ctos: // fall through
     case stos: // fall through
     case itos: lwz(R17_tos, in_bytes(JvmtiThreadState::earlyret_value_offset()), RjvmtiState);
@@ -294,6 +295,7 @@
   switch (state) {
     case atos: push_ptr();                break;
     case btos:
+    case ztos:
     case ctos:
     case stos:
     case itos: push_i();                  break;
@@ -309,6 +311,7 @@
   switch (state) {
     case atos: pop_ptr();            break;
     case btos:
+    case ztos:
     case ctos:
     case stos:
     case itos: pop_i();              break;
@@ -749,6 +752,43 @@
   stdux(Rscratch2, R1_SP, Rscratch1); // atomically set *(SP = top_frame_sp) = **SP
 }
 
+void InterpreterMacroAssembler::narrow(Register result) {
+  Register ret_type = R11_scratch1;
+  ld(R11_scratch1, in_bytes(Method::const_offset()), R19_method);
+  lbz(ret_type, in_bytes(ConstMethod::result_type_offset()), R11_scratch1);
+
+  Label notBool, notByte, notChar, done;
+
+  // common case first
+  cmpwi(CCR0, ret_type, T_INT);
+  beq(CCR0, done);
+
+  cmpwi(CCR0, ret_type, T_BOOLEAN);
+  bne(CCR0, notBool);
+  andi(result, result, 0x1);
+  b(done);
+
+  bind(notBool);
+  cmpwi(CCR0, ret_type, T_BYTE);
+  bne(CCR0, notByte);
+  extsb(result, result);
+  b(done);
+
+  bind(notByte);
+  cmpwi(CCR0, ret_type, T_CHAR);
+  bne(CCR0, notChar);
+  andi(result, result, 0xffff);
+  b(done);
+
+  bind(notChar);
+  // cmpwi(CCR0, ret_type, T_SHORT);  // all that's left
+  // bne(CCR0, done);
+  extsh(result, result);
+
+  // Nothing to do for T_INT
+  bind(done);
+}
+
 // Remove activation.
 //
 // Unlock the receiver if this is a synchronized method.
--- a/hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -140,6 +140,8 @@
   void get_cpool_and_tags(Register Rcpool, Register Rtags);
   void is_a(Label& L);
 
+  void narrow(Register result);
+
   // Java Call Helpers
   void call_from_interpreter(Register Rtarget_method, Register Rret_addr, Register Rscratch1, Register Rscratch2);
 
--- a/hotspot/src/cpu/ppc/vm/nativeInst_ppc.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/cpu/ppc/vm/nativeInst_ppc.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -31,7 +31,6 @@
 #include "memory/allocation.hpp"
 #include "runtime/icache.hpp"
 #include "runtime/os.hpp"
-#include "utilities/top.hpp"
 
 // We have interfaces for the following instructions:
 //
--- a/hotspot/src/cpu/ppc/vm/sharedRuntime_ppc.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/cpu/ppc/vm/sharedRuntime_ppc.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -483,6 +483,18 @@
   assert(size <= 8, "%d bytes vectors are not supported", size);
   return size > 8;
 }
+
+size_t SharedRuntime::trampoline_size() {
+  return Assembler::load_const_size + 8;
+}
+
+void SharedRuntime::generate_trampoline(MacroAssembler *masm, address destination) {
+  Register Rtemp = R12;
+  __ load_const(Rtemp, destination);
+  __ mtctr(Rtemp);
+  __ bctr();
+}
+
 #ifdef COMPILER2
 static int reg2slot(VMReg r) {
   return r->reg2stack() + SharedRuntime::out_preserve_stack_slots();
--- a/hotspot/src/cpu/ppc/vm/stubGenerator_ppc.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/cpu/ppc/vm/stubGenerator_ppc.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -37,7 +37,6 @@
 #include "runtime/sharedRuntime.hpp"
 #include "runtime/stubCodeGenerator.hpp"
 #include "runtime/stubRoutines.hpp"
-#include "utilities/top.hpp"
 #include "runtime/thread.inline.hpp"
 
 #define __ _masm->
--- a/hotspot/src/cpu/ppc/vm/templateInterpreterGenerator_ppc.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/cpu/ppc/vm/templateInterpreterGenerator_ppc.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -655,6 +655,7 @@
   switch (state) {
     case ltos:
     case btos:
+    case ztos:
     case ctos:
     case stos:
     case atos:
@@ -701,6 +702,7 @@
   switch (state) {
     case ltos:
     case btos:
+    case ztos:
     case ctos:
     case stos:
     case atos:
@@ -2092,12 +2094,14 @@
   // Copied from TemplateTable::_return.
   // Restoration of lr done by remove_activation.
   switch (state) {
+    // Narrow result if state is itos but result type is smaller.
+    case itos: __ narrow(R17_tos); /* fall through */
     case ltos:
     case btos:
+    case ztos:
     case ctos:
     case stos:
-    case atos:
-    case itos: __ mr(R3_RET, R17_tos); break;
+    case atos: __ mr(R3_RET, R17_tos); break;
     case ftos:
     case dtos: __ fmr(F1_RET, F15_ftos); break;
     case vtos: // This might be a constructor. Final fields (and volatile fields on PPC64) need
@@ -2157,6 +2161,10 @@
     bname = "trace_code_btos {";
     tsize = 2;
     break;
+  case ztos:
+    bname = "trace_code_ztos {";
+    tsize = 2;
+    break;
   case ctos:
     bname = "trace_code_ctos {";
     tsize = 2;
--- a/hotspot/src/cpu/ppc/vm/templateTable_ppc_64.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/cpu/ppc/vm/templateTable_ppc_64.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -170,6 +170,7 @@
   switch (new_bc) {
     case Bytecodes::_fast_aputfield:
     case Bytecodes::_fast_bputfield:
+    case Bytecodes::_fast_zputfield:
     case Bytecodes::_fast_cputfield:
     case Bytecodes::_fast_dputfield:
     case Bytecodes::_fast_fputfield:
@@ -981,9 +982,21 @@
                  Rarray   = R12_scratch2,
                  Rscratch = R3_ARG1;
   __ pop_i(Rindex);
+  __ pop_ptr(Rarray);
   // tos: val
-  // Rarray: array ptr (popped by index_check)
-  __ index_check(Rarray, Rindex, 0, Rscratch, Rarray);
+
+  // Need to check whether array is boolean or byte
+  // since both types share the bastore bytecode.
+  __ load_klass(Rscratch, Rarray);
+  __ lwz(Rscratch, in_bytes(Klass::layout_helper_offset()), Rscratch);
+  int diffbit = exact_log2(Klass::layout_helper_boolean_diffbit());
+  __ testbitdi(CCR0, R0, Rscratch, diffbit);
+  Label L_skip;
+  __ bfalse(CCR0, L_skip);
+  __ andi(R17_tos, R17_tos, 1);  // if it is a T_BOOLEAN array, mask the stored value to 0/1
+  __ bind(L_skip);
+
+  __ index_check_without_pop(Rarray, Rindex, 0, Rscratch, Rarray);
   __ stb(R17_tos, arrayOopDesc::base_offset_in_bytes(T_BYTE), Rarray);
 }
 
@@ -2108,12 +2121,16 @@
   __ remove_activation(state, /* throw_monitor_exception */ true);
   // Restoration of lr done by remove_activation.
   switch (state) {
+    // Narrow result if state is itos but result type is smaller.
+    // Need to narrow in the return bytecode rather than in generate_return_entry
+    // since compiled code callers expect the result to already be narrowed.
+    case itos: __ narrow(R17_tos); /* fall through */
     case ltos:
     case btos:
+    case ztos:
     case ctos:
     case stos:
-    case atos:
-    case itos: __ mr(R3_RET, R17_tos); break;
+    case atos: __ mr(R3_RET, R17_tos); break;
     case ftos:
     case dtos: __ fmr(F1_RET, F15_ftos); break;
     case vtos: // This might be a constructor. Final fields (and volatile fields on PPC64) need
@@ -2519,6 +2536,21 @@
   __ dispatch_epilog(vtos, Bytecodes::length_for(bytecode()));
 
   __ align(32, 28, 28); // Align load.
+  // __ bind(Lztos); (same code as btos)
+  __ fence(); // Volatile entry point (one instruction before non-volatile_entry point).
+  assert(branch_table[ztos] == 0, "can't compute twice");
+  branch_table[ztos] = __ pc(); // non-volatile_entry point
+  __ lbzx(R17_tos, Rclass_or_obj, Roffset);
+  __ extsb(R17_tos, R17_tos);
+  __ push(ztos);
+  if (!is_static) {
+    // use btos rewriting, no truncating to t/f bit is needed for getfield.
+    patch_bytecode(Bytecodes::_fast_bgetfield, Rbc, Rscratch);
+  }
+  __ beq(CCR6, Lacquire); // Volatile?
+  __ dispatch_epilog(vtos, Bytecodes::length_for(bytecode()));
+
+  __ align(32, 28, 28); // Align load.
   // __ bind(Lctos);
   __ fence(); // Volatile entry point (one instruction before non-volatile_entry point).
   assert(branch_table[ctos] == 0, "can't compute twice");
@@ -2618,6 +2650,7 @@
         case Bytecodes::_fast_aputfield: __ push_ptr(); offs+= Interpreter::stackElementSize; break;
         case Bytecodes::_fast_iputfield: // Fall through
         case Bytecodes::_fast_bputfield: // Fall through
+        case Bytecodes::_fast_zputfield: // Fall through
         case Bytecodes::_fast_cputfield: // Fall through
         case Bytecodes::_fast_sputfield: __ push_i(); offs+=  Interpreter::stackElementSize; break;
         case Bytecodes::_fast_lputfield: __ push_l(); offs+=2*Interpreter::stackElementSize; break;
@@ -2658,6 +2691,7 @@
       case Bytecodes::_fast_aputfield: __ pop_ptr(); break;
       case Bytecodes::_fast_iputfield: // Fall through
       case Bytecodes::_fast_bputfield: // Fall through
+      case Bytecodes::_fast_zputfield: // Fall through
       case Bytecodes::_fast_cputfield: // Fall through
       case Bytecodes::_fast_sputfield: __ pop_i(); break;
       case Bytecodes::_fast_lputfield: __ pop_l(); break;
@@ -2825,6 +2859,21 @@
   __ dispatch_epilog(vtos, Bytecodes::length_for(bytecode()));
 
   __ align(32, 28, 28); // Align pop.
+  // __ bind(Lztos);
+  __ release(); // Volatile entry point (one instruction before non-volatile_entry point).
+  assert(branch_table[ztos] == 0, "can't compute twice");
+  branch_table[ztos] = __ pc(); // non-volatile_entry point
+  __ pop(ztos);
+  if (!is_static) { pop_and_check_object(Rclass_or_obj); } // Kills R11_scratch1.
+  __ andi(R17_tos, R17_tos, 0x1);
+  __ stbx(R17_tos, Rclass_or_obj, Roffset);
+  if (!is_static) { patch_bytecode(Bytecodes::_fast_zputfield, Rbc, Rscratch, true, byte_no); }
+  if (!support_IRIW_for_not_multiple_copy_atomic_cpu) {
+    __ beq(CR_is_vol, Lvolatile); // Volatile?
+  }
+  __ dispatch_epilog(vtos, Bytecodes::length_for(bytecode()));
+
+  __ align(32, 28, 28); // Align pop.
   // __ bind(Lctos);
   __ release(); // Volatile entry point (one instruction before non-volatile_entry point).
   assert(branch_table[ctos] == 0, "can't compute twice");
@@ -2949,6 +2998,9 @@
       __ stdx(R17_tos, Rclass_or_obj, Roffset);
       break;
 
+    case Bytecodes::_fast_zputfield:
+      __ andi(R17_tos, R17_tos, 0x1);  // boolean is true if LSB is 1
+      // fall through to bputfield
     case Bytecodes::_fast_bputfield:
       __ stbx(R17_tos, Rclass_or_obj, Roffset);
       break;
--- a/hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -344,7 +344,7 @@
     length.set_instruction(x->length());
     length.load_item();
   }
-  if (needs_store_check) {
+  if (needs_store_check || x->check_boolean()) {
     value.load_item();
   } else {
     value.load_for_store(x->elt_type());
@@ -389,7 +389,8 @@
     pre_barrier(LIR_OprFact::address(array_addr), LIR_OprFact::illegalOpr /* pre_val */,
                 true /* do_load */, false /* patch */, NULL);
   }
-  __ move(value.result(), array_addr, null_check_info);
+  LIR_Opr result = maybe_mask_boolean(x, array.result(), value.result(), null_check_info);
+  __ move(result, array_addr, null_check_info);
   if (obj_store) {
     // Precise card mark
     post_barrier(LIR_OprFact::address(array_addr), value.result());
--- a/hotspot/src/cpu/sparc/vm/debug_sparc.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/cpu/sparc/vm/debug_sparc.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -29,7 +29,6 @@
 #include "runtime/init.hpp"
 #include "runtime/os.hpp"
 #include "utilities/debug.hpp"
-#include "utilities/top.hpp"
 
 #ifndef PRODUCT
 
--- a/hotspot/src/cpu/sparc/vm/frame_sparc.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/cpu/sparc/vm/frame_sparc.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -26,7 +26,6 @@
 #define CPU_SPARC_VM_FRAME_SPARC_HPP
 
 #include "runtime/synchronizer.hpp"
-#include "utilities/top.hpp"
 
 // A frame represents a physical stack frame (an activation).  Frames can be
 // C or Java frames, and the Java frames can be interpreted or compiled.
--- a/hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -208,6 +208,7 @@
   case atos: ld_ptr(oop_addr, Otos_l);
              st_ptr(G0, oop_addr);                        break;
   case btos:                                           // fall through
+  case ztos:                                           // fall through
   case ctos:                                           // fall through
   case stos:                                           // fall through
   case itos: ld(val_addr, Otos_l1);                       break;
@@ -452,9 +453,10 @@
   interp_verify_oop(Otos_i, state, __FILE__, __LINE__);
   switch (state) {
     case atos: push_ptr();            break;
-    case btos: push_i();              break;
-    case ctos:
-    case stos: push_i();              break;
+    case btos:                        // fall through
+    case ztos:                        // fall through
+    case ctos:                        // fall through
+    case stos:                        // fall through
     case itos: push_i();              break;
     case ltos: push_l();              break;
     case ftos: push_f();              break;
@@ -468,9 +470,10 @@
 void InterpreterMacroAssembler::pop(TosState state) {
   switch (state) {
     case atos: pop_ptr();            break;
-    case btos: pop_i();              break;
-    case ctos:
-    case stos: pop_i();              break;
+    case btos:                       // fall through
+    case ztos:                       // fall through
+    case ctos:                       // fall through
+    case stos:                       // fall through
     case itos: pop_i();              break;
     case ltos: pop_l();              break;
     case ftos: pop_f();              break;
@@ -1103,6 +1106,49 @@
   interp_verify_oop(Otos_i, state, __FILE__, __LINE__);
 }
 
+void InterpreterMacroAssembler::narrow(Register result) {
+
+  ld_ptr(Address(Lmethod, Method::const_offset()), G3_scratch);
+  ldub(G3_scratch, in_bytes(ConstMethod::result_type_offset()), G3_scratch);
+
+  Label notBool, notByte, notChar, done;
+
+  // common case first
+  cmp(G3_scratch, T_INT);
+  br(Assembler::equal, true, pn, done);
+  delayed()->nop();
+
+  cmp(G3_scratch, T_BOOLEAN);
+  br(Assembler::notEqual, true, pn, notBool);
+  delayed()->cmp(G3_scratch, T_BYTE);
+  and3(result, 1, result);
+  ba(done);
+  delayed()->nop();
+
+  bind(notBool);
+  // cmp(G3_scratch, T_BYTE);
+  br(Assembler::notEqual, true, pn, notByte);
+  delayed()->cmp(G3_scratch, T_CHAR);
+  sll(result, 24, result);
+  sra(result, 24, result);
+  ba(done);
+  delayed()->nop();
+
+  bind(notByte);
+  // cmp(G3_scratch, T_CHAR);
+  sll(result, 16, result);
+  br(Assembler::notEqual, true, pn, done);
+  delayed()->sra(result, 16, result);
+  // sll(result, 16, result);
+  srl(result, 16, result);
+
+  // bind(notChar);
+  // must be short, instructions already executed in delay slot
+  // sll(result, 16, result);
+  // sra(result, 16, result);
+
+  bind(done);
+}
 
 // remove activation
 //
@@ -1151,6 +1197,7 @@
   case ltos: mov(Otos_l2, Otos_l2->after_save()); // fall through  // O1 -> I1
 #endif
   case btos:                                      // fall through
+  case ztos:                                      // fall through
   case ctos:
   case stos:                                      // fall through
   case atos:                                      // fall through
--- a/hotspot/src/cpu/sparc/vm/interp_masm_sparc.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/cpu/sparc/vm/interp_masm_sparc.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -103,6 +103,8 @@
   void dispatch_via (TosState state, address* table);
 
 
+  void narrow(Register result);
+
   // Removes the current activation (incl. unlocking of monitors).
   // Additionally this code is used for earlyReturn in which case we
   // want to skip throwing an exception and installing an exception.
--- a/hotspot/src/cpu/sparc/vm/metaspaceShared_sparc.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/cpu/sparc/vm/metaspaceShared_sparc.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -65,8 +65,6 @@
   *vtable = dummy_vtable;
   *md_top += vtable_bytes;
 
-  guarantee(*md_top <= md_end, "Insufficient space for vtables.");
-
   // Get ready to generate dummy methods.
 
   CodeBuffer cb((unsigned char*)*mc_top, mc_end - *mc_top);
--- a/hotspot/src/cpu/sparc/vm/nativeInst_sparc.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/cpu/sparc/vm/nativeInst_sparc.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -29,7 +29,6 @@
 #include "memory/allocation.hpp"
 #include "runtime/icache.hpp"
 #include "runtime/os.hpp"
-#include "utilities/top.hpp"
 
 // We have interface for the following instructions:
 // - NativeInstruction
--- a/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -324,6 +324,16 @@
   return size > 8;
 }
 
+size_t SharedRuntime::trampoline_size() {
+  return 40;
+}
+
+void SharedRuntime::generate_trampoline(MacroAssembler *masm, address destination) {
+  __ set((intptr_t)destination, G3_scratch);
+  __ JMP(G3_scratch, 0);
+  __ delayed()->nop();
+}
+
 // The java_calling_convention describes stack locations as ideal slots on
 // a frame with no abi restrictions. Since we must observe abi restrictions
 // (like the placement of the register window) the slots must be biased by
--- a/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -37,7 +37,6 @@
 #include "runtime/stubCodeGenerator.hpp"
 #include "runtime/stubRoutines.hpp"
 #include "runtime/thread.inline.hpp"
-#include "utilities/top.hpp"
 #ifdef COMPILER2
 #include "opto/runtime.hpp"
 #endif
--- a/hotspot/src/cpu/sparc/vm/templateInterpreterGenerator_sparc.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/cpu/sparc/vm/templateInterpreterGenerator_sparc.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -616,7 +616,7 @@
 
   // compute the beginning of the protected zone minus the requested frame size
   __ sub( Rscratch, Rscratch2,   Rscratch );
-  __ set( JavaThread::stack_red_zone_size() + JavaThread::stack_yellow_zone_size(), Rscratch2 );
+  __ set(MAX2(JavaThread::stack_shadow_zone_size(), JavaThread::stack_guard_zone_size()), Rscratch2 );
   __ add( Rscratch, Rscratch2,   Rscratch );
 
   // Add in the size of the frame (which is the same as subtracting it from the
--- a/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -165,6 +165,7 @@
   switch (bc) {
   case Bytecodes::_fast_aputfield:
   case Bytecodes::_fast_bputfield:
+  case Bytecodes::_fast_zputfield:
   case Bytecodes::_fast_cputfield:
   case Bytecodes::_fast_dputfield:
   case Bytecodes::_fast_fputfield:
@@ -922,8 +923,20 @@
   transition(itos, vtos);
   __ pop_i(O2); // index
   // Otos_i: val
+  // O2: index
   // O3: array
   __ index_check(O3, O2, 0, G3_scratch, O2);
+  // Need to check whether array is boolean or byte
+  // since both types share the bastore bytecode.
+  __ load_klass(O3, G4_scratch);
+  __ ld(G4_scratch, in_bytes(Klass::layout_helper_offset()), G4_scratch);
+  __ set(Klass::layout_helper_boolean_diffbit(), G3_scratch);
+  __ andcc(G3_scratch, G4_scratch, G0);
+  Label L_skip;
+  __ br(Assembler::zero, false, Assembler::pn, L_skip);
+  __ delayed()->nop();
+  __ and3(Otos_i, 1, Otos_i);  // if it is a T_BOOLEAN array, mask the stored value to 0/1
+  __ bind(L_skip);
   __ stb(Otos_i, O2, arrayOopDesc::base_offset_in_bytes(T_BYTE));
 }
 
@@ -2008,6 +2021,12 @@
     __ bind(skip_register_finalizer);
   }
 
+  // Narrow result if state is itos but result type is smaller.
+  // Need to narrow in the return bytecode rather than in generate_return_entry
+  // since compiled code callers expect the result to already be narrowed.
+  if (state == itos) {
+    __ narrow(Otos_i);
+  }
   __ remove_activation(state, /* throw_monitor_exception */ true);
 
   // The caller's SP was adjusted upon method entry to accomodate
@@ -2218,7 +2237,7 @@
   Label checkVolatile;
 
   // compute field type
-  Label notByte, notInt, notShort, notChar, notLong, notFloat, notObj;
+  Label notByte, notBool, notInt, notShort, notChar, notLong, notFloat, notObj;
   __ srl(Rflags, ConstantPoolCacheEntry::tos_state_shift, Rflags);
   // Make sure we don't need to mask Rflags after the above shift
   ConstantPoolCacheEntry::verify_tos_state_shift();
@@ -2273,7 +2292,7 @@
 
   // cmp(Rflags, btos);
   __ br(Assembler::notEqual, false, Assembler::pt, notByte);
-  __ delayed() ->cmp(Rflags, ctos);
+  __ delayed() ->cmp(Rflags, ztos);
 
   // btos
   __ ldsb(Rclass, Roffset, Otos_i);
@@ -2286,6 +2305,22 @@
 
   __ bind(notByte);
 
+  // cmp(Rflags, ztos);
+  __ br(Assembler::notEqual, false, Assembler::pt, notBool);
+  __ delayed() ->cmp(Rflags, ctos);
+
+  // ztos
+  __ ldsb(Rclass, Roffset, Otos_i);
+  __ push(itos);
+  if (!is_static && rc == may_rewrite) {
+    // use btos rewriting, no truncating to t/f bit is needed for getfield.
+    patch_bytecode(Bytecodes::_fast_bgetfield, G3_scratch, G4_scratch);
+  }
+  __ ba(checkVolatile);
+  __ delayed()->tst(Lscratch);
+
+  __ bind(notBool);
+
   // cmp(Rflags, ctos);
   __ br(Assembler::notEqual, false, Assembler::pt, notChar);
   __ delayed() ->cmp(Rflags, stos);
@@ -2449,6 +2484,7 @@
     switch (bytecode()) {  // save tos values before call_VM() clobbers them
     case Bytecodes::_fast_aputfield: __ push_ptr(Otos_i); break;
     case Bytecodes::_fast_bputfield: // fall through
+    case Bytecodes::_fast_zputfield: // fall through
     case Bytecodes::_fast_sputfield: // fall through
     case Bytecodes::_fast_cputfield: // fall through
     case Bytecodes::_fast_iputfield: __ push_i(Otos_i); break;
@@ -2466,6 +2502,7 @@
     switch (bytecode()) {             // restore tos values
     case Bytecodes::_fast_aputfield: __ pop_ptr(Otos_i); break;
     case Bytecodes::_fast_bputfield: // fall through
+    case Bytecodes::_fast_zputfield: // fall through
     case Bytecodes::_fast_sputfield: // fall through
     case Bytecodes::_fast_cputfield: // fall through
     case Bytecodes::_fast_iputfield: __ pop_i(Otos_i); break;
@@ -2581,7 +2618,7 @@
   ConstantPoolCacheEntry::verify_tos_state_shift();
 
   // compute field type
-  Label notInt, notShort, notChar, notObj, notByte, notLong, notFloat;
+  Label notInt, notShort, notChar, notObj, notByte, notBool, notLong, notFloat;
 
   if (is_static) {
     // putstatic with object type most likely, check that first
@@ -2649,7 +2686,7 @@
 
   // cmp(Rflags, btos);
   __ br(Assembler::notEqual, false, Assembler::pt, notByte);
-  __ delayed()->cmp(Rflags, ltos);
+  __ delayed()->cmp(Rflags, ztos);
 
   // btos
   {
@@ -2664,6 +2701,25 @@
   }
 
   __ bind(notByte);
+
+  // cmp(Rflags, btos);
+  __ br(Assembler::notEqual, false, Assembler::pt, notBool);
+  __ delayed()->cmp(Rflags, ltos);
+
+  // ztos
+  {
+    __ pop_i();
+    if (!is_static) pop_and_check_object(Rclass);
+    __ and3(Otos_i, 1, Otos_i);
+    __ stb(Otos_i, Rclass, Roffset);
+    if (!is_static && rc == may_rewrite) {
+      patch_bytecode(Bytecodes::_fast_zputfield, G3_scratch, G4_scratch, true, byte_no);
+    }
+    __ ba(checkVolatile);
+    __ delayed()->tst(Lscratch);
+  }
+
+  __ bind(notBool);
   // cmp(Rflags, ltos);
   __ br(Assembler::notEqual, false, Assembler::pt, notLong);
   __ delayed()->cmp(Rflags, ctos);
@@ -2787,6 +2843,7 @@
   pop_and_check_object(Rclass);
 
   switch (bytecode()) {
+    case Bytecodes::_fast_zputfield: __ and3(Otos_i, 1, Otos_i);  // fall through to bputfield
     case Bytecodes::_fast_bputfield: __ stb(Otos_i, Rclass, Roffset); break;
     case Bytecodes::_fast_cputfield: /* fall through */
     case Bytecodes::_fast_sputfield: __ sth(Otos_i, Rclass, Roffset); break;
--- a/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -24,6 +24,7 @@
 
 #include "precompiled.hpp"
 #include "asm/macroAssembler.inline.hpp"
+#include "logging/log.hpp"
 #include "memory/resourceArea.hpp"
 #include "runtime/java.hpp"
 #include "runtime/os.hpp"
@@ -368,36 +369,38 @@
     FLAG_SET_DEFAULT(UseUnalignedAccesses, false);
   }
 
-  if (PrintMiscellaneous && Verbose) {
-    tty->print_cr("L1 data cache line size: %u", L1_data_cache_line_size());
-    tty->print_cr("L2 data cache line size: %u", L2_data_cache_line_size());
-    tty->print("Allocation");
+  if (log_is_enabled(Info, os, cpu)) {
+    ResourceMark rm;
+    outputStream* log = Log(os, cpu)::info_stream();
+    log->print_cr("L1 data cache line size: %u", L1_data_cache_line_size());
+    log->print_cr("L2 data cache line size: %u", L2_data_cache_line_size());
+    log->print("Allocation");
     if (AllocatePrefetchStyle <= 0) {
-      tty->print_cr(": no prefetching");
+      log->print(": no prefetching");
     } else {
-      tty->print(" prefetching: ");
+      log->print(" prefetching: ");
       if (AllocatePrefetchInstr == 0) {
-          tty->print("PREFETCH");
+          log->print("PREFETCH");
       } else if (AllocatePrefetchInstr == 1) {
-          tty->print("BIS");
+          log->print("BIS");
       }
       if (AllocatePrefetchLines > 1) {
-        tty->print_cr(" at distance %d, %d lines of %d bytes", (int) AllocatePrefetchDistance, (int) AllocatePrefetchLines, (int) AllocatePrefetchStepSize);
+        log->print_cr(" at distance %d, %d lines of %d bytes", (int) AllocatePrefetchDistance, (int) AllocatePrefetchLines, (int) AllocatePrefetchStepSize);
       } else {
-        tty->print_cr(" at distance %d, one line of %d bytes", (int) AllocatePrefetchDistance, (int) AllocatePrefetchStepSize);
+        log->print_cr(" at distance %d, one line of %d bytes", (int) AllocatePrefetchDistance, (int) AllocatePrefetchStepSize);
       }
     }
     if (PrefetchCopyIntervalInBytes > 0) {
-      tty->print_cr("PrefetchCopyIntervalInBytes %d", (int) PrefetchCopyIntervalInBytes);
+      log->print_cr("PrefetchCopyIntervalInBytes %d", (int) PrefetchCopyIntervalInBytes);
     }
     if (PrefetchScanIntervalInBytes > 0) {
-      tty->print_cr("PrefetchScanIntervalInBytes %d", (int) PrefetchScanIntervalInBytes);
+      log->print_cr("PrefetchScanIntervalInBytes %d", (int) PrefetchScanIntervalInBytes);
     }
     if (PrefetchFieldsAhead > 0) {
-      tty->print_cr("PrefetchFieldsAhead %d", (int) PrefetchFieldsAhead);
+      log->print_cr("PrefetchFieldsAhead %d", (int) PrefetchFieldsAhead);
     }
     if (ContendedPaddingWidth > 0) {
-      tty->print_cr("ContendedPaddingWidth %d", (int) ContendedPaddingWidth);
+      log->print_cr("ContendedPaddingWidth %d", (int) ContendedPaddingWidth);
     }
   }
 }
@@ -408,7 +411,7 @@
 
 int VM_Version::determine_features() {
   if (UseV8InstrsOnly) {
-    if (PrintMiscellaneous && Verbose) { tty->print_cr("Version is Forced-V8"); }
+    log_info(os, cpu)("Version is Forced-V8");
     return generic_v8_m;
   }
 
@@ -416,7 +419,7 @@
 
   if (features == unknown_m) {
     features = generic_v9_m;
-    warning("Cannot recognize SPARC version. Default to V9");
+    log_info(os)("Cannot recognize SPARC version. Default to V9");
   }
 
   assert(is_T_family(features) == is_niagara(features), "Niagara should be T series");
@@ -424,12 +427,12 @@
     if (is_T_family(features)) {
       // Happy to accomodate...
     } else {
-      if (PrintMiscellaneous && Verbose) { tty->print_cr("Version is Forced-Niagara"); }
+      log_info(os, cpu)("Version is Forced-Niagara");
       features |= T_family_m;
     }
   } else {
     if (is_T_family(features) && !FLAG_IS_DEFAULT(UseNiagaraInstrs)) {
-      if (PrintMiscellaneous && Verbose) { tty->print_cr("Version is Forced-Not-Niagara"); }
+      log_info(os, cpu)("Version is Forced-Not-Niagara");
       features &= ~(T_family_m | T1_model_m);
     } else {
       // Happy to accomodate...
--- a/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -284,7 +284,7 @@
     length.load_item();
 
   }
-  if (needs_store_check) {
+  if (needs_store_check || x->check_boolean()) {
     value.load_item();
   } else {
     value.load_for_store(x->elt_type());
@@ -332,7 +332,8 @@
     // Seems to be a precise
     post_barrier(LIR_OprFact::address(array_addr), value.result());
   } else {
-    __ move(value.result(), array_addr, null_check_info);
+    LIR_Opr result = maybe_mask_boolean(x, array.result(), value.result(), null_check_info);
+    __ move(result, array_addr, null_check_info);
   }
 }
 
--- a/hotspot/src/cpu/x86/vm/debug_x86.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/cpu/x86/vm/debug_x86.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -29,6 +29,5 @@
 #include "runtime/init.hpp"
 #include "runtime/os.hpp"
 #include "utilities/debug.hpp"
-#include "utilities/top.hpp"
 
 void pd_ps(frame f) {}
--- a/hotspot/src/cpu/x86/vm/frame_x86.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/cpu/x86/vm/frame_x86.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -26,7 +26,6 @@
 #define CPU_X86_VM_FRAME_X86_HPP
 
 #include "runtime/synchronizer.hpp"
-#include "utilities/top.hpp"
 
 // A frame represents a physical stack frame (an activation).  Frames can be
 // C or Java frames, and the Java frames can be interpreted or compiled.
--- a/hotspot/src/cpu/x86/vm/interp_masm_x86.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/cpu/x86/vm/interp_masm_x86.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -349,6 +349,7 @@
                verify_oop(rax, state);              break;
     case ltos: movptr(rax, val_addr);                 break;
     case btos:                                   // fall through
+    case ztos:                                   // fall through
     case ctos:                                   // fall through
     case stos:                                   // fall through
     case itos: movl(rax, val_addr);                 break;
@@ -370,6 +371,7 @@
     case ltos:
                movl(rdx, val_addr1);               // fall through
     case btos:                                     // fall through
+    case ztos:                                     // fall through
     case ctos:                                     // fall through
     case stos:                                     // fall through
     case itos: movl(rax, val_addr);                   break;
@@ -616,6 +618,7 @@
   switch (state) {
   case atos: pop_ptr();                 break;
   case btos:
+  case ztos:
   case ctos:
   case stos:
   case itos: pop_i();                   break;
@@ -633,6 +636,7 @@
   switch (state) {
   case atos: push_ptr();                break;
   case btos:
+  case ztos:
   case ctos:
   case stos:
   case itos: push_i();                  break;
@@ -668,6 +672,7 @@
   switch (state) {
     case atos: pop_ptr(rax);                                 break;
     case btos:                                               // fall through
+    case ztos:                                               // fall through
     case ctos:                                               // fall through
     case stos:                                               // fall through
     case itos: pop_i(rax);                                   break;
@@ -716,6 +721,7 @@
   switch (state) {
     case atos: push_ptr(rax); break;
     case btos:                                               // fall through
+    case ztos:                                               // fall through
     case ctos:                                               // fall through
     case stos:                                               // fall through
     case itos: push_i(rax);                                    break;
@@ -849,6 +855,51 @@
   dispatch_base(state, table);
 }
 
+void InterpreterMacroAssembler::narrow(Register result) {
+
+  // Get method->_constMethod->_result_type
+  movptr(rcx, Address(rbp, frame::interpreter_frame_method_offset * wordSize));
+  movptr(rcx, Address(rcx, Method::const_offset()));
+  load_unsigned_byte(rcx, Address(rcx, ConstMethod::result_type_offset()));
+
+  Label done, notBool, notByte, notChar;
+
+  // common case first
+  cmpl(rcx, T_INT);
+  jcc(Assembler::equal, done);
+
+  // mask integer result to narrower return type.
+  cmpl(rcx, T_BOOLEAN);
+  jcc(Assembler::notEqual, notBool);
+  andl(result, 0x1);
+  jmp(done);
+
+  bind(notBool);
+  cmpl(rcx, T_BYTE);
+  jcc(Assembler::notEqual, notByte);
+  LP64_ONLY(movsbl(result, result);)
+  NOT_LP64(shll(result, 24);)      // truncate upper 24 bits
+  NOT_LP64(sarl(result, 24);)      // and sign-extend byte
+  jmp(done);
+
+  bind(notByte);
+  cmpl(rcx, T_CHAR);
+  jcc(Assembler::notEqual, notChar);
+  LP64_ONLY(movzwl(result, result);)
+  NOT_LP64(andl(result, 0xFFFF);)  // truncate upper 16 bits
+  jmp(done);
+
+  bind(notChar);
+  // cmpl(rcx, T_SHORT);  // all that's left
+  // jcc(Assembler::notEqual, done);
+  LP64_ONLY(movswl(result, result);)
+  NOT_LP64(shll(result, 16);)      // truncate upper 16 bits
+  NOT_LP64(sarl(result, 16);)      // and sign-extend short
+
+  // Nothing to do for T_INT
+  bind(done);
+}
+
 // remove activation
 //
 // Unlock the receiver if this is a synchronized method.
--- a/hotspot/src/cpu/x86/vm/interp_masm_x86.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/cpu/x86/vm/interp_masm_x86.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -192,6 +192,9 @@
   void prepare_to_jump_from_interpreted();
   void jump_from_interpreted(Register method, Register temp);
 
+  // narrow int return value
+  void narrow(Register result);
+
   // Returning from interpreted functions
   //
   // Removes the current activation (incl. unlocking of monitors)
--- a/hotspot/src/cpu/x86/vm/nativeInst_x86.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/cpu/x86/vm/nativeInst_x86.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -29,7 +29,6 @@
 #include "memory/allocation.hpp"
 #include "runtime/icache.hpp"
 #include "runtime/os.hpp"
-#include "utilities/top.hpp"
 
 // We have interfaces for the following instructions:
 // - NativeInstruction
--- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -355,6 +355,14 @@
   return size > 16;
 }
 
+size_t SharedRuntime::trampoline_size() {
+  return 16;
+}
+
+void SharedRuntime::generate_trampoline(MacroAssembler *masm, address destination) {
+  __ jump(RuntimeAddress(destination));
+}
+
 // The java_calling_convention describes stack locations as ideal slots on
 // a frame with no abi restrictions. Since we must observe abi restrictions
 // (like the placement of the register window) the slots must be biased by
--- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -391,6 +391,14 @@
   return size > 16;
 }
 
+size_t SharedRuntime::trampoline_size() {
+  return 16;
+}
+
+void SharedRuntime::generate_trampoline(MacroAssembler *masm, address destination) {
+  __ jump(RuntimeAddress(destination));
+}
+
 // The java_calling_convention describes stack locations as ideal slots on
 // a frame with no abi restrictions. Since we must observe abi restrictions
 // (like the placement of the register window) the slots must be biased by
--- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -38,7 +38,6 @@
 #include "runtime/stubCodeGenerator.hpp"
 #include "runtime/stubRoutines.hpp"
 #include "runtime/thread.inline.hpp"
-#include "utilities/top.hpp"
 #ifdef COMPILER2
 #include "opto/runtime.hpp"
 #endif
--- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -38,7 +38,6 @@
 #include "runtime/stubCodeGenerator.hpp"
 #include "runtime/stubRoutines.hpp"
 #include "runtime/thread.inline.hpp"
-#include "utilities/top.hpp"
 #ifdef COMPILER2
 #include "opto/runtime.hpp"
 #endif
--- a/hotspot/src/cpu/x86/vm/templateTable_x86.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/cpu/x86/vm/templateTable_x86.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -243,6 +243,7 @@
   switch (bc) {
   case Bytecodes::_fast_aputfield:
   case Bytecodes::_fast_bputfield:
+  case Bytecodes::_fast_zputfield:
   case Bytecodes::_fast_cputfield:
   case Bytecodes::_fast_dputfield:
   case Bytecodes::_fast_fputfield:
@@ -1082,6 +1083,16 @@
   // rbx: index
   // rdx: array
   index_check(rdx, rbx); // prefer index in rbx
+  // Need to check whether array is boolean or byte
+  // since both types share the bastore bytecode.
+  __ load_klass(rcx, rdx);
+  __ movl(rcx, Address(rcx, Klass::layout_helper_offset()));
+  int diffbit = Klass::layout_helper_boolean_diffbit();
+  __ testl(rcx, diffbit);
+  Label L_skip;
+  __ jccb(Assembler::zero, L_skip);
+  __ andl(rax, 1);  // if it is a T_BOOLEAN array, mask the stored value to 0/1
+  __ bind(L_skip);
   __ movb(Address(rdx, rbx,
                   Address::times_1,
                   arrayOopDesc::base_offset_in_bytes(T_BYTE)),
@@ -2540,13 +2551,12 @@
 void TemplateTable::_return(TosState state) {
   transition(state, state);
 
-  Register robj = LP64_ONLY(c_rarg1) NOT_LP64(rax);
-
   assert(_desc->calls_vm(),
          "inconsistent calls_vm information"); // call in remove_activation
 
   if (_desc->bytecode() == Bytecodes::_return_register_finalizer) {
     assert(state == vtos, "only valid state");
+    Register robj = LP64_ONLY(c_rarg1) NOT_LP64(rax);
     __ movptr(robj, aaddress(0));
     __ load_klass(rdi, robj);
     __ movl(rdi, Address(rdi, Klass::access_flags_offset()));
@@ -2559,7 +2569,14 @@
     __ bind(skip_register_finalizer);
   }
 
+  // Narrow result if state is itos but result type is smaller.
+  // Need to narrow in the return bytecode rather than in generate_return_entry
+  // since compiled code callers expect the result to already be narrowed.
+  if (state == itos) {
+    __ narrow(rax);
+  }
   __ remove_activation(state, rbcp);
+
   __ jmp(rbcp);
 }
 
@@ -2754,7 +2771,7 @@
   const Address field(obj, off, Address::times_1, 0*wordSize);
   NOT_LP64(const Address hi(obj, off, Address::times_1, 1*wordSize));
 
-  Label Done, notByte, notInt, notShort, notChar, notLong, notFloat, notObj, notDouble;
+  Label Done, notByte, notBool, notInt, notShort, notChar, notLong, notFloat, notObj, notDouble;
 
   __ shrl(flags, ConstantPoolCacheEntry::tos_state_shift);
   // Make sure we don't need to mask edx after the above shift
@@ -2773,6 +2790,20 @@
   __ jmp(Done);
 
   __ bind(notByte);
+  __ cmpl(flags, ztos);
+  __ jcc(Assembler::notEqual, notBool);
+
+  // ztos (same code as btos)
+  __ load_signed_byte(rax, field);
+  __ push(ztos);
+  // Rewrite bytecode to be faster
+  if (!is_static && rc == may_rewrite) {
+    // use btos rewriting, no truncating to t/f bit is needed for getfield.
+    patch_bytecode(Bytecodes::_fast_bgetfield, bc, rbx);
+  }
+  __ jmp(Done);
+
+  __ bind(notBool);
   __ cmpl(flags, atos);
   __ jcc(Assembler::notEqual, notObj);
   // atos
@@ -3006,7 +3037,7 @@
   const Address field(obj, off, Address::times_1, 0*wordSize);
   NOT_LP64( const Address hi(obj, off, Address::times_1, 1*wordSize);)
 
-  Label notByte, notInt, notShort, notChar,
+  Label notByte, notBool, notInt, notShort, notChar,
         notLong, notFloat, notObj, notDouble;
 
   __ shrl(flags, ConstantPoolCacheEntry::tos_state_shift);
@@ -3027,6 +3058,22 @@
   }
 
   __ bind(notByte);
+  __ cmpl(flags, ztos);
+  __ jcc(Assembler::notEqual, notBool);
+
+  // ztos
+  {
+    __ pop(ztos);
+    if (!is_static) pop_and_check_object(obj);
+    __ andl(rax, 0x1);
+    __ movb(field, rax);
+    if (!is_static && rc == may_rewrite) {
+      patch_bytecode(Bytecodes::_fast_zputfield, bc, rbx, true, byte_no);
+    }
+    __ jmp(Done);
+  }
+
+  __ bind(notBool);
   __ cmpl(flags, atos);
   __ jcc(Assembler::notEqual, notObj);
 
@@ -3214,6 +3261,7 @@
     switch (bytecode()) {          // load values into the jvalue object
     case Bytecodes::_fast_aputfield: __ push_ptr(rax); break;
     case Bytecodes::_fast_bputfield: // fall through
+    case Bytecodes::_fast_zputfield: // fall through
     case Bytecodes::_fast_sputfield: // fall through
     case Bytecodes::_fast_cputfield: // fall through
     case Bytecodes::_fast_iputfield: __ push_i(rax); break;
@@ -3238,6 +3286,7 @@
     switch (bytecode()) {             // restore tos values
     case Bytecodes::_fast_aputfield: __ pop_ptr(rax); break;
     case Bytecodes::_fast_bputfield: // fall through
+    case Bytecodes::_fast_zputfield: // fall through
     case Bytecodes::_fast_sputfield: // fall through
     case Bytecodes::_fast_cputfield: // fall through
     case Bytecodes::_fast_iputfield: __ pop_i(rax); break;
@@ -3297,6 +3346,9 @@
   case Bytecodes::_fast_iputfield:
     __ movl(field, rax);
     break;
+  case Bytecodes::_fast_zputfield:
+    __ andl(rax, 0x1);  // boolean is true if LSB is 1
+    // fall through to bputfield
   case Bytecodes::_fast_bputfield:
     __ movb(field, rax);
     break;
--- a/hotspot/src/cpu/x86/vm/vm_version_x86.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/cpu/x86/vm/vm_version_x86.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -25,6 +25,7 @@
 #include "precompiled.hpp"
 #include "asm/macroAssembler.hpp"
 #include "asm/macroAssembler.inline.hpp"
+#include "logging/log.hpp"
 #include "memory/resourceArea.hpp"
 #include "runtime/java.hpp"
 #include "runtime/os.hpp"
@@ -1223,59 +1224,60 @@
   }
 
 #ifndef PRODUCT
-  if (PrintMiscellaneous && Verbose) {
-    tty->print_cr("Logical CPUs per core: %u",
+  if (log_is_enabled(Info, os, cpu)) {
+    outputStream* log = Log(os, cpu)::info_stream();
+    log->print_cr("Logical CPUs per core: %u",
                   logical_processors_per_package());
-    tty->print_cr("L1 data cache line size: %u", L1_data_cache_line_size());
-    tty->print("UseSSE=%d", (int) UseSSE);
+    log->print_cr("L1 data cache line size: %u", L1_data_cache_line_size());
+    log->print("UseSSE=%d", (int) UseSSE);
     if (UseAVX > 0) {
-      tty->print("  UseAVX=%d", (int) UseAVX);
+      log->print("  UseAVX=%d", (int) UseAVX);
     }
     if (UseAES) {
-      tty->print("  UseAES=1");
+      log->print("  UseAES=1");
     }
 #ifdef COMPILER2
     if (MaxVectorSize > 0) {
-      tty->print("  MaxVectorSize=%d", (int) MaxVectorSize);
+      log->print("  MaxVectorSize=%d", (int) MaxVectorSize);
     }
 #endif
-    tty->cr();
-    tty->print("Allocation");
+    log->cr();
+    log->print("Allocation");
     if (AllocatePrefetchStyle <= 0 || UseSSE == 0 && !supports_3dnow_prefetch()) {
-      tty->print_cr(": no prefetching");
+      log->print_cr(": no prefetching");
     } else {
-      tty->print(" prefetching: ");
+      log->print(" prefetching: ");
       if (UseSSE == 0 && supports_3dnow_prefetch()) {
-        tty->print("PREFETCHW");
+        log->print("PREFETCHW");
       } else if (UseSSE >= 1) {
         if (AllocatePrefetchInstr == 0) {
-          tty->print("PREFETCHNTA");
+          log->print("PREFETCHNTA");
         } else if (AllocatePrefetchInstr == 1) {
-          tty->print("PREFETCHT0");
+          log->print("PREFETCHT0");
         } else if (AllocatePrefetchInstr == 2) {
-          tty->print("PREFETCHT2");
+          log->print("PREFETCHT2");
         } else if (AllocatePrefetchInstr == 3) {
-          tty->print("PREFETCHW");
+          log->print("PREFETCHW");
         }
       }
       if (AllocatePrefetchLines > 1) {
-        tty->print_cr(" at distance %d, %d lines of %d bytes", (int) AllocatePrefetchDistance, (int) AllocatePrefetchLines, (int) AllocatePrefetchStepSize);
+        log->print_cr(" at distance %d, %d lines of %d bytes", (int) AllocatePrefetchDistance, (int) AllocatePrefetchLines, (int) AllocatePrefetchStepSize);
       } else {
-        tty->print_cr(" at distance %d, one line of %d bytes", (int) AllocatePrefetchDistance, (int) AllocatePrefetchStepSize);
+        log->print_cr(" at distance %d, one line of %d bytes", (int) AllocatePrefetchDistance, (int) AllocatePrefetchStepSize);
       }
     }
 
     if (PrefetchCopyIntervalInBytes > 0) {
-      tty->print_cr("PrefetchCopyIntervalInBytes %d", (int) PrefetchCopyIntervalInBytes);
+      log->print_cr("PrefetchCopyIntervalInBytes %d", (int) PrefetchCopyIntervalInBytes);
     }
     if (PrefetchScanIntervalInBytes > 0) {
-      tty->print_cr("PrefetchScanIntervalInBytes %d", (int) PrefetchScanIntervalInBytes);
+      log->print_cr("PrefetchScanIntervalInBytes %d", (int) PrefetchScanIntervalInBytes);
     }
     if (PrefetchFieldsAhead > 0) {
-      tty->print_cr("PrefetchFieldsAhead %d", (int) PrefetchFieldsAhead);
+      log->print_cr("PrefetchFieldsAhead %d", (int) PrefetchFieldsAhead);
     }
     if (ContendedPaddingWidth > 0) {
-      tty->print_cr("ContendedPaddingWidth %d", (int) ContendedPaddingWidth);
+      log->print_cr("ContendedPaddingWidth %d", (int) ContendedPaddingWidth);
     }
   }
 #endif // !PRODUCT
--- a/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -82,6 +82,30 @@
   return 0;
 }
 
+intptr_t narrow(BasicType type, intptr_t result) {
+  // mask integer result to narrower return type.
+  switch (type) {
+    case T_BOOLEAN:
+      return result&1;
+    case T_BYTE:
+      return (intptr_t)(jbyte)result;
+    case T_CHAR:
+      return (intptr_t)(uintptr_t)(jchar)result;
+    case T_SHORT:
+      return (intptr_t)(jshort)result;
+    case T_OBJECT:  // nothing to do fall through
+    case T_ARRAY:
+    case T_LONG:
+    case T_INT:
+    case T_FLOAT:
+    case T_DOUBLE:
+    case T_VOID:
+      return result;
+    default  : ShouldNotReachHere();
+  }
+}
+
+
 void CppInterpreter::main_loop(int recurse, TRAPS) {
   JavaThread *thread = (JavaThread *) THREAD;
   ZeroStack *stack = thread->zero_stack();
@@ -161,7 +185,7 @@
     }
     else if (istate->msg() == BytecodeInterpreter::return_from_method) {
       // Copy the result into the caller's frame
-      result_slots = type2size[result_type_of(method)];
+      result_slots = type2size[method->result_type()];
       assert(result_slots >= 0 && result_slots <= 2, "what?");
       result = istate->stack() + result_slots;
       break;
@@ -195,8 +219,14 @@
   stack->set_sp(stack->sp() + method->max_locals());
 
   // Push our result
-  for (int i = 0; i < result_slots; i++)
-    stack->push(result[-i]);
+  for (int i = 0; i < result_slots; i++) {
+    // Adjust result to smaller
+    intptr_t res = result[-i];
+    if (result_slots == 1) {
+      res = narrow(method->result_type(), res);
+    }
+    stack->push(res);
+  }
 }
 
 int CppInterpreter::native_entry(Method* method, intptr_t UNUSED, TRAPS) {
@@ -407,7 +437,7 @@
 
   // Push our result
   if (!HAS_PENDING_EXCEPTION) {
-    BasicType type = result_type_of(method);
+    BasicType type = method->result_type();
     stack->set_sp(stack->sp() - type2size[type]);
 
     switch (type) {
@@ -532,6 +562,7 @@
       break;
 
     case btos:
+    case ztos:
       SET_LOCALS_INT(object->byte_field_acquire(entry->f2_as_index()), 0);
       break;
 
@@ -570,6 +601,7 @@
       break;
 
     case btos:
+    case ztos:
       SET_LOCALS_INT(object->byte_field(entry->f2_as_index()), 0);
       break;
 
@@ -772,26 +804,6 @@
   return (InterpreterFrame *) fp;
 }
 
-BasicType CppInterpreter::result_type_of(Method* method) {
-  BasicType t = T_ILLEGAL; // silence compiler warnings
-  switch (method->result_index()) {
-    case 0 : t = T_BOOLEAN; break;
-    case 1 : t = T_CHAR;    break;
-    case 2 : t = T_BYTE;    break;
-    case 3 : t = T_SHORT;   break;
-    case 4 : t = T_INT;     break;
-    case 5 : t = T_LONG;    break;
-    case 6 : t = T_VOID;    break;
-    case 7 : t = T_FLOAT;   break;
-    case 8 : t = T_DOUBLE;  break;
-    case 9 : t = T_OBJECT;  break;
-    default: ShouldNotReachHere();
-  }
-  assert(AbstractInterpreter::BasicType_as_index(t) == method->result_index(),
-         "out of step with AbstractInterpreter::BasicType_as_index");
-  return t;
-}
-
 address CppInterpreter::return_entry(TosState state, int length, Bytecodes::Code code) {
   ShouldNotCallThis();
   return NULL;
--- a/hotspot/src/cpu/zero/vm/cppInterpreter_zero.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/cpu/zero/vm/cppInterpreter_zero.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2007, 2008, 2010, 2011 Red Hat, Inc.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -49,8 +49,4 @@
   static intptr_t* calculate_unwind_sp(ZeroStack* stack, oop method_handle);
   static void throw_exception(JavaThread* thread, Symbol* name,char *msg=NULL);
 
- private:
-  // Fast result type determination
-  static BasicType result_type_of(Method* method);
-
 #endif // CPU_ZERO_VM_CPPINTERPRETER_ZERO_HPP
--- a/hotspot/src/cpu/zero/vm/debug_zero.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/cpu/zero/vm/debug_zero.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -30,7 +30,6 @@
 #include "runtime/init.hpp"
 #include "runtime/os.hpp"
 #include "utilities/debug.hpp"
-#include "utilities/top.hpp"
 
 void pd_ps(frame f) {
   ShouldNotCallThis();
--- a/hotspot/src/cpu/zero/vm/frame_zero.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/cpu/zero/vm/frame_zero.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -27,7 +27,6 @@
 #define CPU_ZERO_VM_FRAME_ZERO_HPP
 
 #include "runtime/synchronizer.hpp"
-#include "utilities/top.hpp"
 
 // A frame represents a physical stack frame on the Zero stack.
 
--- a/hotspot/src/cpu/zero/vm/nativeInst_zero.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/cpu/zero/vm/nativeInst_zero.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -30,7 +30,6 @@
 #include "memory/allocation.hpp"
 #include "runtime/icache.hpp"
 #include "runtime/os.hpp"
-#include "utilities/top.hpp"
 
 // We have interfaces for the following instructions:
 // - NativeInstruction
--- a/hotspot/src/cpu/zero/vm/sharedRuntime_zero.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/cpu/zero/vm/sharedRuntime_zero.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -132,6 +132,15 @@
   return generate_empty_runtime_stub("resolve_blob");
 }
 
+size_t SharedRuntime::trampoline_size() {
+  ShouldNotCallThis();
+  return 0;
+}
+
+void SharedRuntime::generate_trampoline(MacroAssembler *masm, address destination) {
+  ShouldNotCallThis();
+  return;
+}
 
 int SharedRuntime::c_calling_convention(const BasicType *sig_bt,
                                          VMRegPair *regs,
--- a/hotspot/src/cpu/zero/vm/stubGenerator_zero.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/cpu/zero/vm/stubGenerator_zero.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -40,7 +40,6 @@
 #include "runtime/stubRoutines.hpp"
 #include "runtime/thread.inline.hpp"
 #include "stack_zero.inline.hpp"
-#include "utilities/top.hpp"
 #ifdef COMPILER2
 #include "opto/runtime.hpp"
 #endif
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/SAGetopt.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/SAGetopt.java	Wed Jul 05 21:37:42 2017 +0200
@@ -55,11 +55,11 @@
     private void extractOptarg(String opt) {
         // Argument expected
         if (_optind > _argv.length) {
-            throw new RuntimeException("Not enough arguments for '" + opt + "'");
+            throw new SAGetoptException("Not enough arguments for '" + opt + "'");
         }
 
         if (! _argv[_optind].isEmpty() && _argv[_optind].charAt(0) == '-') {
-            throw new RuntimeException("Argument is expected for '" + opt + "'");
+            throw new SAGetoptException("Argument is expected for '" + opt + "'");
         }
 
         _optarg = _argv[_optind];
@@ -72,7 +72,7 @@
 
         if (los.contains(ca[0])) {
             if (ca.length > 1) {
-                throw new RuntimeException("Argument is not expected for '" + ca[0] + "'");
+                throw new SAGetoptException("Argument is not expected for '" + ca[0] + "'");
             }
             return carg;
         }
@@ -87,14 +87,14 @@
                 try {
                     extractOptarg(ca[0]);
                 } catch (ArrayIndexOutOfBoundsException e) {
-                    throw new RuntimeException("Argument is expected for '" + ca[0] + "'");
+                    throw new SAGetoptException("Argument is expected for '" + ca[0] + "'");
                 }
             }
 
             return ca[0];
         }
 
-        throw new RuntimeException("Invalid option '" + ca[0] + "'");
+        throw new SAGetoptException("Invalid option '" + ca[0] + "'");
     }
 
     public String next(String optStr, String[] longOptStr) {
@@ -148,7 +148,7 @@
 
         int chIndex = optStr.indexOf(ch);
         if (chIndex == -1) {
-            throw new RuntimeException("Invalid option '" + ch + "'");
+            throw new SAGetoptException("Invalid option '" + ch + "'");
         }
 
         if (_optopt >= carg.length()) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/SAGetoptException.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,33 @@
+/*
+ * 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 sun.jvm.hotspot;
+
+public class SAGetoptException extends IllegalArgumentException {
+
+    public SAGetoptException(String message) {
+        super(message);
+    }
+
+}
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/SALauncher.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/SALauncher.java	Wed Jul 05 21:37:42 2017 +0200
@@ -111,34 +111,31 @@
         return launcherHelp();
     }
 
-    private static void buildAttachArgs(ArrayList<String> newArgs,
-                                        String pid, String exe, String core) {
-        if ((pid == null) && (exe == null)) {
-            throw new IllegalArgumentException(
-                                     "You have to set --pid or --exe.");
+    private static void buildAttachArgs(ArrayList<String> newArgs, String pid,
+                                  String exe, String core, boolean allowEmpty) {
+        if (!allowEmpty && (pid == null) && (exe == null)) {
+            throw new SAGetoptException("You have to set --pid or --exe.");
         }
 
         if (pid != null) { // Attach to live process
             if (exe != null) {
-                throw new IllegalArgumentException(
-                                             "Unnecessary argument: --exe");
+                throw new SAGetoptException("Unnecessary argument: --exe");
             } else if (core != null) {
-                throw new IllegalArgumentException(
-                                             "Unnecessary argument: --core");
+                throw new SAGetoptException("Unnecessary argument: --core");
             } else if (!pid.matches("^\\d+$")) {
-                throw new IllegalArgumentException("Invalid pid: " + pid);
+                throw new SAGetoptException("Invalid pid: " + pid);
             }
 
             newArgs.add(pid);
-        } else {
+        } else if (exe != null) {
             if (exe.length() == 0) {
-                throw new IllegalArgumentException("You have to set --exe.");
+                throw new SAGetoptException("You have to set --exe.");
             }
 
             newArgs.add(exe);
 
             if ((core == null) || (core.length() == 0)) {
-                throw new IllegalArgumentException("You have to set --core.");
+                throw new SAGetoptException("You have to set --core.");
             }
 
             newArgs.add(core);
@@ -170,7 +167,7 @@
             }
         }
 
-        buildAttachArgs(newArgs, pid, exe, core);
+        buildAttachArgs(newArgs, pid, exe, core, true);
         CLHSDB.main(newArgs.toArray(new String[newArgs.size()]));
     }
 
@@ -199,7 +196,7 @@
             }
         }
 
-        buildAttachArgs(newArgs, pid, exe, core);
+        buildAttachArgs(newArgs, pid, exe, core, true);
         HSDB.main(newArgs.toArray(new String[newArgs.size()]));
     }
 
@@ -237,7 +234,7 @@
             }
         }
 
-        buildAttachArgs(newArgs, pid, exe, core);
+        buildAttachArgs(newArgs, pid, exe, core, false);
         JStack.main(newArgs.toArray(new String[newArgs.size()]));
     }
 
@@ -287,7 +284,7 @@
             }
         }
 
-        buildAttachArgs(newArgs, pid, exe, core);
+        buildAttachArgs(newArgs, pid, exe, core, false);
         JMap.main(newArgs.toArray(new String[newArgs.size()]));
     }
 
@@ -325,7 +322,7 @@
             }
         }
 
-        buildAttachArgs(newArgs, pid, exe, core);
+        buildAttachArgs(newArgs, pid, exe, core, false);
         JInfo.main(newArgs.toArray(new String[newArgs.size()]));
     }
 
@@ -358,7 +355,7 @@
             }
         }
 
-        buildAttachArgs(newArgs, pid, exe, core);
+        buildAttachArgs(newArgs, pid, exe, core, false);
         JSnap.main(newArgs.toArray(new String[newArgs.size()]));
     }
 
@@ -416,8 +413,8 @@
                 return;
             }
 
-            throw new IllegalArgumentException("Unknown tool: " + args[0]);
-        } catch (Exception e) {
+            throw new SAGetoptException("Unknown tool: " + args[0]);
+        } catch (SAGetoptException e) {
             System.err.println(e.getMessage());
             toolHelp(args[0]);
         }
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/interpreter/Bytecodes.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/interpreter/Bytecodes.java	Wed Jul 05 21:37:42 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2012, 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
@@ -253,29 +253,30 @@
   public static final int _fast_sgetfield       = 210;
   public static final int _fast_aputfield       = 211;
   public static final int _fast_bputfield       = 212;
-  public static final int _fast_cputfield       = 213;
-  public static final int _fast_dputfield       = 214;
-  public static final int _fast_fputfield       = 215;
-  public static final int _fast_iputfield       = 216;
-  public static final int _fast_lputfield       = 217;
-  public static final int _fast_sputfield       = 218;
-  public static final int _fast_aload_0         = 219;
-  public static final int _fast_iaccess_0       = 220;
-  public static final int _fast_aaccess_0       = 221;
-  public static final int _fast_faccess_0       = 222;
-  public static final int _fast_iload           = 223;
-  public static final int _fast_iload2          = 224;
-  public static final int _fast_icaload         = 225;
-  public static final int _fast_invokevfinal    = 226;
-  public static final int _fast_linearswitch    = 227;
-  public static final int _fast_binaryswitch    = 228;
-  public static final int _fast_aldc            = 229;
-  public static final int _fast_aldc_w          = 230;
-  public static final int _return_register_finalizer = 231;
-  public static final int _invokehandle         = 232;
-  public static final int _shouldnotreachhere   = 233; // For debugging
+  public static final int _fast_zputfield       = 213;
+  public static final int _fast_cputfield       = 214;
+  public static final int _fast_dputfield       = 215;
+  public static final int _fast_fputfield       = 216;
+  public static final int _fast_iputfield       = 217;
+  public static final int _fast_lputfield       = 218;
+  public static final int _fast_sputfield       = 219;
+  public static final int _fast_aload_0         = 220;
+  public static final int _fast_iaccess_0       = 221;
+  public static final int _fast_aaccess_0       = 222;
+  public static final int _fast_faccess_0       = 223;
+  public static final int _fast_iload           = 224;
+  public static final int _fast_iload2          = 225;
+  public static final int _fast_icaload         = 226;
+  public static final int _fast_invokevfinal    = 227;
+  public static final int _fast_linearswitch    = 228;
+  public static final int _fast_binaryswitch    = 229;
+  public static final int _fast_aldc            = 230;
+  public static final int _fast_aldc_w          = 231;
+  public static final int _return_register_finalizer = 232;
+  public static final int _invokehandle         = 233;
+  public static final int _shouldnotreachhere   = 234; // For debugging
 
-  public static final int number_of_codes       = 234;
+  public static final int number_of_codes       = 235;
 
   // Flag bits derived from format strings, can_trap, can_rewrite, etc.:
   // semantic flags:
@@ -776,6 +777,7 @@
 
     def(_fast_aputfield      , "fast_aputfield"      , "bJJ"  , null    , BasicType.getTObject() ,  0, true , _putfield       );
     def(_fast_bputfield      , "fast_bputfield"      , "bJJ"  , null    , BasicType.getTInt()    ,  0, true , _putfield       );
+    def(_fast_zputfield      , "fast_zputfield"      , "bJJ"  , null    , BasicType.getTInt()    ,  0, true , _putfield       );
     def(_fast_cputfield      , "fast_cputfield"      , "bJJ"  , null    , BasicType.getTChar()   ,  0, true , _putfield       );
     def(_fast_dputfield      , "fast_dputfield"      , "bJJ"  , null    , BasicType.getTDouble() ,  0, true , _putfield       );
     def(_fast_fputfield      , "fast_fputfield"      , "bJJ"  , null    , BasicType.getTFloat()  ,  0, true , _putfield       );
--- a/hotspot/src/os/aix/vm/os_aix.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/os/aix/vm/os_aix.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -3612,14 +3612,12 @@
     struct rlimit nbr_files;
     int status = getrlimit(RLIMIT_NOFILE, &nbr_files);
     if (status != 0) {
-      if (PrintMiscellaneous && (Verbose || WizardMode))
-        perror("os::init_2 getrlimit failed");
+      log_info(os)("os::init_2 getrlimit failed: %s", os::strerror(errno));
     } else {
       nbr_files.rlim_cur = nbr_files.rlim_max;
       status = setrlimit(RLIMIT_NOFILE, &nbr_files);
       if (status != 0) {
-        if (PrintMiscellaneous && (Verbose || WizardMode))
-          perror("os::init_2 setrlimit failed");
+        log_info(os)("os::init_2 setrlimit failed: %s", os::strerror(errno));
       }
     }
   }
--- a/hotspot/src/os/aix/vm/perfMemory_aix.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/os/aix/vm/perfMemory_aix.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -956,7 +956,7 @@
 #ifdef O_NOFOLLOW
   RESTARTABLE(::open(filename, oflags), result);
 #else
-  open_o_nofollow(filename, oflags);
+  result = open_o_nofollow(filename, oflags);
 #endif
 
   if (result == OS_ERR) {
--- a/hotspot/src/os/bsd/vm/os_bsd.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/os/bsd/vm/os_bsd.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -3459,25 +3459,13 @@
   guarantee(polling_page != MAP_FAILED, "os::init_2: failed to allocate polling page");
 
   os::set_polling_page(polling_page);
-
-#ifndef PRODUCT
-  if (Verbose && PrintMiscellaneous) {
-    tty->print("[SafePoint Polling address: " INTPTR_FORMAT "]\n",
-               (intptr_t)polling_page);
-  }
-#endif
+  log_info(os)("SafePoint Polling address: " INTPTR_FORMAT, p2i(polling_page));
 
   if (!UseMembar) {
     address mem_serialize_page = (address) ::mmap(NULL, Bsd::page_size(), PROT_READ | PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
     guarantee(mem_serialize_page != MAP_FAILED, "mmap Failed for memory serialize page");
     os::set_memory_serialize_page(mem_serialize_page);
-
-#ifndef PRODUCT
-    if (Verbose && PrintMiscellaneous) {
-      tty->print("[Memory Serialize  Page address: " INTPTR_FORMAT "]\n",
-                 (intptr_t)mem_serialize_page);
-    }
-#endif
+    log_info(os)("Memory Serialize Page address: " INTPTR_FORMAT, p2i(mem_serialize_page));
   }
 
   // initialize suspend/resume support - must do this before signal_sets_init()
@@ -3519,9 +3507,7 @@
     struct rlimit nbr_files;
     int status = getrlimit(RLIMIT_NOFILE, &nbr_files);
     if (status != 0) {
-      if (PrintMiscellaneous && (Verbose || WizardMode)) {
-        perror("os::init_2 getrlimit failed");
-      }
+      log_info(os)("os::init_2 getrlimit failed: %s", os::strerror(errno));
     } else {
       nbr_files.rlim_cur = nbr_files.rlim_max;
 
@@ -3534,9 +3520,7 @@
 
       status = setrlimit(RLIMIT_NOFILE, &nbr_files);
       if (status != 0) {
-        if (PrintMiscellaneous && (Verbose || WizardMode)) {
-          perror("os::init_2 setrlimit failed");
-        }
+        log_info(os)("os::init_2 setrlimit failed: %s", os::strerror(errno));
       }
     }
   }
@@ -3748,6 +3732,28 @@
   return ::stat(pathbuf, sbuf);
 }
 
+static inline struct timespec get_mtime(const char* filename) {
+  struct stat st;
+  int ret = os::stat(filename, &st);
+  assert(ret == 0, "failed to stat() file '%s': %s", filename, strerror(errno));
+#ifdef __APPLE__
+  return st.st_mtimespec;
+#else
+  return st.st_mtim;
+#endif
+}
+
+int os::compare_file_modified_times(const char* file1, const char* file2) {
+  struct timespec filetime1 = get_mtime(file1);
+  struct timespec filetime2 = get_mtime(file2);
+  int diff = filetime1.tv_sec - filetime2.tv_sec;
+  if (diff == 0) {
+    return filetime1.tv_nsec - filetime2.tv_nsec;
+  }
+  return diff;
+}
+
+
 bool os::check_heap(bool force) {
   return true;
 }
--- a/hotspot/src/os/linux/vm/os_linux.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/os/linux/vm/os_linux.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -2163,7 +2163,7 @@
         bool model_name_printed = false;
         if (strstr(buf, "model name") != NULL) {
           if (!model_name_printed) {
-            st->print_raw("\nCPU Model and flags from /proc/cpuinfo:\n");
+            st->print_raw("CPU Model and flags from /proc/cpuinfo:\n");
             st->print_raw(buf);
             model_name_printed = true;
           } else {
@@ -4671,25 +4671,13 @@
   guarantee(polling_page != MAP_FAILED, "os::init_2: failed to allocate polling page");
 
   os::set_polling_page(polling_page);
-
-#ifndef PRODUCT
-  if (Verbose && PrintMiscellaneous) {
-    tty->print("[SafePoint Polling address: " INTPTR_FORMAT "]\n",
-               (intptr_t)polling_page);
-  }
-#endif
+  log_info(os)("SafePoint Polling address: " INTPTR_FORMAT, p2i(polling_page));
 
   if (!UseMembar) {
     address mem_serialize_page = (address) ::mmap(NULL, Linux::page_size(), PROT_READ | PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
     guarantee(mem_serialize_page != MAP_FAILED, "mmap Failed for memory serialize page");
     os::set_memory_serialize_page(mem_serialize_page);
-
-#ifndef PRODUCT
-    if (Verbose && PrintMiscellaneous) {
-      tty->print("[Memory Serialize  Page address: " INTPTR_FORMAT "]\n",
-                 (intptr_t)mem_serialize_page);
-    }
-#endif
+    log_info(os)("Memory Serialize Page address: " INTPTR_FORMAT, p2i(mem_serialize_page));
   }
 
   // initialize suspend/resume support - must do this before signal_sets_init()
@@ -4732,10 +4720,8 @@
 #endif
 
   Linux::libpthread_init();
-  if (PrintMiscellaneous && (Verbose || WizardMode)) {
-    tty->print_cr("[HotSpot is running with %s, %s]\n",
-                  Linux::glibc_version(), Linux::libpthread_version());
-  }
+  log_info(os)("HotSpot is running with %s, %s",
+               Linux::glibc_version(), Linux::libpthread_version());
 
   if (UseNUMA) {
     if (!Linux::libnuma_init()) {
@@ -4776,16 +4762,12 @@
     struct rlimit nbr_files;
     int status = getrlimit(RLIMIT_NOFILE, &nbr_files);
     if (status != 0) {
-      if (PrintMiscellaneous && (Verbose || WizardMode)) {
-        perror("os::init_2 getrlimit failed");
-      }
+      log_info(os)("os::init_2 getrlimit failed: %s", os::strerror(errno));
     } else {
       nbr_files.rlim_cur = nbr_files.rlim_max;
       status = setrlimit(RLIMIT_NOFILE, &nbr_files);
       if (status != 0) {
-        if (PrintMiscellaneous && (Verbose || WizardMode)) {
-          perror("os::init_2 setrlimit failed");
-        }
+        log_info(os)("os::init_2 setrlimit failed: %s", os::strerror(errno));
       }
     }
   }
@@ -6026,7 +6008,22 @@
   return yes;
 }
 
-
+static inline struct timespec get_mtime(const char* filename) {
+  struct stat st;
+  int ret = os::stat(filename, &st);
+  assert(ret == 0, "failed to stat() file '%s': %s", filename, strerror(errno));
+  return st.st_mtim;
+}
+
+int os::compare_file_modified_times(const char* file1, const char* file2) {
+  struct timespec filetime1 = get_mtime(file1);
+  struct timespec filetime2 = get_mtime(file2);
+  int diff = filetime1.tv_sec - filetime2.tv_sec;
+  if (diff == 0) {
+    return filetime1.tv_nsec - filetime2.tv_nsec;
+  }
+  return diff;
+}
 
 /////////////// Unit tests ///////////////
 
--- a/hotspot/src/os/posix/vm/os_posix.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/os/posix/vm/os_posix.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -181,6 +181,10 @@
     return vsnprintf(buf, len, fmt, args);
 }
 
+int os::fileno(FILE* fp) {
+  return ::fileno(fp);
+}
+
 void os::Posix::print_load_average(outputStream* st) {
   st->print("load average:");
   double loadavg[3];
--- a/hotspot/src/os/solaris/vm/os_solaris.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/os/solaris/vm/os_solaris.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -161,6 +161,7 @@
 
 address os::Solaris::_main_stack_base = NULL;  // 4352906 workaround
 
+os::Solaris::pthread_setname_np_func_t os::Solaris::_pthread_setname_np = NULL;
 
 // "default" initializers for missing libc APIs
 extern "C" {
@@ -441,8 +442,15 @@
 }
 
 void os::set_native_thread_name(const char *name) {
-  // Not yet implemented.
-  return;
+  if (Solaris::_pthread_setname_np != NULL) {
+    // Only the first 31 bytes of 'name' are processed by pthread_setname_np
+    // but we explicitly copy into a size-limited buffer to avoid any
+    // possible overflow.
+    char buf[32];
+    snprintf(buf, sizeof(buf), "%s", name);
+    buf[sizeof(buf) - 1] = '\0';
+    Solaris::_pthread_setname_np(pthread_self(), buf);
+  }
 }
 
 bool os::distribute_processes(uint length, uint* distribution) {
@@ -1819,6 +1827,19 @@
   return ::stat(pathbuf, sbuf);
 }
 
+static inline time_t get_mtime(const char* filename) {
+  struct stat st;
+  int ret = os::stat(filename, &st);
+  assert(ret == 0, "failed to stat() file '%s': %s", filename, strerror(errno));
+  return st.st_mtime;
+}
+
+int os::compare_file_modified_times(const char* file1, const char* file2) {
+  time_t t1 = get_mtime(file1);
+  time_t t2 = get_mtime(file2);
+  return t1 - t2;
+}
+
 static bool _print_ascii_file(const char* filename, outputStream* st) {
   int fd = ::open(filename, O_RDONLY);
   if (fd == -1) {
@@ -2754,13 +2775,13 @@
     pd_unmap_memory(addr, bytes);
   }
 
-  if (PrintMiscellaneous && Verbose) {
+  if (log_is_enabled(Warning, os)) {
     char buf[256];
     buf[0] = '\0';
     if (addr == NULL) {
       jio_snprintf(buf, sizeof(buf), ": %s", os::strerror(err));
     }
-    warning("attempt_reserve_memory_at: couldn't reserve " SIZE_FORMAT " bytes at "
+    log_info(os)("attempt_reserve_memory_at: couldn't reserve " SIZE_FORMAT " bytes at "
             PTR_FORMAT ": reserve_memory_helper returned " PTR_FORMAT
             "%s", bytes, requested_addr, addr, buf);
   }
@@ -2790,9 +2811,7 @@
           assert(i > 0, "gap adjustment code problem");
           have_adjusted_gap = true;  // adjust the gap only once, just in case
           gap = actual_gap;
-          if (PrintMiscellaneous && Verbose) {
-            warning("attempt_reserve_memory_at: adjusted gap to 0x%lx", gap);
-          }
+          log_info(os)("attempt_reserve_memory_at: adjusted gap to 0x%lx", gap);
           unmap_memory(base[i], bytes);
           unmap_memory(base[i-1], size[i-1]);
           i-=2;
@@ -2824,8 +2843,8 @@
       } else {
         size_t bottom_overlap = base[i] + bytes - requested_addr;
         if (bottom_overlap >= 0 && bottom_overlap < bytes) {
-          if (PrintMiscellaneous && Verbose && bottom_overlap == 0) {
-            warning("attempt_reserve_memory_at: possible alignment bug");
+          if (bottom_overlap == 0) {
+            log_info(os)("attempt_reserve_memory_at: possible alignment bug");
           }
           unmap_memory(requested_addr, bottom_overlap);
           size[i] = bytes - bottom_overlap;
@@ -4355,8 +4374,8 @@
 void init_pset_getloadavg_ptr(void) {
   pset_getloadavg_ptr =
     (pset_getloadavg_type)dlsym(RTLD_DEFAULT, "pset_getloadavg");
-  if (PrintMiscellaneous && Verbose && pset_getloadavg_ptr == NULL) {
-    warning("pset_getloadavg function not found");
+  if (pset_getloadavg_ptr == NULL) {
+    log_warning(os)("pset_getloadavg function not found");
   }
 }
 
@@ -4412,6 +4431,13 @@
   // 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);
+
+  // retrieve entry point for pthread_setname_np
+  void * handle = dlopen("libc.so.1", RTLD_LAZY);
+  if (handle != NULL) {
+    Solaris::_pthread_setname_np =
+        (Solaris::pthread_setname_np_func_t)dlsym(handle, "pthread_setname_np");
+  }
 }
 
 // To install functions for atexit system call
@@ -4439,25 +4465,13 @@
   }
 
   os::set_polling_page(polling_page);
-
-#ifndef PRODUCT
-  if (Verbose && PrintMiscellaneous) {
-    tty->print("[SafePoint Polling address: " INTPTR_FORMAT "]\n",
-               (intptr_t)polling_page);
-  }
-#endif
+  log_info(os)("SafePoint Polling address: " INTPTR_FORMAT, p2i(polling_page));
 
   if (!UseMembar) {
     address mem_serialize_page = (address)Solaris::mmap_chunk(NULL, page_size, MAP_PRIVATE, PROT_READ | PROT_WRITE);
     guarantee(mem_serialize_page != NULL, "mmap Failed for memory serialize page");
     os::set_memory_serialize_page(mem_serialize_page);
-
-#ifndef PRODUCT
-    if (Verbose && PrintMiscellaneous) {
-      tty->print("[Memory Serialize  Page address: " INTPTR_FORMAT "]\n",
-                 (intptr_t)mem_serialize_page);
-    }
-#endif
+    log_info(os)("Memory Serialize Page address: " INTPTR_FORMAT, p2i(mem_serialize_page));
   }
 
   // Check minimum allowable stack size for thread creation and to initialize
@@ -4537,16 +4551,12 @@
     struct rlimit nbr_files;
     int status = getrlimit(RLIMIT_NOFILE, &nbr_files);
     if (status != 0) {
-      if (PrintMiscellaneous && (Verbose || WizardMode)) {
-        perror("os::init_2 getrlimit failed");
-      }
+      log_info(os)("os::init_2 getrlimit failed: %s", os::strerror(errno));
     } else {
       nbr_files.rlim_cur = nbr_files.rlim_max;
       status = setrlimit(RLIMIT_NOFILE, &nbr_files);
       if (status != 0) {
-        if (PrintMiscellaneous && (Verbose || WizardMode)) {
-          perror("os::init_2 setrlimit failed");
-        }
+        log_info(os)("os::init_2 setrlimit failed: %s", os::strerror(errno));
       }
     }
   }
--- a/hotspot/src/os/solaris/vm/os_solaris.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/os/solaris/vm/os_solaris.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -122,6 +122,9 @@
   static int _SIGasync;                      // user-overridable ASYNC_SIGNAL
   static void set_SIGasync(int newsig) { _SIGasync = newsig; }
 
+  typedef int (*pthread_setname_np_func_t)(pthread_t, const char*);
+  static pthread_setname_np_func_t _pthread_setname_np;
+
  public:
   // Large Page Support--ISM.
   static bool largepage_range(char* addr, size_t size);
--- a/hotspot/src/os/windows/vm/os_windows.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/os/windows/vm/os_windows.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -1594,6 +1594,19 @@
   return ret;
 }
 
+static inline time_t get_mtime(const char* filename) {
+  struct stat st;
+  int ret = os::stat(filename, &st);
+  assert(ret == 0, "failed to stat() file '%s': %s", filename, strerror(errno));
+  return st.st_mtime;
+}
+
+int os::compare_file_modified_times(const char* file1, const char* file2) {
+  time_t t1 = get_mtime(file1);
+  time_t t2 = get_mtime(file2);
+  return t1 - t2;
+}
+
 void os::print_os_info_brief(outputStream* st) {
   os::print_os_info(st);
 }
@@ -2436,14 +2449,10 @@
           bool res = os::protect_memory((char*) page_start, page_size,
                                         os::MEM_PROT_RWX);
 
-          if (PrintMiscellaneous && Verbose) {
-            char buf[256];
-            jio_snprintf(buf, sizeof(buf), "Execution protection violation "
-                         "at " INTPTR_FORMAT
-                         ", unguarding " INTPTR_FORMAT ": %s", addr,
-                         page_start, (res ? "success" : os::strerror(errno)));
-            tty->print_raw_cr(buf);
-          }
+          log_debug(os)("Execution protection violation "
+                        "at " INTPTR_FORMAT
+                        ", unguarding " INTPTR_FORMAT ": %s", p2i(addr),
+                        p2i(page_start), (res ? "success" : os::strerror(errno)));
 
           // Set last_addr so if we fault again at the same address, we don't
           // end up in an endless loop.
@@ -2896,12 +2905,12 @@
   NUMAInterleaveGranularity = align_size_up(NUMAInterleaveGranularity, min_interleave_granularity);
 
   if (numa_node_list_holder.build()) {
-    if (PrintMiscellaneous && Verbose) {
-      tty->print("NUMA UsedNodeCount=%d, namely ", numa_node_list_holder.get_count());
+    if (log_is_enabled(Debug, os, cpu)) {
+      Log(os, cpu) log;
+      log.debug("NUMA UsedNodeCount=%d, namely ", numa_node_list_holder.get_count());
       for (int i = 0; i < numa_node_list_holder.get_count(); i++) {
-        tty->print("%d ", numa_node_list_holder.get_node_list_entry(i));
+        log.debug("  %d ", numa_node_list_holder.get_node_list_entry(i));
       }
-      tty->print("\n");
     }
     success = true;
   } else {
@@ -3010,9 +3019,7 @@
       }
 #ifdef ASSERT
       if (should_inject_error) {
-        if (TracePageSizes && Verbose) {
-          tty->print_cr("Reserving pages individually failed.");
-        }
+        log_develop_debug(pagesize)("Reserving pages individually failed.");
       }
 #endif
       return NULL;
@@ -3196,9 +3203,8 @@
   // 1) the UseLargePagesIndividualAllocation flag is set (set by default on WS2003)
   // 2) NUMA Interleaving is enabled, in which case we use a different node for each page
   if (UseLargePagesIndividualAllocation || UseNUMAInterleaving) {
-    if (TracePageSizes && Verbose) {
-      tty->print_cr("Reserving large pages individually.");
-    }
+    log_debug(pagesize)("Reserving large pages individually.");
+
     char * p_buf = allocate_pages_individually(bytes, addr, flags, prot, LargePagesIndividualAllocationInjectError);
     if (p_buf == NULL) {
       // give an appropriate warning message
@@ -3215,9 +3221,8 @@
     return p_buf;
 
   } else {
-    if (TracePageSizes && Verbose) {
-      tty->print_cr("Reserving large pages in a single large chunk.");
-    }
+    log_debug(pagesize)("Reserving large pages in a single large chunk.");
+
     // normal policy just allocate it all at once
     DWORD flag = MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES;
     char * res = (char *)VirtualAlloc(addr, bytes, flag, prot);
@@ -4119,13 +4124,7 @@
   guarantee(return_page != NULL, "Commit Failed for polling page");
 
   os::set_polling_page(polling_page);
-
-#ifndef PRODUCT
-  if (Verbose && PrintMiscellaneous) {
-    tty->print("[SafePoint Polling address: " INTPTR_FORMAT "]\n",
-               (intptr_t)polling_page);
-  }
-#endif
+  log_info(os)("SafePoint Polling address: " INTPTR_FORMAT, p2i(polling_page));
 
   if (!UseMembar) {
     address mem_serialize_page = (address)VirtualAlloc(NULL, os::vm_page_size(), MEM_RESERVE, PAGE_READWRITE);
@@ -4135,13 +4134,7 @@
     guarantee(return_page != NULL, "Commit Failed for memory serialize page");
 
     os::set_memory_serialize_page(mem_serialize_page);
-
-#ifndef PRODUCT
-    if (Verbose && PrintMiscellaneous) {
-      tty->print("[Memory Serialize  Page address: " INTPTR_FORMAT "]\n",
-                 (intptr_t)mem_serialize_page);
-    }
-#endif
+    log_info(os)("Memory Serialize Page address: " INTPTR_FORMAT, p2i(mem_serialize_page));
   }
 
   // Setup Windows Exceptions
@@ -4609,6 +4602,9 @@
   return 0;
 }
 
+int os::fileno(FILE* fp) {
+  return _fileno(fp);
+}
 
 // This code is a copy of JDK's sysSync
 // from src/windows/hpi/src/sys_api_md.c
@@ -4769,10 +4765,7 @@
   hFile = CreateFile(file_name, GENERIC_READ, FILE_SHARE_READ, NULL,
                      OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
   if (hFile == NULL) {
-    if (PrintMiscellaneous && Verbose) {
-      DWORD err = GetLastError();
-      tty->print_cr("CreateFile() failed: GetLastError->%ld.", err);
-    }
+    log_info(os)("CreateFile() failed: GetLastError->%ld.", GetLastError());
     return NULL;
   }
 
@@ -4790,10 +4783,7 @@
     base = (char*) VirtualAlloc(addr, bytes, MEM_COMMIT | MEM_RESERVE,
                                 PAGE_READWRITE);
     if (base == NULL) {
-      if (PrintMiscellaneous && Verbose) {
-        DWORD err = GetLastError();
-        tty->print_cr("VirtualAlloc() failed: GetLastError->%ld.", err);
-      }
+      log_info(os)("VirtualAlloc() failed: GetLastError->%ld.", GetLastError());
       CloseHandle(hFile);
       return NULL;
     }
@@ -4807,10 +4797,7 @@
     // number of bytes were read before returning.
     bool res = ReadFile(hFile, base, (DWORD)bytes, &bytes_read, &overlapped) != 0;
     if (!res) {
-      if (PrintMiscellaneous && Verbose) {
-        DWORD err = GetLastError();
-        tty->print_cr("ReadFile() failed: GetLastError->%ld.", err);
-      }
+      log_info(os)("ReadFile() failed: GetLastError->%ld.", GetLastError());
       release_memory(base, bytes);
       CloseHandle(hFile);
       return NULL;
@@ -4819,10 +4806,7 @@
     HANDLE hMap = CreateFileMapping(hFile, NULL, PAGE_WRITECOPY, 0, 0,
                                     NULL /* file_name */);
     if (hMap == NULL) {
-      if (PrintMiscellaneous && Verbose) {
-        DWORD err = GetLastError();
-        tty->print_cr("CreateFileMapping() failed: GetLastError->%ld.", err);
-      }
+      log_info(os)("CreateFileMapping() failed: GetLastError->%ld.", GetLastError());
       CloseHandle(hFile);
       return NULL;
     }
@@ -4831,20 +4815,14 @@
     base = (char*)MapViewOfFileEx(hMap, access, 0, (DWORD)file_offset,
                                   (DWORD)bytes, addr);
     if (base == NULL) {
-      if (PrintMiscellaneous && Verbose) {
-        DWORD err = GetLastError();
-        tty->print_cr("MapViewOfFileEx() failed: GetLastError->%ld.", err);
-      }
+      log_info(os)("MapViewOfFileEx() failed: GetLastError->%ld.", GetLastError());
       CloseHandle(hMap);
       CloseHandle(hFile);
       return NULL;
     }
 
     if (CloseHandle(hMap) == 0) {
-      if (PrintMiscellaneous && Verbose) {
-        DWORD err = GetLastError();
-        tty->print_cr("CloseHandle(hMap) failed: GetLastError->%ld.", err);
-      }
+      log_info(os)("CloseHandle(hMap) failed: GetLastError->%ld.", GetLastError());
       CloseHandle(hFile);
       return base;
     }
@@ -4856,10 +4834,7 @@
     bool res = VirtualProtect(base, bytes, exec_access, &old_protect) != 0;
 
     if (!res) {
-      if (PrintMiscellaneous && Verbose) {
-        DWORD err = GetLastError();
-        tty->print_cr("VirtualProtect() failed: GetLastError->%ld.", err);
-      }
+      log_info(os)("VirtualProtect() failed: GetLastError->%ld.", GetLastError());
       // Don't consider this a hard error, on IA32 even if the
       // VirtualProtect fails, we should still be able to execute
       CloseHandle(hFile);
@@ -4868,10 +4843,7 @@
   }
 
   if (CloseHandle(hFile) == 0) {
-    if (PrintMiscellaneous && Verbose) {
-      DWORD err = GetLastError();
-      tty->print_cr("CloseHandle(hFile) failed: GetLastError->%ld.", err);
-    }
+    log_info(os)("CloseHandle(hFile) failed: GetLastError->%ld.", GetLastError());
     return base;
   }
 
@@ -4904,10 +4876,7 @@
 bool os::pd_unmap_memory(char* addr, size_t bytes) {
   MEMORY_BASIC_INFORMATION mem_info;
   if (VirtualQuery(addr, &mem_info, sizeof(mem_info)) == 0) {
-    if (PrintMiscellaneous && Verbose) {
-      DWORD err = GetLastError();
-      tty->print_cr("VirtualQuery() failed: GetLastError->%ld.", err);
-    }
+    log_info(os)("VirtualQuery() failed: GetLastError->%ld.", GetLastError());
     return false;
   }
 
@@ -4924,10 +4893,7 @@
 
   BOOL result = UnmapViewOfFile(addr);
   if (result == 0) {
-    if (PrintMiscellaneous && Verbose) {
-      DWORD err = GetLastError();
-      tty->print_cr("UnmapViewOfFile() failed: GetLastError->%ld.", err);
-    }
+    log_info(os)("UnmapViewOfFile() failed: GetLastError->%ld.", GetLastError());
     return false;
   }
   return true;
--- a/hotspot/src/os_cpu/aix_ppc/vm/os_aix_ppc.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/os_cpu/aix_ppc/vm/os_aix_ppc.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2012, 2014 SAP SE. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -184,9 +184,7 @@
     if (os::Aix::chained_handler(sig, info, ucVoid)) {
       return 1;
     } else {
-      if (PrintMiscellaneous && (WizardMode || Verbose)) {
-        warning("Ignoring SIGPIPE - see bug 4229104");
-      }
+      // Ignoring SIGPIPE - see bugs 4229104
       return 1;
     }
   }
--- a/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp	Wed Jul 05 21:37:42 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
@@ -469,11 +469,7 @@
     if (os::Bsd::chained_handler(sig, info, ucVoid)) {
       return true;
     } else {
-      if (PrintMiscellaneous && (WizardMode || Verbose)) {
-        char buf[64];
-        warning("Ignoring %s - see bugs 4229104 or 646499219",
-                os::exception_name(sig, buf, sizeof(buf)));
-      }
+      // Ignoring SIGPIPE/SIGXFSZ - see bugs 4229104 or 6499219
       return true;
     }
   }
@@ -728,14 +724,10 @@
         bool res = os::protect_memory((char*) page_start, page_size,
                                       os::MEM_PROT_RWX);
 
-        if (PrintMiscellaneous && Verbose) {
-          char buf[256];
-          jio_snprintf(buf, sizeof(buf), "Execution protection violation "
-                       "at " INTPTR_FORMAT
-                       ", unguarding " INTPTR_FORMAT ": %s, errno=%d", addr,
-                       page_start, (res ? "success" : "failed"), errno);
-          tty->print_raw_cr(buf);
-        }
+        log_debug(os)("Execution protection violation "
+                      "at " INTPTR_FORMAT
+                      ", unguarding " INTPTR_FORMAT ": %s, errno=%d", p2i(addr),
+                      p2i(page_start), (res ? "success" : "failed"), errno);
         stub = pc;
 
         // Set last_addr so if we fault again at the same address, we don't end
--- a/hotspot/src/os_cpu/bsd_x86/vm/thread_bsd_x86.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/os_cpu/bsd_x86/vm/thread_bsd_x86.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "memory/metaspaceShared.hpp"
 #include "runtime/frame.inline.hpp"
 #include "runtime/thread.inline.hpp"
 
@@ -64,6 +65,14 @@
       return false;
     }
 
+#if INCLUDE_CDS
+    if (UseSharedSpaces && MetaspaceShared::is_in_shared_region(addr.pc(), MetaspaceShared::md)) {
+      // In the middle of a trampoline call. Bail out for safety.
+      // This happens rarely so shouldn't affect profiling.
+      return false;
+    }
+#endif
+
     frame ret_frame(ret_sp, ret_fp, addr.pc());
     if (!ret_frame.safe_for_sender(jt)) {
 #if defined(COMPILER2) || INCLUDE_JVMCI
--- a/hotspot/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp	Wed Jul 05 21:37:42 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.
  * Copyright 2007, 2008, 2009, 2010 Red Hat, Inc.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -159,11 +159,7 @@
     if (os::Bsd::chained_handler(sig, info, ucVoid)) {
       return true;
     } else {
-      if (PrintMiscellaneous && (WizardMode || Verbose)) {
-        char buf[64];
-        warning("Ignoring %s - see bugs 4229104 or 646499219",
-                os::exception_name(sig, buf, sizeof(buf)));
-      }
+      // Ignoring SIGPIPE/SIGXFSZ - see bugs 4229104 or 6499219
       return true;
     }
   }
--- a/hotspot/src/os_cpu/linux_aarch64/vm/os_linux_aarch64.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/os_cpu/linux_aarch64/vm/os_linux_aarch64.cpp	Wed Jul 05 21:37:42 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) 2014, Red Hat Inc. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -270,11 +270,7 @@
     if (os::Linux::chained_handler(sig, info, ucVoid)) {
       return true;
     } else {
-      if (PrintMiscellaneous && (WizardMode || Verbose)) {
-        char buf[64];
-        warning("Ignoring %s - see bugs 4229104 or 646499219",
-                os::exception_name(sig, buf, sizeof(buf)));
-      }
+      // Ignoring SIGPIPE/SIGXFSZ - see bugs 4229104 or 6499219
       return true;
     }
   }
--- a/hotspot/src/os_cpu/linux_aarch64/vm/thread_linux_aarch64.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/os_cpu/linux_aarch64/vm/thread_linux_aarch64.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -24,6 +24,7 @@
  */
 
 #include "precompiled.hpp"
+#include "memory/metaspaceShared.hpp"
 #include "runtime/frame.inline.hpp"
 #include "runtime/thread.inline.hpp"
 
@@ -66,6 +67,14 @@
       return false;
     }
 
+#if INCLUDE_CDS
+    if (UseSharedSpaces && MetaspaceShared::is_in_shared_region(addr.pc(), MetaspaceShared::md)) {
+      // In the middle of a trampoline call. Bail out for safety.
+      // This happens rarely so shouldn't affect profiling.
+      return false;
+    }
+#endif
+
     frame ret_frame(ret_sp, ret_fp, addr.pc());
     if (!ret_frame.safe_for_sender(jt)) {
 #ifdef COMPILER2
--- a/hotspot/src/os_cpu/linux_ppc/vm/os_linux_ppc.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/os_cpu/linux_ppc/vm/os_linux_ppc.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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.
  *
@@ -198,9 +198,7 @@
     if (os::Linux::chained_handler(sig, info, ucVoid)) {
       return true;
     } else {
-      if (PrintMiscellaneous && (WizardMode || Verbose)) {
-        warning("Ignoring SIGPIPE - see bug 4229104");
-      }
+      // Ignoring SIGPIPE - see bugs 4229104
       return true;
     }
   }
--- a/hotspot/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp	Wed Jul 05 21:37:42 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
@@ -561,11 +561,7 @@
     if (os::Linux::chained_handler(sig, info, ucVoid)) {
       return true;
     } else {
-      if (PrintMiscellaneous && (WizardMode || Verbose)) {
-        char buf[64];
-        warning("Ignoring %s - see bugs 4229104 or 646499219",
-                os::exception_name(sig, buf, sizeof(buf)));
-      }
+      // Ignoring SIGPIPE/SIGXFSZ - see bugs 4229104 or 6499219
       return true;
     }
   }
--- a/hotspot/src/os_cpu/linux_sparc/vm/thread_linux_sparc.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/os_cpu/linux_sparc/vm/thread_linux_sparc.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "memory/metaspaceShared.hpp"
 #include "runtime/frame.inline.hpp"
 #include "runtime/thread.inline.hpp"
 
@@ -64,6 +65,14 @@
     return false;
   }
 
+#if INCLUDE_CDS
+  if (UseSharedSpaces && MetaspaceShared::is_in_shared_region(addr.pc(), MetaspaceShared::md)) {
+    // In the middle of a trampoline call. Bail out for safety.
+    // This happens rarely so shouldn't affect profiling.
+    return false;
+  }
+#endif
+
   // we were running Java code when SIGPROF came in
   if (isInJava) {
     // If we have a last_Java_sp, then the SIGPROF signal caught us
--- a/hotspot/src/os_cpu/linux_sparc/vm/vm_version_linux_sparc.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/os_cpu/linux_sparc/vm/vm_version_linux_sparc.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 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
@@ -66,12 +66,12 @@
   features = generic_v9_m;
 
   if (detect_niagara()) {
-    if (PrintMiscellaneous && Verbose) { tty->print_cr("Detected Linux on Niagara"); }
+    log_info(os, cpu)("Detected Linux on Niagara");
     features = niagara1_m | T_family_m;
   }
 
   if (detect_M_family()) {
-    if (PrintMiscellaneous && Verbose) { tty->print_cr("Detected Linux on M family"); }
+    log_info(os, cpu)("Detected Linux on M family");
     features = sun4v_m | generic_v9_m | M_family_m | T_family_m;
   }
 
--- a/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp	Wed Jul 05 21:37:42 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
@@ -287,11 +287,7 @@
     if (os::Linux::chained_handler(sig, info, ucVoid)) {
       return true;
     } else {
-      if (PrintMiscellaneous && (WizardMode || Verbose)) {
-        char buf[64];
-        warning("Ignoring %s - see bugs 4229104 or 646499219",
-                os::exception_name(sig, buf, sizeof(buf)));
-      }
+      // Ignoring SIGPIPE/SIGXFSZ - see bugs 4229104 or 6499219
       return true;
     }
   }
@@ -542,14 +538,10 @@
         bool res = os::protect_memory((char*) page_start, page_size,
                                       os::MEM_PROT_RWX);
 
-        if (PrintMiscellaneous && Verbose) {
-          char buf[256];
-          jio_snprintf(buf, sizeof(buf), "Execution protection violation "
-                       "at " INTPTR_FORMAT
-                       ", unguarding " INTPTR_FORMAT ": %s, errno=%d", addr,
-                       page_start, (res ? "success" : "failed"), errno);
-          tty->print_raw_cr(buf);
-        }
+        log_debug(os)("Execution protection violation "
+                      "at " INTPTR_FORMAT
+                      ", unguarding " INTPTR_FORMAT ": %s, errno=%d", p2i(addr),
+                      p2i(page_start), (res ? "success" : "failed"), errno);
         stub = pc;
 
         // Set last_addr so if we fault again at the same address, we don't end
@@ -645,12 +637,8 @@
   int major = strtol(uts.release,&minor_string,10);
   int minor = strtol(minor_string+1,NULL,10);
   bool result = (major > 2 || (major==2 && minor >= 4));
-#ifndef PRODUCT
-  if (PrintMiscellaneous && Verbose) {
-    tty->print("OS version is %d.%d, which %s support SSE/SSE2\n",
+  log_info(os)("OS version is %d.%d, which %s support SSE/SSE2",
                major,minor, result ? "DOES" : "does NOT");
-  }
-#endif
   return result;
 #endif // AMD64
 }
@@ -939,9 +927,7 @@
 
   MemTracker::record_virtual_memory_type((address)codebuf, mtInternal);
 
-  if (PrintMiscellaneous && (Verbose || WizardMode)) {
-     tty->print_cr("[CS limit NX emulation work-around, exec code at: %p]", codebuf);
-  }
+  log_info(os)("[CS limit NX emulation work-around, exec code at: %p]", codebuf);
 
   // Some code to exec: the 'ret' instruction
   codebuf[0] = 0xC3;
--- a/hotspot/src/os_cpu/linux_x86/vm/thread_linux_x86.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/os_cpu/linux_x86/vm/thread_linux_x86.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "memory/metaspaceShared.hpp"
 #include "runtime/frame.inline.hpp"
 #include "runtime/thread.inline.hpp"
 
@@ -65,6 +66,14 @@
       return false;
     }
 
+#if INCLUDE_CDS
+    if (UseSharedSpaces && MetaspaceShared::is_in_shared_region(addr.pc(), MetaspaceShared::md)) {
+      // In the middle of a trampoline call. Bail out for safety.
+      // This happens rarely so shouldn't affect profiling.
+      return false;
+    }
+#endif
+
     frame ret_frame(ret_sp, ret_fp, addr.pc());
     if (!ret_frame.safe_for_sender(jt)) {
 #if defined(COMPILER2) || INCLUDE_JVMCI
--- a/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -154,11 +154,7 @@
     if (os::Linux::chained_handler(sig, info, ucVoid)) {
       return true;
     } else {
-      if (PrintMiscellaneous && (WizardMode || Verbose)) {
-        char buf[64];
-        warning("Ignoring %s - see bugs 4229104 or 646499219",
-                os::exception_name(sig, buf, sizeof(buf)));
-      }
+      // Ignoring SIGPIPE/SIGXFSZ - see bugs 4229104 or 6499219
       return true;
     }
   }
--- a/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp	Wed Jul 05 21:37:42 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
@@ -338,12 +338,7 @@
     if (os::Solaris::chained_handler(sig, info, ucVoid)) {
       return true;
     } else {
-      if (PrintMiscellaneous && (WizardMode || Verbose)) {
-        char buf[64];
-        warning("Ignoring %s - see 4229104 or 6499219",
-                os::exception_name(sig, buf, sizeof(buf)));
-
-      }
+      // Ignoring SIGPIPE/SIGXFSZ - see bugs 4229104 or 6499219
       return true;
     }
   }
--- a/hotspot/src/os_cpu/solaris_sparc/vm/thread_solaris_sparc.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/os_cpu/solaris_sparc/vm/thread_solaris_sparc.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "memory/metaspaceShared.hpp"
 #include "runtime/frame.inline.hpp"
 #include "runtime/thread.inline.hpp"
 
@@ -77,6 +78,14 @@
     return false;
   }
 
+#if INCLUDE_CDS
+  if (UseSharedSpaces && MetaspaceShared::is_in_shared_region(addr.pc(), MetaspaceShared::md)) {
+    // In the middle of a trampoline call. Bail out for safety.
+    // This happens rarely so shouldn't affect profiling.
+    return false;
+  }
+#endif
+
   frame ret_frame(ret_sp, frame::unpatchable, addr.pc());
 
   // we were running Java code when SIGPROF came in
--- a/hotspot/src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 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,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "logging/log.hpp"
 #include "memory/allocation.hpp"
 #include "memory/allocation.inline.hpp"
 #include "runtime/os.hpp"
@@ -361,15 +362,10 @@
   assert(avn <= 2, "should return two or less av's");
   uint_t av = avs[0];
 
-#ifndef PRODUCT
-  if (PrintMiscellaneous && Verbose) {
-    tty->print("getisax(2) returned: " PTR32_FORMAT, av);
-    if (avn > 1) {
-      tty->print(", " PTR32_FORMAT, avs[1]);
-    }
-    tty->cr();
+  log_info(os, cpu)("getisax(2) returned: " PTR32_FORMAT, av);
+  if (avn > 1) {
+    log_info(os, cpu)(" " PTR32_FORMAT, avs[1]);
   }
-#endif
 
   if (av & AV_SPARC_MUL32)  features |= hardware_mul32_m;
   if (av & AV_SPARC_DIV32)  features |= hardware_div32_m;
@@ -464,11 +460,7 @@
           if (strcmp((const char*)&(knm[i].name),"implementation") == 0) {
             implementation = KSTAT_NAMED_STR_PTR(&knm[i]);
             has_implementation = true;
-#ifndef PRODUCT
-            if (PrintMiscellaneous && Verbose) {
-              tty->print_cr("cpu_info.implementation: %s", implementation);
-            }
-#endif
+            log_info(os, cpu)("cpu_info.implementation: %s", implementation);
             features |= parse_features(implementation);
             break;
           }
--- a/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp	Wed Jul 05 21:37:42 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
@@ -403,12 +403,7 @@
     if (os::Solaris::chained_handler(sig, info, ucVoid)) {
       return true;
     } else {
-      if (PrintMiscellaneous && (WizardMode || Verbose)) {
-        char buf[64];
-        warning("Ignoring %s - see 4229104 or 6499219",
-                os::exception_name(sig, buf, sizeof(buf)));
-
-      }
+      // Ignoring SIGPIPE/SIGXFSZ - see bugs 4229104 or 6499219
       return true;
     }
   }
@@ -640,14 +635,10 @@
         bool res = os::protect_memory((char*) page_start, page_size,
                                       os::MEM_PROT_RWX);
 
-        if (PrintMiscellaneous && Verbose) {
-          char buf[256];
-          jio_snprintf(buf, sizeof(buf), "Execution protection violation "
-                       "at " INTPTR_FORMAT
-                       ", unguarding " INTPTR_FORMAT ": %s, errno=%d", addr,
-                       page_start, (res ? "success" : "failed"), errno);
-          tty->print_raw_cr(buf);
-        }
+        log_debug(os)("Execution protection violation "
+                      "at " INTPTR_FORMAT
+                      ", unguarding " INTPTR_FORMAT ": %s, errno=%d", p2i(addr),
+                      p2i(page_start), (res ? "success" : "failed"), errno);
         stub = pc;
 
         // Set last_addr so if we fault again at the same address, we don't end
--- a/hotspot/src/os_cpu/solaris_x86/vm/thread_solaris_x86.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/os_cpu/solaris_x86/vm/thread_solaris_x86.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "memory/metaspaceShared.hpp"
 #include "runtime/frame.inline.hpp"
 #include "runtime/thread.inline.hpp"
 
@@ -70,6 +71,14 @@
     return false;
   }
 
+#if INCLUDE_CDS
+  if (UseSharedSpaces && MetaspaceShared::is_in_shared_region(addr.pc(), MetaspaceShared::md)) {
+    // In the middle of a trampoline call. Bail out for safety.
+    // This happens rarely so shouldn't affect profiling.
+    return false;
+  }
+#endif
+
   // If sp and fp are nonsense just leave them out
 
   if (!jt->on_local_stack((address)ret_sp)) {
--- a/hotspot/src/os_cpu/windows_x86/vm/thread_windows_x86.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/os_cpu/windows_x86/vm/thread_windows_x86.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "memory/metaspaceShared.hpp"
 #include "runtime/frame.inline.hpp"
 #include "runtime/thread.inline.hpp"
 
@@ -72,6 +73,14 @@
       return false;
     }
 
+#if INCLUDE_CDS
+    if (UseSharedSpaces && MetaspaceShared::is_in_shared_region(addr.pc(), MetaspaceShared::md)) {
+      // In the middle of a trampoline call. Bail out for safety.
+      // This happens rarely so shouldn't affect profiling.
+      return false;
+    }
+#endif
+
     frame ret_frame(ret_sp, ret_fp, addr.pc());
     if (!ret_frame.safe_for_sender(jt)) {
 #if defined(COMPILER2) || INCLUDE_JVMCI
--- a/hotspot/src/share/vm/asm/assembler.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/asm/assembler.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -33,7 +33,6 @@
 #include "runtime/vm_version.hpp"
 #include "utilities/debug.hpp"
 #include "utilities/growableArray.hpp"
-#include "utilities/top.hpp"
 
 // This file contains platform-independent assembler declarations.
 
--- a/hotspot/src/share/vm/asm/register.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/asm/register.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -25,7 +25,8 @@
 #ifndef SHARE_VM_ASM_REGISTER_HPP
 #define SHARE_VM_ASM_REGISTER_HPP
 
-#include "utilities/top.hpp"
+#include "utilities/debug.hpp"
+#include "utilities/globalDefinitions.hpp"
 
 // Use AbstractRegister as shortcut
 class AbstractRegisterImpl;
--- a/hotspot/src/share/vm/c1/c1_Canonicalizer.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/c1/c1_Canonicalizer.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -305,7 +305,8 @@
     // limit this optimization to current block
     if (value != NULL && in_current_block(conv)) {
       set_canonical(new StoreIndexed(x->array(), x->index(), x->length(),
-                                     x->elt_type(), value, x->state_before()));
+                                     x->elt_type(), value, x->state_before(),
+                                     x->check_boolean()));
       return;
     }
   }
--- a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -976,7 +976,19 @@
       (array->as_NewArray() && array->as_NewArray()->length() && array->as_NewArray()->length()->type()->is_constant())) {
     length = append(new ArrayLength(array, state_before));
   }
-  StoreIndexed* result = new StoreIndexed(array, index, length, type, value, state_before);
+  ciType* array_type = array->declared_type();
+  bool check_boolean = false;
+  if (array_type != NULL) {
+    if (array_type->is_loaded() &&
+      array_type->as_array_klass()->element_type()->basic_type() == T_BOOLEAN) {
+      assert(type == T_BYTE, "boolean store uses bastore");
+      Value mask = append(new Constant(new IntConstant(1)));
+      value = append(new LogicOp(Bytecodes::_iand, value, mask));
+    }
+  } else if (type == T_BYTE) {
+    check_boolean = true;
+  }
+  StoreIndexed* result = new StoreIndexed(array, index, length, type, value, state_before, check_boolean);
   append(result);
   _memory->store_value(value);
 
@@ -1443,6 +1455,36 @@
     need_mem_bar = true;
   }
 
+  BasicType bt = method()->return_type()->basic_type();
+  switch (bt) {
+    case T_BYTE:
+    {
+      Value shift = append(new Constant(new IntConstant(24)));
+      x = append(new ShiftOp(Bytecodes::_ishl, x, shift));
+      x = append(new ShiftOp(Bytecodes::_ishr, x, shift));
+      break;
+    }
+    case T_SHORT:
+    {
+      Value shift = append(new Constant(new IntConstant(16)));
+      x = append(new ShiftOp(Bytecodes::_ishl, x, shift));
+      x = append(new ShiftOp(Bytecodes::_ishr, x, shift));
+      break;
+    }
+    case T_CHAR:
+    {
+      Value mask = append(new Constant(new IntConstant(0xFFFF)));
+      x = append(new LogicOp(Bytecodes::_iand, x, mask));
+      break;
+    }
+    case T_BOOLEAN:
+    {
+      Value mask = append(new Constant(new IntConstant(1)));
+      x = append(new LogicOp(Bytecodes::_iand, x, mask));
+      break;
+    }
+  }
+
   // Check to see whether we are inlining. If so, Return
   // instructions become Gotos to the continuation point.
   if (continuation() != NULL) {
@@ -1611,6 +1653,10 @@
       if (state_before == NULL) {
         state_before = copy_state_for_exception();
       }
+      if (field->type()->basic_type() == T_BOOLEAN) {
+        Value mask = append(new Constant(new IntConstant(1)));
+        val = append(new LogicOp(Bytecodes::_iand, val, mask));
+      }
       append(new StoreField(append(obj), offset, field, val, true, state_before, needs_patching));
       break;
     }
@@ -1672,6 +1718,10 @@
       if (state_before == NULL) {
         state_before = copy_state_for_exception();
       }
+      if (field->type()->basic_type() == T_BOOLEAN) {
+        Value mask = append(new Constant(new IntConstant(1)));
+        val = append(new LogicOp(Bytecodes::_iand, val, mask));
+      }
       StoreField* store = new StoreField(obj, offset, field, val, false, state_before, needs_patching);
       if (!needs_patching) store = _memory->store(store);
       if (store != NULL) {
@@ -4134,7 +4184,12 @@
 #ifndef _LP64
   offset = append(new Convert(Bytecodes::_l2i, offset, as_ValueType(T_INT)));
 #endif
-  Instruction* op = append(new UnsafePutObject(t, args->at(1), offset, args->at(3), is_volatile));
+  Value val = args->at(3);
+  if (t == T_BOOLEAN) {
+    Value mask = append(new Constant(new IntConstant(1)));
+    val = append(new LogicOp(Bytecodes::_iand, val, mask));
+  }
+  Instruction* op = append(new UnsafePutObject(t, args->at(1), offset, val, is_volatile));
   compilation()->set_has_unsafe_access(true);
   kill_all();
 }
@@ -4208,7 +4263,7 @@
   Value index = args->at(1);
   if (is_store) {
     Value value = args->at(2);
-    Instruction* store = append(new StoreIndexed(array, index, NULL, T_CHAR, value, state_before));
+    Instruction* store = append(new StoreIndexed(array, index, NULL, T_CHAR, value, state_before, false));
     store->set_flag(Instruction::NeedsRangeCheckFlag, false);
     _memory->store_value(value);
   } else {
--- a/hotspot/src/share/vm/c1/c1_Instruction.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/c1/c1_Instruction.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -974,11 +974,13 @@
 
   ciMethod* _profiled_method;
   int       _profiled_bci;
+  bool      _check_boolean;
+
  public:
   // creation
-  StoreIndexed(Value array, Value index, Value length, BasicType elt_type, Value value, ValueStack* state_before)
+  StoreIndexed(Value array, Value index, Value length, BasicType elt_type, Value value, ValueStack* state_before, bool check_boolean)
   : AccessIndexed(array, index, length, elt_type, state_before)
-  , _value(value), _profiled_method(NULL), _profiled_bci(0)
+  , _value(value), _profiled_method(NULL), _profiled_bci(0), _check_boolean(check_boolean)
   {
     set_flag(NeedsWriteBarrierFlag, (as_ValueType(elt_type)->is_object()));
     set_flag(NeedsStoreCheckFlag, (as_ValueType(elt_type)->is_object()));
@@ -990,6 +992,7 @@
   Value value() const                            { return _value; }
   bool needs_write_barrier() const               { return check_flag(NeedsWriteBarrierFlag); }
   bool needs_store_check() const                 { return check_flag(NeedsStoreCheckFlag); }
+  bool check_boolean() const                     { return _check_boolean; }
   // Helpers for MethodData* profiling
   void set_should_profile(bool value)                { set_flag(ProfileMDOFlag, value); }
   void set_profiled_method(ciMethod* method)         { _profiled_method = method;   }
--- a/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -28,7 +28,6 @@
 #include "c1/c1_CodeStubs.hpp"
 #include "ci/ciMethodData.hpp"
 #include "oops/methodData.hpp"
-#include "utilities/top.hpp"
 
 class Compilation;
 class ScopeValue;
--- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -3680,3 +3680,26 @@
     }
   }
 }
+
+LIR_Opr LIRGenerator::maybe_mask_boolean(StoreIndexed* x, LIR_Opr array, LIR_Opr value, CodeEmitInfo*& null_check_info) {
+  if (x->check_boolean()) {
+    LIR_Opr value_fixed = rlock_byte(T_BYTE);
+    if (TwoOperandLIRForm) {
+      __ move(value, value_fixed);
+      __ logical_and(value_fixed, LIR_OprFact::intConst(1), value_fixed);
+    } else {
+      __ logical_and(value, LIR_OprFact::intConst(1), value_fixed);
+    }
+    LIR_Opr klass = new_register(T_METADATA);
+    __ move(new LIR_Address(array, oopDesc::klass_offset_in_bytes(), T_ADDRESS), klass, null_check_info);
+    null_check_info = NULL;
+    LIR_Opr layout = new_register(T_INT);
+    __ move(new LIR_Address(klass, in_bytes(Klass::layout_helper_offset()), T_INT), layout);
+    int diffbit = Klass::layout_helper_boolean_diffbit();
+    __ logical_and(layout, LIR_OprFact::intConst(diffbit), layout);
+    __ cmp(lir_cond_notEqual, layout, LIR_OprFact::intConst(0));
+    __ cmove(lir_cond_notEqual, value_fixed, value, value_fixed, T_BYTE);
+    value = value_fixed;
+  }
+  return value;
+}
--- a/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -448,6 +448,7 @@
   void profile_arguments(ProfileCall* x);
   void profile_parameters(Base* x);
   void profile_parameters_at_call(ProfileCall* x);
+  LIR_Opr maybe_mask_boolean(StoreIndexed* x, LIR_Opr array, LIR_Opr value, CodeEmitInfo*& null_check_info);
 
  public:
   Compilation*  compilation() const              { return _compilation; }
--- a/hotspot/src/share/vm/ci/ciFlags.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/ci/ciFlags.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -29,6 +29,7 @@
 #include "memory/allocation.hpp"
 #include "prims/jvm.h"
 #include "utilities/accessFlags.hpp"
+#include "utilities/ostream.hpp"
 
 // ciFlags
 //
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -2713,11 +2713,9 @@
   m->set_constants(_cp);
   m->set_name_index(name_index);
   m->set_signature_index(signature_index);
-#ifdef CC_INTERP
-  // hmm is there a gc issue here??
+
   ResultTypeFinder rtf(cp->symbol_at(signature_index));
-  m->set_result_index(rtf.type());
-#endif
+  m->constMethod()->set_result_type(rtf.type());
 
   if (args_size >= 0) {
     m->set_size_of_parameters(args_size);
--- a/hotspot/src/share/vm/classfile/classFileStream.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/classfile/classFileStream.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -25,8 +25,9 @@
 #ifndef SHARE_VM_CLASSFILE_CLASSFILESTREAM_HPP
 #define SHARE_VM_CLASSFILE_CLASSFILESTREAM_HPP
 
+#include "memory/allocation.hpp"
 #include "utilities/bytes.hpp"
-#include "utilities/top.hpp"
+#include "utilities/exceptions.hpp"
 
 // Input stream for reading .class file
 //
--- a/hotspot/src/share/vm/classfile/classLoader.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/classfile/classLoader.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -98,12 +98,13 @@
 
 // Entry points for jimage.dll for loading jimage file entries
 
-static JImageOpen_t                    JImageOpen                    = NULL;
-static JImageClose_t                   JImageClose                   = NULL;
-static JImagePackageToModule_t         JImagePackageToModule         = NULL;
-static JImageFindResource_t            JImageFindResource            = NULL;
-static JImageGetResource_t             JImageGetResource             = NULL;
-static JImageResourceIterator_t        JImageResourceIterator        = NULL;
+static JImageOpen_t                    JImageOpen             = NULL;
+static JImageClose_t                   JImageClose            = NULL;
+static JImagePackageToModule_t         JImagePackageToModule  = NULL;
+static JImageFindResource_t            JImageFindResource     = NULL;
+static JImageGetResource_t             JImageGetResource      = NULL;
+static JImageResourceIterator_t        JImageResourceIterator = NULL;
+static JImage_ResourcePath_t           JImageResourcePath     = NULL;
 
 // Globals
 
@@ -233,6 +234,7 @@
   strcpy(copy, zip_name);
   _zip_name = copy;
   _is_boot_append = is_boot_append;
+  _multi_versioned = _unknown;
 }
 
 ClassPathZipEntry::~ClassPathZipEntry() {
@@ -330,13 +332,20 @@
 
 bool ClassPathZipEntry::is_multiple_versioned(TRAPS) {
   assert(DumpSharedSpaces, "called only at dump time");
+  if (_multi_versioned != _unknown) {
+    return (_multi_versioned == _yes) ? true : false;
+  }
   jint size;
-  char* buffer = (char*)open_entry("META-INF/MANIFEST.MF", &size, false, CHECK_false);
+  char* buffer = (char*)open_entry("META-INF/MANIFEST.MF", &size, true, CHECK_false);
   if (buffer != NULL) {
-    if (strstr(buffer, "Multi-Release: true") != NULL) {
+    char* p = buffer;
+    for ( ; *p; ++p) *p = tolower(*p);
+    if (strstr(buffer, "multi-release: true") != NULL) {
+      _multi_versioned = _yes;
       return true;
     }
   }
+  _multi_versioned = _no;
   return false;
 }
 #endif // INCLUDE_CDS
@@ -917,6 +926,8 @@
   guarantee(JImageGetResource != NULL, "function JIMAGE_GetResource not found");
   JImageResourceIterator = CAST_TO_FN_PTR(JImageResourceIterator_t, os::dll_lookup(handle, "JIMAGE_ResourceIterator"));
   guarantee(JImageResourceIterator != NULL, "function JIMAGE_ResourceIterator not found");
+  JImageResourcePath = CAST_TO_FN_PTR(JImage_ResourcePath_t, os::dll_lookup(handle, "JIMAGE_ResourcePath"));
+  guarantee(JImageResourcePath != NULL, "function JIMAGE_ResourcePath not found");
 }
 
 jboolean ClassLoader::decompress(void *in, u8 inSize, void *out, u8 outSize, char **pmsg) {
--- a/hotspot/src/share/vm/classfile/classLoader.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/classfile/classLoader.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -101,10 +101,17 @@
 
 
 class ClassPathZipEntry: public ClassPathEntry {
+ enum {
+   _unknown = 0,
+   _yes     = 1,
+   _no      = 2
+ };
  private:
   jzfile* _zip;              // The zip archive
   const char*   _zip_name;   // Name of zip archive
   bool _is_boot_append;      // entry coming from -Xbootclasspath/a
+  u1 _multi_versioned;       // indicates if the jar file has multi-versioned entries.
+                             // It can have value of "_unknown", "_yes", or "_no"
  public:
   bool is_jrt()            { return false; }
   bool is_jar_file() const { return true;  }
--- a/hotspot/src/share/vm/classfile/classLoaderData.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/classfile/classLoaderData.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -373,13 +373,10 @@
   // Lazily create the package entry table at first request.
   if (_packages == NULL) {
     MutexLockerEx m1(metaspace_lock(), Mutex::_no_safepoint_check_flag);
-    // Check again if _packages has been allocated while we were getting this lock.
-    if (_packages != NULL) {
-      return _packages;
+    // Check if _packages got allocated while we were waiting for this lock.
+    if (_packages == NULL) {
+      _packages = new PackageEntryTable(PackageEntryTable::_packagetable_entry_size);
     }
-    // Ensure _packages is stable, since it is examined without a lock
-    OrderAccess::storestore();
-    _packages = new PackageEntryTable(PackageEntryTable::_packagetable_entry_size);
   }
   return _packages;
 }
--- a/hotspot/src/share/vm/classfile/defaultMethods.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/classfile/defaultMethods.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -860,10 +860,8 @@
   m->set_constants(NULL); // This will get filled in later
   m->set_name_index(cp->utf8(name));
   m->set_signature_index(cp->utf8(sig));
-#ifdef CC_INTERP
   ResultTypeFinder rtf(sig);
-  m->set_result_index(rtf.type());
-#endif
+  m->constMethod()->set_result_type(rtf.type());
   m->set_size_of_parameters(params);
   m->set_max_stack(max_stack);
   m->set_max_locals(params);
--- a/hotspot/src/share/vm/classfile/javaClasses.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/classfile/javaClasses.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -2187,43 +2187,19 @@
 }
 
 Method* java_lang_StackFrameInfo::get_method(Handle stackFrame, InstanceKlass* holder, TRAPS) {
-  if (MemberNameInStackFrame) {
-    Handle mname(THREAD, stackFrame->obj_field(_memberName_offset));
-    Method* method = (Method*)java_lang_invoke_MemberName::vmtarget(mname());
-    // we should expand MemberName::name when Throwable uses StackTrace
-    // MethodHandles::expand_MemberName(mname, MethodHandles::_suppress_defc|MethodHandles::_suppress_type, CHECK_NULL);
-    return method;
-  } else {
-    short mid       = stackFrame->short_field(_mid_offset);
-    short version   = stackFrame->short_field(_version_offset);
-    return holder->method_with_orig_idnum(mid, version);
-  }
-}
-
-Symbol* java_lang_StackFrameInfo::get_file_name(Handle stackFrame, InstanceKlass* holder) {
-  if (MemberNameInStackFrame) {
-    return holder->source_file_name();
-  } else {
-    short version = stackFrame->short_field(_version_offset);
-    return Backtrace::get_source_file_name(holder, version);
-  }
+  Handle mname(THREAD, stackFrame->obj_field(_memberName_offset));
+  Method* method = (Method*)java_lang_invoke_MemberName::vmtarget(mname());
+  // we should expand MemberName::name when Throwable uses StackTrace
+  // MethodHandles::expand_MemberName(mname, MethodHandles::_suppress_defc|MethodHandles::_suppress_type, CHECK_NULL);
+  return method;
 }
 
 void java_lang_StackFrameInfo::set_method_and_bci(Handle stackFrame, const methodHandle& method, int bci) {
   // set Method* or mid/cpref
-  if (MemberNameInStackFrame) {
-    oop mname = stackFrame->obj_field(_memberName_offset);
-    InstanceKlass* ik = method->method_holder();
-    CallInfo info(method(), ik);
-    MethodHandles::init_method_MemberName(mname, info);
-  } else {
-    int mid = method->orig_method_idnum();
-    int cpref = method->name_index();
-    assert((jushort)mid == mid,        "mid should be short");
-    assert((jushort)cpref == cpref,    "cpref should be short");
-    java_lang_StackFrameInfo::set_mid(stackFrame(),     (short)mid);
-    java_lang_StackFrameInfo::set_cpref(stackFrame(),   (short)cpref);
-  }
+  oop mname = stackFrame->obj_field(_memberName_offset);
+  InstanceKlass* ik = method->method_holder();
+  CallInfo info(method(), ik);
+  MethodHandles::init_method_MemberName(mname, info);
   // set bci
   java_lang_StackFrameInfo::set_bci(stackFrame(), bci);
   // method may be redefined; store the version
@@ -2232,52 +2208,23 @@
   java_lang_StackFrameInfo::set_version(stackFrame(), (short)version);
 }
 
-void java_lang_StackFrameInfo::fill_methodInfo(Handle stackFrame, TRAPS) {
+void java_lang_StackFrameInfo::to_stack_trace_element(Handle stackFrame, Handle stack_trace_element, TRAPS) {
   ResourceMark rm(THREAD);
-  oop k = stackFrame->obj_field(_declaringClass_offset);
-  InstanceKlass* holder = InstanceKlass::cast(java_lang_Class::as_Klass(k));
+  Handle k (THREAD, stackFrame->obj_field(_declaringClass_offset));
+  InstanceKlass* holder = InstanceKlass::cast(java_lang_Class::as_Klass(k()));
   Method* method = java_lang_StackFrameInfo::get_method(stackFrame, holder, CHECK);
-  int bci = stackFrame->int_field(_bci_offset);
-
-  // The method can be NULL if the requested class version is gone
-  Symbol* sym = (method != NULL) ? method->name() : NULL;
-  if (MemberNameInStackFrame) {
-    assert(sym != NULL, "MemberName must have method name");
-  } else {
-      // The method can be NULL if the requested class version is gone
-    if (sym == NULL) {
-      short cpref   = stackFrame->short_field(_cpref_offset);
-      sym = holder->constants()->symbol_at(cpref);
-    }
-  }
-
-  // set method name
-  oop methodname = StringTable::intern(sym, CHECK);
-  java_lang_StackFrameInfo::set_methodName(stackFrame(), methodname);
-
-  // set file name and line number
-  Symbol* source = get_file_name(stackFrame, holder);
-  if (source != NULL) {
-    oop filename = StringTable::intern(source, CHECK);
-    java_lang_StackFrameInfo::set_fileName(stackFrame(), filename);
-  }
-
-  // if the method has been redefined, the bci is no longer applicable
+
   short version = stackFrame->short_field(_version_offset);
-  if (version_matches(method, version)) {
-    int line_number = Backtrace::get_line_number(method, bci);
-    java_lang_StackFrameInfo::set_lineNumber(stackFrame(), line_number);
-  }
+  short bci = stackFrame->short_field(_bci_offset);
+  int cpref = method->name_index();
+  java_lang_StackTraceElement::fill_in(stack_trace_element, holder, method, version, bci, cpref, CHECK);
 }
 
 void java_lang_StackFrameInfo::compute_offsets() {
   Klass* k = SystemDictionary::StackFrameInfo_klass();
   compute_offset(_declaringClass_offset, k, vmSymbols::declaringClass_name(),  vmSymbols::class_signature());
   compute_offset(_memberName_offset,     k, vmSymbols::memberName_name(),  vmSymbols::object_signature());
-  compute_offset(_bci_offset,            k, vmSymbols::bci_name(),         vmSymbols::int_signature());
-  compute_offset(_methodName_offset,     k, vmSymbols::methodName_name(),  vmSymbols::string_signature());
-  compute_offset(_fileName_offset,       k, vmSymbols::fileName_name(),    vmSymbols::string_signature());
-  compute_offset(_lineNumber_offset,     k, vmSymbols::lineNumber_name(),  vmSymbols::int_signature());
+  compute_offset(_bci_offset,            k, vmSymbols::bci_name(),         vmSymbols::short_signature());
   STACKFRAMEINFO_INJECTED_FIELDS(INJECTED_FIELD_COMPUTE_OFFSET);
 }
 
@@ -3690,12 +3637,7 @@
 int java_lang_StackFrameInfo::_declaringClass_offset;
 int java_lang_StackFrameInfo::_memberName_offset;
 int java_lang_StackFrameInfo::_bci_offset;
-int java_lang_StackFrameInfo::_methodName_offset;
-int java_lang_StackFrameInfo::_fileName_offset;
-int java_lang_StackFrameInfo::_lineNumber_offset;
-int java_lang_StackFrameInfo::_mid_offset;
 int java_lang_StackFrameInfo::_version_offset;
-int java_lang_StackFrameInfo::_cpref_offset;
 int java_lang_LiveStackFrameInfo::_monitors_offset;
 int java_lang_LiveStackFrameInfo::_locals_offset;
 int java_lang_LiveStackFrameInfo::_operands_offset;
@@ -3741,34 +3683,14 @@
   element->obj_field_put(_declaringClass_offset, value);
 }
 
-void java_lang_StackFrameInfo::set_mid(oop element, short value) {
-  element->short_field_put(_mid_offset, value);
-}
-
 void java_lang_StackFrameInfo::set_version(oop element, short value) {
   element->short_field_put(_version_offset, value);
 }
 
-void java_lang_StackFrameInfo::set_cpref(oop element, short value) {
-  element->short_field_put(_cpref_offset, value);
-}
-
 void java_lang_StackFrameInfo::set_bci(oop element, int value) {
   element->int_field_put(_bci_offset, value);
 }
 
-void java_lang_StackFrameInfo::set_fileName(oop element, oop value) {
-  element->obj_field_put(_fileName_offset, value);
-}
-
-void java_lang_StackFrameInfo::set_methodName(oop element, oop value) {
-  element->obj_field_put(_methodName_offset, value);
-}
-
-void java_lang_StackFrameInfo::set_lineNumber(oop element, int value) {
-  element->int_field_put(_lineNumber_offset, value);
-}
-
 void java_lang_LiveStackFrameInfo::set_monitors(oop element, oop value) {
   element->obj_field_put(_monitors_offset, value);
 }
--- a/hotspot/src/share/vm/classfile/javaClasses.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/classfile/javaClasses.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -1364,25 +1364,16 @@
 // Interface to java.lang.StackFrameInfo objects
 
 #define STACKFRAMEINFO_INJECTED_FIELDS(macro)                      \
-  macro(java_lang_StackFrameInfo, mid,     short_signature, false) \
-  macro(java_lang_StackFrameInfo, version, short_signature, false) \
-  macro(java_lang_StackFrameInfo, cpref,   short_signature, false)
+  macro(java_lang_StackFrameInfo, version, short_signature, false)
 
 class java_lang_StackFrameInfo: AllStatic {
 private:
   static int _declaringClass_offset;
   static int _memberName_offset;
   static int _bci_offset;
-  static int _methodName_offset;
-  static int _fileName_offset;
-  static int _lineNumber_offset;
-
-  static int _mid_offset;
   static int _version_offset;
-  static int _cpref_offset;
 
   static Method* get_method(Handle stackFrame, InstanceKlass* holder, TRAPS);
-  static Symbol* get_file_name(Handle stackFrame, InstanceKlass* holder);
 
 public:
   // Setters
@@ -1390,19 +1381,12 @@
   static void set_method_and_bci(Handle stackFrame, const methodHandle& method, int bci);
   static void set_bci(oop info, int value);
 
-  // set method info in an instance of StackFrameInfo
-  static void fill_methodInfo(Handle info, TRAPS);
-  static void set_methodName(oop info, oop value);
-  static void set_fileName(oop info, oop value);
-  static void set_lineNumber(oop info, int value);
-
-  // these injected fields are only used if -XX:-MemberNameInStackFrame set
-  static void set_mid(oop info, short value);
   static void set_version(oop info, short value);
-  static void set_cpref(oop info, short value);
 
   static void compute_offsets();
 
+  static void to_stack_trace_element(Handle stackFrame, Handle stack_trace_element, TRAPS);
+
   // Debugging
   friend class JavaClasses;
 };
--- a/hotspot/src/share/vm/classfile/javaClasses.inline.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/classfile/javaClasses.inline.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -222,20 +222,17 @@
   return line_number;
 }
 
-/*
- * Returns the source file name of a given InstanceKlass and version
- */
 inline Symbol* Backtrace::get_source_file_name(InstanceKlass* holder, int version) {
-  // Find the specific ik version that contains this source_file_name_index
-  // via the previous versions list, but use the current version's
-  // constant pool to look it up.  The previous version's index has been
-  // merged for the current constant pool.
-  InstanceKlass* ik = holder->get_klass_version(version);
-  // This version has been cleaned up.
-  if (ik == NULL) return NULL;
-  int source_file_name_index = ik->source_file_name_index();
-  return (source_file_name_index == 0) ?
-      (Symbol*)NULL : holder->constants()->symbol_at(source_file_name_index);
+  // RedefineClasses() currently permits redefine operations to
+  // happen in parallel using a "last one wins" philosophy. That
+  // spec laxness allows the constant pool entry associated with
+  // the source_file_name_index for any older constant pool version
+  // to be unstable so we shouldn't try to use it.
+  if (holder->constants()->version() != version) {
+    return NULL;
+  } else {
+    return holder->source_file_name();
+  }
 }
 
 #endif // SHARE_VM_CLASSFILE_JAVACLASSES_INLINE_HPP
--- a/hotspot/src/share/vm/classfile/jimage.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/classfile/jimage.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -30,7 +30,7 @@
 typedef jlong JImageLocationRef;
 
 // Max path length limit independent of platform.  Windows max path is 1024,
-// other platforms use 4096.  The JCK fails several tests when 1024 is used.
+// other platforms use 4096.
 #define JIMAGE_MAX_PATH 4096
 
 // JImage Error Codes
@@ -113,7 +113,8 @@
  *
  *  Ex.
  *   jlong size;
- *   JImageLocationRef location = (*JImageFindResource)(image, "java.base", "9.0", "java/lang/String.class", &size);
+ *   JImageLocationRef location = (*JImageFindResource)(image,
+ *                                "java.base", "9.0", "java/lang/String.class", &size);
  */
 extern "C" JImageLocationRef JIMAGE_FindResource(JImageFile* jimage,
         const char* module_name, const char* version, const char* name,
@@ -134,7 +135,8 @@
  *
  * Ex.
  *  jlong size;
- *  JImageLocationRef location = (*JImageFindResource)(image, "java.base", "9.0", "java/lang/String.class", &size);
+ *  JImageLocationRef location = (*JImageFindResource)(image,
+ *                               "java.base", "9.0", "java/lang/String.class", &size);
  *  char* buffer = new char[size];
  *  (*JImageGetResource)(image, location, buffer, size);
  */
@@ -154,7 +156,8 @@
  * required. All strings are utf-8, zero byte terminated.file.
  *
  * Ex.
- *   bool ctw_visitor(JImageFile* jimage, const char* module_name, const char* version, const char* package, const char* name, const char* extension, void* arg) {
+ *   bool ctw_visitor(JImageFile* jimage, const char* module_name, const char* version,
+ *                  const char* package, const char* name, const char* extension, void* arg) {
  *     if (strcmp(extension, “class”) == 0) {
  *       char path[JIMAGE_MAX_PATH];
  *       Thread* THREAD = Thread::current();
@@ -176,3 +179,20 @@
 
 typedef void (*JImageResourceIterator_t)(JImageFile* jimage,
         JImageResourceVisitor_t visitor, void* arg);
+
+/*
+ * JIMAGE_ResourcePath- Given an open image file, a location reference, a buffer
+ * and a maximum buffer size, copy the path of the resource into the buffer.
+ * Returns false if not a valid location reference.
+ *
+ * Ex.
+ *   JImageLocationRef location = ...
+ *   char path[JIMAGE_MAX_PATH];
+ *    (*JImageResourcePath)(image, location, path, JIMAGE_MAX_PATH);
+ */
+extern "C" bool JIMAGE_ResourcePath(JImageFile* image, JImageLocationRef locationRef,
+                                    char* path, size_t max);
+
+typedef bool (*JImage_ResourcePath_t)(JImageFile* jimage, JImageLocationRef location,
+        char* buffer, jlong size);
+
--- a/hotspot/src/share/vm/classfile/moduleEntry.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/classfile/moduleEntry.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -36,6 +36,7 @@
 #include "utilities/events.hpp"
 #include "utilities/growableArray.hpp"
 #include "utilities/hashtable.inline.hpp"
+#include "utilities/ostream.hpp"
 
 ModuleEntry* ModuleEntryTable::_javabase_module = NULL;
 
@@ -359,31 +360,29 @@
   java_lang_Class::set_fixup_module_field_list(NULL);
 }
 
-#ifndef PRODUCT
-void ModuleEntryTable::print() {
-  tty->print_cr("Module Entry Table (table_size=%d, entries=%d)",
-                table_size(), number_of_entries());
+void ModuleEntryTable::print(outputStream* st) {
+  st->print_cr("Module Entry Table (table_size=%d, entries=%d)",
+               table_size(), number_of_entries());
   for (int i = 0; i < table_size(); i++) {
     for (ModuleEntry* probe = bucket(i);
                               probe != NULL;
                               probe = probe->next()) {
-      probe->print();
+      probe->print(st);
     }
   }
 }
 
-void ModuleEntry::print() {
+void ModuleEntry::print(outputStream* st) {
   ResourceMark rm;
-  tty->print_cr("entry "PTR_FORMAT" name %s module "PTR_FORMAT" loader %s version %s location %s strict %s next "PTR_FORMAT,
-                p2i(this),
-                name() == NULL ? UNNAMED_MODULE : name()->as_C_string(),
-                p2i(module()),
-                loader()->loader_name(),
-                version() != NULL ? version()->as_C_string() : "NULL",
-                location() != NULL ? location()->as_C_string() : "NULL",
-                BOOL_TO_STR(!can_read_all_unnamed()), p2i(next()));
+  st->print_cr("entry "PTR_FORMAT" name %s module "PTR_FORMAT" loader %s version %s location %s strict %s next "PTR_FORMAT,
+               p2i(this),
+               name() == NULL ? UNNAMED_MODULE : name()->as_C_string(),
+               p2i(module()),
+               loader()->loader_name(),
+               version() != NULL ? version()->as_C_string() : "NULL",
+               location() != NULL ? location()->as_C_string() : "NULL",
+               BOOL_TO_STR(!can_read_all_unnamed()), p2i(next()));
 }
-#endif
 
 void ModuleEntryTable::verify() {
   int element_count = 0;
--- a/hotspot/src/share/vm/classfile/moduleEntry.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/classfile/moduleEntry.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -33,6 +33,7 @@
 #include "trace/traceMacros.hpp"
 #include "utilities/growableArray.hpp"
 #include "utilities/hashtable.hpp"
+#include "utilities/ostream.hpp"
 
 #define UNNAMED_MODULE "Unnamed Module"
 
@@ -141,7 +142,7 @@
   void purge_reads();
   void delete_reads();
 
-  void print() PRODUCT_RETURN;
+  void print(outputStream* st = tty);
   void verify();
 };
 
@@ -223,7 +224,7 @@
   static void finalize_javabase(Handle module_handle, Symbol* version, Symbol* location);
   static void patch_javabase_entries(Handle module_handle);
 
-  void print() PRODUCT_RETURN;
+  void print(outputStream* st = tty);
   void verify();
 };
 
--- a/hotspot/src/share/vm/classfile/packageEntry.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/classfile/packageEntry.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -32,6 +32,7 @@
 #include "utilities/events.hpp"
 #include "utilities/growableArray.hpp"
 #include "utilities/hashtable.inline.hpp"
+#include "utilities/ostream.hpp"
 
 // Return true if this package is exported to m.
 bool PackageEntry::is_qexported_to(ModuleEntry* m) const {
@@ -265,28 +266,26 @@
   }
 }
 
-#ifndef PRODUCT
-void PackageEntryTable::print() {
-  tty->print_cr("Package Entry Table (table_size=%d, entries=%d)",
-                table_size(), number_of_entries());
+void PackageEntryTable::print(outputStream* st) {
+  st->print_cr("Package Entry Table (table_size=%d, entries=%d)",
+               table_size(), number_of_entries());
   for (int i = 0; i < table_size(); i++) {
     for (PackageEntry* probe = bucket(i);
                        probe != NULL;
                        probe = probe->next()) {
-      probe->print();
+      probe->print(st);
     }
   }
 }
 
-void PackageEntry::print() {
+void PackageEntry::print(outputStream* st) {
   ResourceMark rm;
-  tty->print_cr("package entry "PTR_FORMAT" name %s module %s classpath_index "
-                INT32_FORMAT " is_exported %d is_exported_allUnnamed %d " "next "PTR_FORMAT,
-                p2i(this), name()->as_C_string(),
-                (module()->is_named() ? module()->name()->as_C_string() : UNNAMED_MODULE),
-                _classpath_index, _is_exported, _is_exported_allUnnamed, p2i(next()));
+  st->print_cr("package entry "PTR_FORMAT" name %s module %s classpath_index "
+               INT32_FORMAT " is_exported %d is_exported_allUnnamed %d " "next "PTR_FORMAT,
+               p2i(this), name()->as_C_string(),
+               (module()->is_named() ? module()->name()->as_C_string() : UNNAMED_MODULE),
+               _classpath_index, _is_exported, _is_exported_allUnnamed, p2i(next()));
 }
-#endif
 
 void PackageEntryTable::verify() {
   int element_count = 0;
--- a/hotspot/src/share/vm/classfile/packageEntry.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/classfile/packageEntry.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -29,6 +29,7 @@
 #include "oops/symbol.hpp"
 #include "utilities/growableArray.hpp"
 #include "utilities/hashtable.hpp"
+#include "utilities/ostream.hpp"
 
 // A PackageEntry basically represents a Java package.  It contains:
 //   - Symbol* containing the package's name.
@@ -144,7 +145,7 @@
   void purge_qualified_exports();
   void delete_qualified_exports();
 
-  void print() PRODUCT_RETURN;
+  void print(outputStream* st = tty);
   void verify();
 };
 
@@ -195,7 +196,7 @@
   // purge dead weak references out of exported list
   void purge_all_package_exports();
 
-  void print() PRODUCT_RETURN;
+  void print(outputStream* st = tty);
   void verify();
 };
 
--- a/hotspot/src/share/vm/code/relocInfo.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/code/relocInfo.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -26,8 +26,9 @@
 #define SHARE_VM_CODE_RELOCINFO_HPP
 
 #include "memory/allocation.hpp"
-#include "utilities/top.hpp"
+#include "runtime/os.hpp"
 
+class Metadata;
 class NativeMovConstReg;
 
 // Types in this file:
--- a/hotspot/src/share/vm/code/vmreg.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/code/vmreg.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -28,10 +28,9 @@
 #include "asm/register.hpp"
 #include "memory/allocation.hpp"
 #include "utilities/globalDefinitions.hpp"
-
+#include "utilities/ostream.hpp"
 #ifdef COMPILER2
 #include "opto/adlcVMDeps.hpp"
-#include "utilities/ostream.hpp"
 #endif
 
 //------------------------------VMReg------------------------------------------
--- a/hotspot/src/share/vm/gc/cms/compactibleFreeListSpace.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/gc/cms/compactibleFreeListSpace.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -32,6 +32,7 @@
 #include "gc/shared/genCollectedHeap.hpp"
 #include "gc/shared/space.inline.hpp"
 #include "gc/shared/spaceDecorator.hpp"
+#include "logging/logStream.inline.hpp"
 #include "memory/allocation.inline.hpp"
 #include "memory/resourceArea.hpp"
 #include "memory/universe.inline.hpp"
@@ -505,10 +506,13 @@
     return;
   }
   log.debug("%s", title);
-  _dictionary->report_statistics(log.debug_stream());
+
+  LogStream out(log.debug());
+  _dictionary->report_statistics(&out);
+
   if (log.is_trace()) {
-    ResourceMark rm;
-    reportIndexedFreeListStatistics(log.trace_stream());
+    LogStream trace_out(log.trace());
+    reportIndexedFreeListStatistics(&trace_out);
     size_t total_size = totalSizeInIndexedFreeLists() +
                        _dictionary->total_chunk_size(DEBUG_ONLY(freelistLock()));
     log.trace(" free=" SIZE_FORMAT " frag=%1.4f", total_size, flsFrag());
@@ -2836,6 +2840,11 @@
   par_get_chunk_of_blocks_dictionary(word_sz, n, fl);
 }
 
+const size_t CompactibleFreeListSpace::max_flag_size_for_task_size() const {
+  const size_t ergo_max = _old_gen->reserved().word_size() / (CardTableModRefBS::card_size_in_words * BitsPerWord);
+  return ergo_max;
+}
+
 // Set up the space's par_seq_tasks structure for work claiming
 // for parallel rescan. See CMSParRemarkTask where this is currently used.
 // XXX Need to suitably abstract and generalize this and the next
--- a/hotspot/src/share/vm/gc/cms/compactibleFreeListSpace.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/gc/cms/compactibleFreeListSpace.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -82,6 +82,8 @@
   template <typename SpaceType>
   friend void CompactibleSpace::scan_and_compact(SpaceType* space);
   template <typename SpaceType>
+  friend void CompactibleSpace::verify_up_to_first_dead(SpaceType* space);
+  template <typename SpaceType>
   friend void CompactibleSpace::scan_and_forward(SpaceType* space, CompactPoint* cp);
 
   // "Size" of chunks of work (executed during parallel remark phases
@@ -345,6 +347,8 @@
   // Support for parallelization of rescan and marking.
   const size_t rescan_task_size()  const { return _rescan_task_size;  }
   const size_t marking_task_size() const { return _marking_task_size; }
+  // Return ergonomic max size for CMSRescanMultiple and CMSConcMarkMultiple.
+  const size_t max_flag_size_for_task_size() const;
   SequentialSubTasksDone* conc_par_seq_tasks() {return &_conc_par_seq_tasks; }
   void initialize_sequential_subtasks_for_rescan(int n_threads);
   void initialize_sequential_subtasks_for_marking(int n_threads,
--- a/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -425,7 +425,7 @@
     st->print(",cms_consumption_rate=%g,time_until_full=%g",
               cms_consumption_rate(), time_until_cms_gen_full());
   }
-  st->print(" ");
+  st->cr();
 }
 #endif // #ifndef PRODUCT
 
@@ -1108,8 +1108,10 @@
 }
 
 bool CMSCollector::shouldConcurrentCollect() {
+  LogTarget(Trace, gc) log;
+
   if (_full_gc_requested) {
-    log_trace(gc)("CMSCollector: collect because of explicit  gc request (or GCLocker)");
+    log.print("CMSCollector: collect because of explicit  gc request (or GCLocker)");
     return true;
   }
 
@@ -1117,21 +1119,22 @@
   // ------------------------------------------------------------------
   // Print out lots of information which affects the initiation of
   // a collection.
-  Log(gc) log;
-  if (log.is_trace() && stats().valid()) {
-    log.trace("CMSCollector shouldConcurrentCollect: ");
-    ResourceMark rm;
-    stats().print_on(log.debug_stream());
-    log.trace("time_until_cms_gen_full %3.7f", stats().time_until_cms_gen_full());
-    log.trace("free=" SIZE_FORMAT, _cmsGen->free());
-    log.trace("contiguous_available=" SIZE_FORMAT, _cmsGen->contiguous_available());
-    log.trace("promotion_rate=%g", stats().promotion_rate());
-    log.trace("cms_allocation_rate=%g", stats().cms_allocation_rate());
-    log.trace("occupancy=%3.7f", _cmsGen->occupancy());
-    log.trace("initiatingOccupancy=%3.7f", _cmsGen->initiating_occupancy());
-    log.trace("cms_time_since_begin=%3.7f", stats().cms_time_since_begin());
-    log.trace("cms_time_since_end=%3.7f", stats().cms_time_since_end());
-    log.trace("metadata initialized %d", MetaspaceGC::should_concurrent_collect());
+  if (log.is_enabled() && stats().valid()) {
+    log.print("CMSCollector shouldConcurrentCollect: ");
+
+    LogStream out(log);
+    stats().print_on(&out);
+
+    log.print("time_until_cms_gen_full %3.7f", stats().time_until_cms_gen_full());
+    log.print("free=" SIZE_FORMAT, _cmsGen->free());
+    log.print("contiguous_available=" SIZE_FORMAT, _cmsGen->contiguous_available());
+    log.print("promotion_rate=%g", stats().promotion_rate());
+    log.print("cms_allocation_rate=%g", stats().cms_allocation_rate());
+    log.print("occupancy=%3.7f", _cmsGen->occupancy());
+    log.print("initiatingOccupancy=%3.7f", _cmsGen->initiating_occupancy());
+    log.print("cms_time_since_begin=%3.7f", stats().cms_time_since_begin());
+    log.print("cms_time_since_end=%3.7f", stats().cms_time_since_end());
+    log.print("metadata initialized %d", MetaspaceGC::should_concurrent_collect());
   }
   // ------------------------------------------------------------------
 
@@ -1149,8 +1152,8 @@
       // this branch will not fire after the first successful CMS
       // collection because the stats should then be valid.
       if (_cmsGen->occupancy() >= _bootstrap_occupancy) {
-        log_trace(gc)(" CMSCollector: collect for bootstrapping statistics: occupancy = %f, boot occupancy = %f",
-                      _cmsGen->occupancy(), _bootstrap_occupancy);
+        log.print(" CMSCollector: collect for bootstrapping statistics: occupancy = %f, boot occupancy = %f",
+                  _cmsGen->occupancy(), _bootstrap_occupancy);
         return true;
       }
     }
@@ -1162,7 +1165,7 @@
   // XXX We need to make sure that the gen expansion
   // criterion dovetails well with this. XXX NEED TO FIX THIS
   if (_cmsGen->should_concurrent_collect()) {
-    log_trace(gc)("CMS old gen initiated");
+    log.print("CMS old gen initiated");
     return true;
   }
 
@@ -1173,12 +1176,12 @@
   assert(gch->collector_policy()->is_generation_policy(),
          "You may want to check the correctness of the following");
   if (gch->incremental_collection_will_fail(true /* consult_young */)) {
-    log_trace(gc)("CMSCollector: collect because incremental collection will fail ");
+    log.print("CMSCollector: collect because incremental collection will fail ");
     return true;
   }
 
   if (MetaspaceGC::should_concurrent_collect()) {
-    log_trace(gc)("CMSCollector: collect for metadata allocation ");
+    log.print("CMSCollector: collect for metadata allocation ");
     return true;
   }
 
@@ -1193,10 +1196,10 @@
     // as we want to be able to trigger the first CMS cycle as well)
     if (stats().cms_time_since_begin() >= (CMSTriggerInterval / ((double) MILLIUNITS))) {
       if (stats().valid()) {
-        log_trace(gc)("CMSCollector: collect because of trigger interval (time since last begin %3.7f secs)",
-                      stats().cms_time_since_begin());
+        log.print("CMSCollector: collect because of trigger interval (time since last begin %3.7f secs)",
+                  stats().cms_time_since_begin());
       } else {
-        log_trace(gc)("CMSCollector: collect because of trigger interval (first collection)");
+        log.print("CMSCollector: collect because of trigger interval (first collection)");
       }
       return true;
     }
@@ -3598,7 +3601,7 @@
     size_t capacity = get_eden_capacity();
     // Don't start sampling unless we will get sufficiently
     // many samples.
-    if (used < (capacity/(CMSScheduleRemarkSamplingRatio * 100)
+    if (used < (((capacity / CMSScheduleRemarkSamplingRatio) / 100)
                 * CMSScheduleRemarkEdenPenetration)) {
       _start_sampling = true;
     } else {
--- a/hotspot/src/share/vm/gc/g1/concurrentG1Refine.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/concurrentG1Refine.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -29,42 +29,174 @@
 #include "gc/g1/g1HotCardCache.hpp"
 #include "gc/g1/g1Predictions.hpp"
 #include "runtime/java.hpp"
+#include "utilities/debug.hpp"
+#include "utilities/globalDefinitions.hpp"
+#include "utilities/pair.hpp"
+#include <math.h>
 
-ConcurrentG1Refine::ConcurrentG1Refine(G1CollectedHeap* g1h, const G1Predictions* predictor) :
+// Arbitrary but large limits, to simplify some of the zone calculations.
+// The general idea is to allow expressions like
+//   MIN2(x OP y, max_XXX_zone)
+// without needing to check for overflow in "x OP y", because the
+// ranges for x and y have been restricted.
+STATIC_ASSERT(sizeof(LP64_ONLY(jint) NOT_LP64(jshort)) <= (sizeof(size_t)/2));
+const size_t max_yellow_zone = LP64_ONLY(max_jint) NOT_LP64(max_jshort);
+const size_t max_green_zone = max_yellow_zone / 2;
+const size_t max_red_zone = INT_MAX; // For dcqs.set_max_completed_queue.
+STATIC_ASSERT(max_yellow_zone <= max_red_zone);
+
+// Range check assertions for green zone values.
+#define assert_zone_constraints_g(green)                        \
+  do {                                                          \
+    size_t azc_g_green = (green);                               \
+    assert(azc_g_green <= max_green_zone,                       \
+           "green exceeds max: " SIZE_FORMAT, azc_g_green);     \
+  } while (0)
+
+// Range check assertions for green and yellow zone values.
+#define assert_zone_constraints_gy(green, yellow)                       \
+  do {                                                                  \
+    size_t azc_gy_green = (green);                                      \
+    size_t azc_gy_yellow = (yellow);                                    \
+    assert_zone_constraints_g(azc_gy_green);                            \
+    assert(azc_gy_yellow <= max_yellow_zone,                            \
+           "yellow exceeds max: " SIZE_FORMAT, azc_gy_yellow);          \
+    assert(azc_gy_green <= azc_gy_yellow,                               \
+           "green (" SIZE_FORMAT ") exceeds yellow (" SIZE_FORMAT ")",  \
+           azc_gy_green, azc_gy_yellow);                                \
+  } while (0)
+
+// Range check assertions for green, yellow, and red zone values.
+#define assert_zone_constraints_gyr(green, yellow, red)                 \
+  do {                                                                  \
+    size_t azc_gyr_green = (green);                                     \
+    size_t azc_gyr_yellow = (yellow);                                   \
+    size_t azc_gyr_red = (red);                                         \
+    assert_zone_constraints_gy(azc_gyr_green, azc_gyr_yellow);          \
+    assert(azc_gyr_red <= max_red_zone,                                 \
+           "red exceeds max: " SIZE_FORMAT, azc_gyr_red);               \
+    assert(azc_gyr_yellow <= azc_gyr_red,                               \
+           "yellow (" SIZE_FORMAT ") exceeds red (" SIZE_FORMAT ")",    \
+           azc_gyr_yellow, azc_gyr_red);                                \
+  } while (0)
+
+// Logging tag sequence for refinement control updates.
+#define CTRL_TAGS gc, ergo, refine
+
+// For logging zone values, ensuring consistency of level and tags.
+#define LOG_ZONES(...) log_debug( CTRL_TAGS )(__VA_ARGS__)
+
+// Package for pair of refinement thread activation and deactivation
+// thresholds.  The activation and deactivation levels are resp. the first
+// and second values of the pair.
+typedef Pair<size_t, size_t> Thresholds;
+inline size_t activation_level(const Thresholds& t) { return t.first; }
+inline size_t deactivation_level(const Thresholds& t) { return t.second; }
+
+static Thresholds calc_thresholds(size_t green_zone,
+                                  size_t yellow_zone,
+                                  uint worker_i) {
+  double yellow_size = yellow_zone - green_zone;
+  double step = yellow_size / ConcurrentG1Refine::thread_num();
+  if (worker_i == 0) {
+    // Potentially activate worker 0 more aggressively, to keep
+    // available buffers near green_zone value.  When yellow_size is
+    // large we don't want to allow a full step to accumulate before
+    // doing any processing, as that might lead to significantly more
+    // than green_zone buffers to be processed by update_rs.
+    step = MIN2(step, ParallelGCThreads / 2.0);
+  }
+  size_t activate_offset = static_cast<size_t>(ceil(step * (worker_i + 1)));
+  size_t deactivate_offset = static_cast<size_t>(floor(step * worker_i));
+  return Thresholds(green_zone + activate_offset,
+                    green_zone + deactivate_offset);
+}
+
+ConcurrentG1Refine::ConcurrentG1Refine(G1CollectedHeap* g1h,
+                                       size_t green_zone,
+                                       size_t yellow_zone,
+                                       size_t red_zone,
+                                       size_t min_yellow_zone_size) :
   _threads(NULL),
   _sample_thread(NULL),
-  _predictor_sigma(predictor->sigma()),
+  _n_worker_threads(thread_num()),
+  _green_zone(green_zone),
+  _yellow_zone(yellow_zone),
+  _red_zone(red_zone),
+  _min_yellow_zone_size(min_yellow_zone_size),
   _hot_card_cache(g1h)
 {
-  // Ergonomically select initial concurrent refinement parameters
-  if (FLAG_IS_DEFAULT(G1ConcRefinementGreenZone)) {
-    FLAG_SET_DEFAULT(G1ConcRefinementGreenZone, ParallelGCThreads);
-  }
-  set_green_zone(G1ConcRefinementGreenZone);
+  assert_zone_constraints_gyr(green_zone, yellow_zone, red_zone);
+}
 
-  if (FLAG_IS_DEFAULT(G1ConcRefinementYellowZone)) {
-    FLAG_SET_DEFAULT(G1ConcRefinementYellowZone, green_zone() * 3);
+static size_t calc_min_yellow_zone_size() {
+  size_t step = G1ConcRefinementThresholdStep;
+  uint n_workers = ConcurrentG1Refine::thread_num();
+  if ((max_yellow_zone / step) < n_workers) {
+    return max_yellow_zone;
+  } else {
+    return step * n_workers;
   }
-  set_yellow_zone(MAX2(G1ConcRefinementYellowZone, green_zone()));
+}
 
-  if (FLAG_IS_DEFAULT(G1ConcRefinementRedZone)) {
-    FLAG_SET_DEFAULT(G1ConcRefinementRedZone, yellow_zone() * 2);
+static size_t calc_init_green_zone() {
+  size_t green = G1ConcRefinementGreenZone;
+  if (FLAG_IS_DEFAULT(G1ConcRefinementGreenZone)) {
+    green = ParallelGCThreads;
   }
-  set_red_zone(MAX2(G1ConcRefinementRedZone, yellow_zone()));
-
+  return MIN2(green, max_green_zone);
 }
 
-ConcurrentG1Refine* ConcurrentG1Refine::create(G1CollectedHeap* g1h, CardTableEntryClosure* refine_closure, jint* ecode) {
-  G1CollectorPolicy* policy = g1h->g1_policy();
-  ConcurrentG1Refine* cg1r = new ConcurrentG1Refine(g1h, &policy->predictor());
+static size_t calc_init_yellow_zone(size_t green, size_t min_size) {
+  size_t config = G1ConcRefinementYellowZone;
+  size_t size = 0;
+  if (FLAG_IS_DEFAULT(G1ConcRefinementYellowZone)) {
+    size = green * 2;
+  } else if (green < config) {
+    size = config - green;
+  }
+  size = MAX2(size, min_size);
+  size = MIN2(size, max_yellow_zone);
+  return MIN2(green + size, max_yellow_zone);
+}
+
+static size_t calc_init_red_zone(size_t green, size_t yellow) {
+  size_t size = yellow - green;
+  if (!FLAG_IS_DEFAULT(G1ConcRefinementRedZone)) {
+    size_t config = G1ConcRefinementRedZone;
+    if (yellow < config) {
+      size = MAX2(size, config - yellow);
+    }
+  }
+  return MIN2(yellow + size, max_red_zone);
+}
+
+ConcurrentG1Refine* ConcurrentG1Refine::create(G1CollectedHeap* g1h,
+                                               CardTableEntryClosure* refine_closure,
+                                               jint* ecode) {
+  size_t min_yellow_zone_size = calc_min_yellow_zone_size();
+  size_t green_zone = calc_init_green_zone();
+  size_t yellow_zone = calc_init_yellow_zone(green_zone, min_yellow_zone_size);
+  size_t red_zone = calc_init_red_zone(green_zone, yellow_zone);
+
+  LOG_ZONES("Initial Refinement Zones: "
+            "green: " SIZE_FORMAT ", "
+            "yellow: " SIZE_FORMAT ", "
+            "red: " SIZE_FORMAT ", "
+            "min yellow size: " SIZE_FORMAT,
+            green_zone, yellow_zone, red_zone, min_yellow_zone_size);
+
+  ConcurrentG1Refine* cg1r = new ConcurrentG1Refine(g1h,
+                                                    green_zone,
+                                                    yellow_zone,
+                                                    red_zone,
+                                                    min_yellow_zone_size);
+
   if (cg1r == NULL) {
     *ecode = JNI_ENOMEM;
     vm_shutdown_during_initialization("Could not create ConcurrentG1Refine");
     return NULL;
   }
-  cg1r->_n_worker_threads = thread_num();
-
-  cg1r->reset_threshold_step();
 
   cg1r->_threads = NEW_C_HEAP_ARRAY_RETURN_NULL(ConcurrentG1RefineThread*, cg1r->_n_worker_threads, mtGC);
   if (cg1r->_threads == NULL) {
@@ -77,7 +209,15 @@
 
   ConcurrentG1RefineThread *next = NULL;
   for (uint i = cg1r->_n_worker_threads - 1; i != UINT_MAX; i--) {
-    ConcurrentG1RefineThread* t = new ConcurrentG1RefineThread(cg1r, next, refine_closure, worker_id_offset, i);
+    Thresholds thresholds = calc_thresholds(green_zone, yellow_zone, i);
+    ConcurrentG1RefineThread* t =
+      new ConcurrentG1RefineThread(cg1r,
+                                   next,
+                                   refine_closure,
+                                   worker_id_offset,
+                                   i,
+                                   activation_level(thresholds),
+                                   deactivation_level(thresholds));
     assert(t != NULL, "Conc refine should have been created");
     if (t->osthread() == NULL) {
       *ecode = JNI_ENOMEM;
@@ -101,14 +241,6 @@
   return cg1r;
 }
 
-void ConcurrentG1Refine::reset_threshold_step() {
-  if (FLAG_IS_DEFAULT(G1ConcRefinementThresholdStep)) {
-    _thread_threshold_step = (yellow_zone() - green_zone()) / (worker_thread_num() + 1);
-  } else {
-    _thread_threshold_step = G1ConcRefinementThresholdStep;
-  }
-}
-
 void ConcurrentG1Refine::init(G1RegionToSpaceMapper* card_counts_storage) {
   _hot_card_cache.initialize(card_counts_storage);
 }
@@ -120,10 +252,11 @@
   _sample_thread->stop();
 }
 
-void ConcurrentG1Refine::reinitialize_threads() {
-  reset_threshold_step();
+void ConcurrentG1Refine::update_thread_thresholds() {
   for (uint i = 0; i < _n_worker_threads; i++) {
-    _threads[i]->initialize();
+    Thresholds thresholds = calc_thresholds(_green_zone, _yellow_zone, i);
+    _threads[i]->update_thresholds(activation_level(thresholds),
+                                   deactivation_level(thresholds));
   }
 }
 
@@ -142,7 +275,7 @@
 }
 
 void ConcurrentG1Refine::worker_threads_do(ThreadClosure * tc) {
-  for (uint i = 0; i < worker_thread_num(); i++) {
+  for (uint i = 0; i < _n_worker_threads; i++) {
     tc->do_thread(_threads[i]);
   }
 }
@@ -160,34 +293,80 @@
   st->cr();
 }
 
+static size_t calc_new_green_zone(size_t green,
+                                  double update_rs_time,
+                                  size_t update_rs_processed_buffers,
+                                  double goal_ms) {
+  // Adjust green zone based on whether we're meeting the time goal.
+  // Limit to max_green_zone.
+  const double inc_k = 1.1, dec_k = 0.9;
+  if (update_rs_time > goal_ms) {
+    if (green > 0) {
+      green = static_cast<size_t>(green * dec_k);
+    }
+  } else if (update_rs_time < goal_ms &&
+             update_rs_processed_buffers > green) {
+    green = static_cast<size_t>(MAX2(green * inc_k, green + 1.0));
+    green = MIN2(green, max_green_zone);
+  }
+  return green;
+}
+
+static size_t calc_new_yellow_zone(size_t green, size_t min_yellow_size) {
+  size_t size = green * 2;
+  size = MAX2(size, min_yellow_size);
+  return MIN2(green + size, max_yellow_zone);
+}
+
+static size_t calc_new_red_zone(size_t green, size_t yellow) {
+  return MIN2(yellow + (yellow - green), max_red_zone);
+}
+
+void ConcurrentG1Refine::update_zones(double update_rs_time,
+                                      size_t update_rs_processed_buffers,
+                                      double goal_ms) {
+  log_trace( CTRL_TAGS )("Updating Refinement Zones: "
+                         "update_rs time: %.3fms, "
+                         "update_rs buffers: " SIZE_FORMAT ", "
+                         "update_rs goal time: %.3fms",
+                         update_rs_time,
+                         update_rs_processed_buffers,
+                         goal_ms);
+
+  _green_zone = calc_new_green_zone(_green_zone,
+                                    update_rs_time,
+                                    update_rs_processed_buffers,
+                                    goal_ms);
+  _yellow_zone = calc_new_yellow_zone(_green_zone, _min_yellow_zone_size);
+  _red_zone = calc_new_red_zone(_green_zone, _yellow_zone);
+
+  assert_zone_constraints_gyr(_green_zone, _yellow_zone, _red_zone);
+  LOG_ZONES("Updated Refinement Zones: "
+            "green: " SIZE_FORMAT ", "
+            "yellow: " SIZE_FORMAT ", "
+            "red: " SIZE_FORMAT,
+            _green_zone, _yellow_zone, _red_zone);
+}
+
 void ConcurrentG1Refine::adjust(double update_rs_time,
-                                double update_rs_processed_buffers,
+                                size_t update_rs_processed_buffers,
                                 double goal_ms) {
   DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
 
   if (G1UseAdaptiveConcRefinement) {
-    const int k_gy = 3, k_gr = 6;
-    const double inc_k = 1.1, dec_k = 0.9;
+    update_zones(update_rs_time, update_rs_processed_buffers, goal_ms);
+    update_thread_thresholds();
 
-    size_t g = green_zone();
-    if (update_rs_time > goal_ms) {
-      g = (size_t)(g * dec_k);  // Can become 0, that's OK. That would mean a mutator-only processing.
+    // Change the barrier params
+    if (_n_worker_threads == 0) {
+      // Disable dcqs notification when there are no threads to notify.
+      dcqs.set_process_completed_threshold(INT_MAX);
     } else {
-      if (update_rs_time < goal_ms && update_rs_processed_buffers > g) {
-        g = (size_t)MAX2(g * inc_k, g + 1.0);
-      }
+      // Worker 0 is the primary; wakeup is via dcqs notification.
+      STATIC_ASSERT(max_yellow_zone <= INT_MAX);
+      size_t activate = _threads[0]->activation_threshold();
+      dcqs.set_process_completed_threshold((int)activate);
     }
-    // Change the refinement threads params
-    set_green_zone(g);
-    set_yellow_zone(g * k_gy);
-    set_red_zone(g * k_gr);
-    reinitialize_threads();
-
-    size_t processing_threshold_delta = MAX2<size_t>(green_zone() * _predictor_sigma, 1);
-    size_t processing_threshold = MIN2(green_zone() + processing_threshold_delta,
-                                    yellow_zone());
-    // Change the barrier params
-    dcqs.set_process_completed_threshold((int)processing_threshold);
     dcqs.set_max_completed_queue((int)red_zone());
   }
 
--- a/hotspot/src/share/vm/gc/g1/concurrentG1Refine.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/concurrentG1Refine.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -65,18 +65,24 @@
   size_t _green_zone;
   size_t _yellow_zone;
   size_t _red_zone;
-
-  size_t _thread_threshold_step;
-
-  double _predictor_sigma;
+  size_t _min_yellow_zone_size;
 
   // We delay the refinement of 'hot' cards using the hot card cache.
   G1HotCardCache _hot_card_cache;
 
-  // Reset the threshold step value based of the current zone boundaries.
-  void reset_threshold_step();
+  ConcurrentG1Refine(G1CollectedHeap* g1h,
+                     size_t green_zone,
+                     size_t yellow_zone,
+                     size_t red_zone,
+                     size_t min_yellow_zone_size);
 
-  ConcurrentG1Refine(G1CollectedHeap* g1h, const G1Predictions* predictions);
+  // Update green/yellow/red zone values based on how well goals are being met.
+  void update_zones(double update_rs_time,
+                    size_t update_rs_processed_buffers,
+                    double goal_ms);
+
+  // Update thread thresholds to account for updated zone values.
+  void update_thread_thresholds();
 
  public:
   ~ConcurrentG1Refine();
@@ -88,9 +94,7 @@
   void init(G1RegionToSpaceMapper* card_counts_storage);
   void stop();
 
-  void adjust(double update_rs_time, double update_rs_processed_buffers, double goal_ms);
-
-  void reinitialize_threads();
+  void adjust(double update_rs_time, size_t update_rs_processed_buffers, double goal_ms);
 
   // Iterate over all concurrent refinement threads
   void threads_do(ThreadClosure *tc);
@@ -105,18 +109,10 @@
 
   void print_worker_threads_on(outputStream* st) const;
 
-  void set_green_zone(size_t x)  { _green_zone = x;  }
-  void set_yellow_zone(size_t x) { _yellow_zone = x; }
-  void set_red_zone(size_t x)    { _red_zone = x;    }
-
   size_t green_zone() const      { return _green_zone;  }
   size_t yellow_zone() const     { return _yellow_zone; }
   size_t red_zone() const        { return _red_zone;    }
 
-  uint worker_thread_num() const { return _n_worker_threads; }
-
-  size_t thread_threshold_step() const { return _thread_threshold_step; }
-
   G1HotCardCache* hot_card_cache() { return &_hot_card_cache; }
 
   static bool hot_card_cache_enabled() { return G1HotCardCache::default_use_cache(); }
--- a/hotspot/src/share/vm/gc/g1/concurrentG1RefineThread.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/concurrentG1RefineThread.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -36,7 +36,8 @@
 ConcurrentG1RefineThread::
 ConcurrentG1RefineThread(ConcurrentG1Refine* cg1r, ConcurrentG1RefineThread *next,
                          CardTableEntryClosure* refine_closure,
-                         uint worker_id_offset, uint worker_id) :
+                         uint worker_id_offset, uint worker_id,
+                         size_t activate, size_t deactivate) :
   ConcurrentGCThread(),
   _refine_closure(refine_closure),
   _worker_id_offset(worker_id_offset),
@@ -45,7 +46,9 @@
   _next(next),
   _monitor(NULL),
   _cg1r(cg1r),
-  _vtime_accum(0.0)
+  _vtime_accum(0.0),
+  _activation_threshold(activate),
+  _deactivation_threshold(deactivate)
 {
 
   // Each thread has its own monitor. The i-th thread is responsible for signaling
@@ -58,21 +61,17 @@
   } else {
     _monitor = DirtyCardQ_CBL_mon;
   }
-  initialize();
 
   // set name
   set_name("G1 Refine#%d", worker_id);
   create_and_start();
 }
 
-void ConcurrentG1RefineThread::initialize() {
-  // Current thread activation threshold
-  _threshold = MIN2(cg1r()->thread_threshold_step() * (_worker_id + 1) + cg1r()->green_zone(),
-                    cg1r()->yellow_zone());
-  // A thread deactivates once the number of buffer reached a deactivation threshold
-   _deactivation_threshold =
-     MAX2(_threshold - MIN2(_threshold, cg1r()->thread_threshold_step()),
-          cg1r()->green_zone());
+void ConcurrentG1RefineThread::update_thresholds(size_t activate,
+                                                 size_t deactivate) {
+  assert(deactivate < activate, "precondition");
+  _activation_threshold = activate;
+  _deactivation_threshold = deactivate;
 }
 
 void ConcurrentG1RefineThread::wait_for_completed_buffers() {
@@ -118,9 +117,10 @@
       break;
     }
 
+    size_t buffers_processed = 0;
     DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
     log_debug(gc, refine)("Activated %d, on threshold: " SIZE_FORMAT ", current: " SIZE_FORMAT,
-                          _worker_id, _threshold, dcqs.completed_buffers_num());
+                          _worker_id, _activation_threshold, dcqs.completed_buffers_num());
 
     {
       SuspendibleThreadSetJoiner sts_join;
@@ -139,7 +139,9 @@
         }
 
         // Check if we need to activate the next thread.
-        if (_next != NULL && !_next->is_active() && curr_buffer_num > _next->_threshold) {
+        if ((_next != NULL) &&
+            !_next->is_active() &&
+            (curr_buffer_num > _next->_activation_threshold)) {
           _next->activate();
         }
 
@@ -150,14 +152,16 @@
                                                     false /* during_pause */)) {
           break; // Deactivate, number of buffers fell below threshold.
         }
+        ++buffers_processed;
       }
     }
 
     deactivate();
     log_debug(gc, refine)("Deactivated %d, off threshold: " SIZE_FORMAT
-                          ", current: " SIZE_FORMAT,
+                          ", current: " SIZE_FORMAT ", processed: " SIZE_FORMAT,
                           _worker_id, _deactivation_threshold,
-                          dcqs.completed_buffers_num());
+                          dcqs.completed_buffers_num(),
+                          buffers_processed);
 
     if (os::supports_vtime()) {
       _vtime_accum = (os::elapsedVTime() - _vtime_start);
--- a/hotspot/src/share/vm/gc/g1/concurrentG1RefineThread.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/concurrentG1RefineThread.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -53,10 +53,8 @@
   // The closure applied to completed log buffers.
   CardTableEntryClosure* _refine_closure;
 
-  size_t _thread_threshold_step;
-  // This thread activation threshold
-  size_t _threshold;
-  // This thread deactivation threshold
+  // This thread's activation/deactivation thresholds
+  size_t _activation_threshold;
   size_t _deactivation_threshold;
 
   void wait_for_completed_buffers();
@@ -75,9 +73,11 @@
   // Constructor
   ConcurrentG1RefineThread(ConcurrentG1Refine* cg1r, ConcurrentG1RefineThread* next,
                            CardTableEntryClosure* refine_closure,
-                           uint worker_id_offset, uint worker_id);
+                           uint worker_id_offset, uint worker_id,
+                           size_t activate, size_t deactivate);
 
-  void initialize();
+  void update_thresholds(size_t activate, size_t deactivate);
+  size_t activation_threshold() const { return _activation_threshold; }
 
   // Total virtual time so far.
   double vtime_accum() { return _vtime_accum; }
--- a/hotspot/src/share/vm/gc/g1/concurrentMarkThread.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/concurrentMarkThread.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -28,6 +28,7 @@
 #include "gc/g1/g1Analytics.hpp"
 #include "gc/g1/g1CollectedHeap.inline.hpp"
 #include "gc/g1/g1CollectorPolicy.hpp"
+#include "gc/g1/g1ConcurrentMark.inline.hpp"
 #include "gc/g1/g1MMUTracker.hpp"
 #include "gc/g1/suspendibleThreadSet.hpp"
 #include "gc/g1/vm_operations_g1.hpp"
@@ -183,6 +184,11 @@
         }
       } while (cm()->restart_for_overflow());
 
+      if (!cm()->has_aborted()) {
+        G1ConcPhaseTimer t(_cm, "Concurrent Create Live Data");
+        cm()->create_live_data();
+      }
+
       double end_time = os::elapsedVTime();
       // Update the total virtual time before doing this, since it will try
       // to measure it to get the vtime for this marking.  We purposely
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/gc/g1/g1CardLiveData.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,558 @@
+/*
+ * 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 "precompiled.hpp"
+#include "gc/g1/g1CollectedHeap.inline.hpp"
+#include "gc/g1/g1ConcurrentMark.inline.hpp"
+#include "gc/g1/g1CardLiveData.inline.hpp"
+#include "gc/g1/suspendibleThreadSet.hpp"
+#include "gc/shared/workgroup.hpp"
+#include "memory/universe.hpp"
+#include "runtime/atomic.inline.hpp"
+#include "runtime/globals.hpp"
+#include "runtime/os.hpp"
+#include "utilities/bitMap.inline.hpp"
+#include "utilities/debug.hpp"
+
+G1CardLiveData::G1CardLiveData() :
+  _max_capacity(0),
+  _cards_per_region(0),
+  _live_regions(NULL),
+  _live_regions_size_in_bits(0),
+  _live_cards(NULL),
+  _live_cards_size_in_bits(0) {
+}
+
+G1CardLiveData::~G1CardLiveData()  {
+  free_large_bitmap(_live_cards, _live_cards_size_in_bits);
+  free_large_bitmap(_live_regions, _live_regions_size_in_bits);
+}
+
+G1CardLiveData::bm_word_t* G1CardLiveData::allocate_large_bitmap(size_t size_in_bits) {
+  size_t size_in_words = BitMap::calc_size_in_words(size_in_bits);
+
+  bm_word_t* map = MmapArrayAllocator<bm_word_t, mtGC>::allocate(size_in_words);
+
+  return map;
+}
+
+void G1CardLiveData::free_large_bitmap(bm_word_t* bitmap, size_t size_in_bits) {
+  MmapArrayAllocator<bm_word_t, mtGC>::free(bitmap, size_in_bits / BitsPerWord);
+}
+
+void G1CardLiveData::initialize(size_t max_capacity, uint num_max_regions) {
+  assert(max_capacity % num_max_regions == 0,
+         "Given capacity must be evenly divisible by region size.");
+  size_t region_size = max_capacity / num_max_regions;
+  assert(region_size % (G1SATBCardTableModRefBS::card_size * BitsPerWord) == 0,
+         "Region size must be evenly divisible by area covered by a single word.");
+  _max_capacity = max_capacity;
+  _cards_per_region = region_size / G1SATBCardTableModRefBS::card_size;
+
+  _live_regions_size_in_bits = live_region_bitmap_size_in_bits();
+  _live_regions = allocate_large_bitmap(_live_regions_size_in_bits);
+  _live_cards_size_in_bits = live_card_bitmap_size_in_bits();
+  _live_cards = allocate_large_bitmap(_live_cards_size_in_bits);
+}
+
+void G1CardLiveData::pretouch() {
+  live_cards_bm().pretouch();
+  live_regions_bm().pretouch();
+}
+
+size_t G1CardLiveData::live_region_bitmap_size_in_bits() const {
+  return _max_capacity / (_cards_per_region << G1SATBCardTableModRefBS::card_shift);
+}
+
+size_t G1CardLiveData::live_card_bitmap_size_in_bits() const {
+  return _max_capacity >> G1SATBCardTableModRefBS::card_shift;
+}
+
+// Helper class that provides functionality to generate the Live Data Count
+// information.
+class G1CardLiveDataHelper VALUE_OBJ_CLASS_SPEC {
+private:
+  BitMap _region_bm;
+  BitMap _card_bm;
+
+  // The card number of the bottom of the G1 heap.
+  // Used in biasing indices into accounting card bitmaps.
+  BitMap::idx_t _heap_card_bias;
+
+  // Utility routine to set an exclusive range of bits on the given
+  // bitmap, optimized for very small ranges.
+  // There must be at least one bit to set.
+  void set_card_bitmap_range(BitMap::idx_t start_idx,
+                             BitMap::idx_t end_idx) {
+
+    // Set the exclusive bit range [start_idx, end_idx).
+    assert((end_idx - start_idx) > 0, "at least one bit");
+
+    // For small ranges use a simple loop; otherwise use set_range.
+    // The range is made up of the cards that are spanned by an object/mem
+    // region so 8 cards will allow up to object sizes up to 4K to be handled
+    // using the loop.
+    if ((end_idx - start_idx) <= 8) {
+      for (BitMap::idx_t i = start_idx; i < end_idx; i += 1) {
+        _card_bm.set_bit(i);
+      }
+    } else {
+      _card_bm.set_range(start_idx, end_idx);
+    }
+  }
+
+  // We cache the last mark set. This avoids setting the same bit multiple times.
+  // This is particularly interesting for dense bitmaps, as this avoids doing
+  // lots of work most of the time.
+  BitMap::idx_t _last_marked_bit_idx;
+
+  // Mark the card liveness bitmap for the object spanning from start to end.
+  void mark_card_bitmap_range(HeapWord* start, HeapWord* end) {
+    BitMap::idx_t start_idx = card_live_bitmap_index_for(start);
+    BitMap::idx_t end_idx = card_live_bitmap_index_for((HeapWord*)align_ptr_up(end, CardTableModRefBS::card_size));
+
+    assert((end_idx - start_idx) > 0, "Trying to mark zero sized range.");
+
+    if (start_idx == _last_marked_bit_idx) {
+      start_idx++;
+    }
+    if (start_idx == end_idx) {
+      return;
+    }
+
+    // Set the bits in the card bitmap for the cards spanned by this object.
+    set_card_bitmap_range(start_idx, end_idx);
+    _last_marked_bit_idx = end_idx - 1;
+  }
+
+  void reset_mark_cache() {
+    _last_marked_bit_idx = (BitMap::idx_t)-1;
+  }
+
+public:
+  // Returns the index in the per-card liveness count bitmap
+  // for the given address
+  inline BitMap::idx_t card_live_bitmap_index_for(HeapWord* addr) {
+    // Below, the term "card num" means the result of shifting an address
+    // by the card shift -- address 0 corresponds to card number 0.  One
+    // must subtract the card num of the bottom of the heap to obtain a
+    // card table index.
+    BitMap::idx_t card_num = uintptr_t(addr) >> CardTableModRefBS::card_shift;
+    return card_num - _heap_card_bias;
+  }
+
+  // Takes a region that's not empty (i.e., it has at least one
+  // live object in it and sets its corresponding bit on the region
+  // bitmap to 1.
+  void set_bit_for_region(HeapRegion* hr) {
+    _region_bm.par_set_bit(hr->hrm_index());
+  }
+
+  // Mark the range of bits covered by allocations done since the last marking
+  // in the given heap region, i.e. from NTAMS to top of the given region.
+  // Returns if there has been some allocation in this region since the last marking.
+  bool mark_allocated_since_marking(HeapRegion* hr) {
+    reset_mark_cache();
+
+    HeapWord* ntams = hr->next_top_at_mark_start();
+    HeapWord* top   = hr->top();
+
+    assert(hr->bottom() <= ntams && ntams <= hr->end(), "Preconditions.");
+
+    // Mark the allocated-since-marking portion...
+    if (ntams < top) {
+      mark_card_bitmap_range(ntams, top);
+      return true;
+    } else {
+      return false;
+    }
+  }
+
+  // Mark the range of bits covered by live objects on the mark bitmap between
+  // bottom and NTAMS of the given region.
+  // Returns the number of live bytes marked within that area for the given
+  // heap region.
+  size_t mark_marked_during_marking(G1CMBitMap* mark_bitmap, HeapRegion* hr) {
+    reset_mark_cache();
+
+    size_t marked_bytes = 0;
+
+    HeapWord* ntams = hr->next_top_at_mark_start();
+    HeapWord* start = hr->bottom();
+
+    if (ntams <= start) {
+      // Skip empty regions.
+      return 0;
+    }
+    if (hr->is_humongous()) {
+      HeapRegion* start_region = hr->humongous_start_region();
+      if (mark_bitmap->isMarked(start_region->bottom())) {
+        mark_card_bitmap_range(start, hr->top());
+        return pointer_delta(hr->top(), start, 1);
+      } else {
+        // Humongous start object was actually dead.
+        return 0;
+      }
+    }
+
+    assert(start <= hr->end() && start <= ntams && ntams <= hr->end(),
+           "Preconditions not met - "
+           "start: " PTR_FORMAT ", ntams: " PTR_FORMAT ", end: " PTR_FORMAT,
+           p2i(start), p2i(ntams), p2i(hr->end()));
+
+    // Find the first marked object at or after "start".
+    start = mark_bitmap->getNextMarkedWordAddress(start, ntams);
+    while (start < ntams) {
+      oop obj = oop(start);
+      size_t obj_size = obj->size();
+      HeapWord* obj_end = start + obj_size;
+
+      assert(obj_end <= hr->end(), "Humongous objects must have been handled elsewhere.");
+
+      mark_card_bitmap_range(start, obj_end);
+
+      // Add the size of this object to the number of marked bytes.
+      marked_bytes += obj_size * HeapWordSize;
+
+      // Find the next marked object after this one.
+      start = mark_bitmap->getNextMarkedWordAddress(obj_end, ntams);
+    }
+
+    return marked_bytes;
+  }
+
+  G1CardLiveDataHelper(G1CardLiveData* live_data, HeapWord* base_address) :
+    _region_bm(live_data->live_regions_bm()),
+    _card_bm(live_data->live_cards_bm()) {
+    // Calculate the card number for the bottom of the heap. Used
+    // in biasing indexes into the accounting card bitmaps.
+    _heap_card_bias =
+      uintptr_t(base_address) >> CardTableModRefBS::card_shift;
+  }
+};
+
+class G1CreateCardLiveDataTask: public AbstractGangTask {
+  // Aggregate the counting data that was constructed concurrently
+  // with marking.
+  class G1CreateLiveDataClosure : public HeapRegionClosure {
+    G1CardLiveDataHelper _helper;
+
+    G1CMBitMap* _mark_bitmap;
+
+    G1ConcurrentMark* _cm;
+  public:
+    G1CreateLiveDataClosure(G1CollectedHeap* g1h,
+                            G1ConcurrentMark* cm,
+                            G1CMBitMap* mark_bitmap,
+                            G1CardLiveData* live_data) :
+      HeapRegionClosure(),
+      _helper(live_data, g1h->reserved_region().start()),
+      _mark_bitmap(mark_bitmap),
+      _cm(cm) { }
+
+    bool doHeapRegion(HeapRegion* hr) {
+      size_t marked_bytes = _helper.mark_marked_during_marking(_mark_bitmap, hr);
+      if (marked_bytes > 0) {
+        hr->add_to_marked_bytes(marked_bytes);
+      }
+
+      return (_cm->do_yield_check() && _cm->has_aborted());
+    }
+  };
+
+  G1ConcurrentMark* _cm;
+  G1CardLiveData* _live_data;
+  HeapRegionClaimer _hr_claimer;
+
+public:
+  G1CreateCardLiveDataTask(G1CMBitMap* bitmap,
+                           G1CardLiveData* live_data,
+                           uint n_workers) :
+      AbstractGangTask("G1 Create Live Data"),
+      _live_data(live_data),
+      _hr_claimer(n_workers) {
+  }
+
+  void work(uint worker_id) {
+    SuspendibleThreadSetJoiner sts_join;
+
+    G1CollectedHeap* g1h = G1CollectedHeap::heap();
+    G1ConcurrentMark* cm = g1h->concurrent_mark();
+    G1CreateLiveDataClosure cl(g1h, cm, cm->nextMarkBitMap(), _live_data);
+    g1h->heap_region_par_iterate(&cl, worker_id, &_hr_claimer);
+  }
+};
+
+void G1CardLiveData::create(WorkGang* workers, G1CMBitMap* mark_bitmap) {
+  uint n_workers = workers->active_workers();
+
+  G1CreateCardLiveDataTask cl(mark_bitmap,
+                              this,
+                              n_workers);
+  workers->run_task(&cl);
+}
+
+class G1FinalizeCardLiveDataTask: public AbstractGangTask {
+  // Finalizes the liveness counting data.
+  // Sets the bits corresponding to the interval [NTAMS, top]
+  // (which contains the implicitly live objects) in the
+  // card liveness bitmap. Also sets the bit for each region
+  // containing live data, in the region liveness bitmap.
+  class G1FinalizeCardLiveDataClosure: public HeapRegionClosure {
+  private:
+    G1CardLiveDataHelper _helper;
+  public:
+    G1FinalizeCardLiveDataClosure(G1CollectedHeap* g1h,
+                                  G1CMBitMap* bitmap,
+                                  G1CardLiveData* live_data) :
+      HeapRegionClosure(),
+      _helper(live_data, g1h->reserved_region().start()) { }
+
+    bool doHeapRegion(HeapRegion* hr) {
+      bool allocated_since_marking = _helper.mark_allocated_since_marking(hr);
+      if (allocated_since_marking || hr->next_marked_bytes() > 0) {
+        _helper.set_bit_for_region(hr);
+      }
+      return false;
+    }
+  };
+
+  G1CMBitMap* _bitmap;
+
+  G1CardLiveData* _live_data;
+
+  HeapRegionClaimer _hr_claimer;
+
+public:
+  G1FinalizeCardLiveDataTask(G1CMBitMap* bitmap, G1CardLiveData* live_data, uint n_workers) :
+    AbstractGangTask("G1 Finalize Card Live Data"),
+    _bitmap(bitmap),
+    _live_data(live_data),
+    _hr_claimer(n_workers) {
+  }
+
+  void work(uint worker_id) {
+    G1FinalizeCardLiveDataClosure cl(G1CollectedHeap::heap(), _bitmap, _live_data);
+
+    G1CollectedHeap::heap()->heap_region_par_iterate(&cl, worker_id, &_hr_claimer);
+  }
+};
+
+void G1CardLiveData::finalize(WorkGang* workers, G1CMBitMap* mark_bitmap) {
+  // Finalize the live data.
+  G1FinalizeCardLiveDataTask cl(mark_bitmap,
+                                this,
+                                workers->active_workers());
+  workers->run_task(&cl);
+}
+
+class G1ClearCardLiveDataTask : public AbstractGangTask {
+  BitMap _bitmap;
+  size_t _num_chunks;
+  size_t _cur_chunk;
+public:
+  G1ClearCardLiveDataTask(BitMap bitmap, size_t num_tasks) :
+    AbstractGangTask("G1 Clear Card Live Data"),
+    _bitmap(bitmap),
+    _num_chunks(num_tasks),
+    _cur_chunk(0) {
+  }
+
+  static size_t chunk_size() { return M; }
+
+  virtual void work(uint worker_id) {
+    while (true) {
+      size_t to_process = Atomic::add(1, &_cur_chunk) - 1;
+      if (to_process >= _num_chunks) {
+        break;
+      }
+
+      BitMap::idx_t start = M * BitsPerByte * to_process;
+      BitMap::idx_t end = MIN2(start + M * BitsPerByte, _bitmap.size());
+      _bitmap.clear_range(start, end);
+    }
+  }
+};
+
+void G1CardLiveData::clear(WorkGang* workers) {
+  guarantee(Universe::is_fully_initialized(), "Should not call this during initialization.");
+
+  size_t const num_chunks = align_size_up(live_cards_bm().size_in_bytes(), G1ClearCardLiveDataTask::chunk_size()) / G1ClearCardLiveDataTask::chunk_size();
+
+  G1ClearCardLiveDataTask cl(live_cards_bm(), num_chunks);
+  workers->run_task(&cl);
+
+  // The region live bitmap is always very small, even for huge heaps. Clear
+  // directly.
+  live_regions_bm().clear();
+}
+
+class G1VerifyCardLiveDataTask: public AbstractGangTask {
+  // Heap region closure used for verifying the live count data
+  // that was created concurrently and finalized during
+  // the remark pause. This closure is applied to the heap
+  // regions during the STW cleanup pause.
+  class G1VerifyCardLiveDataClosure: public HeapRegionClosure {
+  private:
+    G1CollectedHeap* _g1h;
+    G1CMBitMap* _mark_bitmap;
+    G1CardLiveDataHelper _helper;
+
+    G1CardLiveData* _act_live_data;
+
+    G1CardLiveData* _exp_live_data;
+
+    int _failures;
+
+    // Completely recreates the live data count for the given heap region and
+    // returns the number of bytes marked.
+    size_t create_live_data_count(HeapRegion* hr) {
+      size_t bytes_marked = _helper.mark_marked_during_marking(_mark_bitmap, hr);
+      bool allocated_since_marking = _helper.mark_allocated_since_marking(hr);
+      if (allocated_since_marking || bytes_marked > 0) {
+        _helper.set_bit_for_region(hr);
+      }
+      return bytes_marked;
+    }
+  public:
+    G1VerifyCardLiveDataClosure(G1CollectedHeap* g1h,
+                                G1CMBitMap* mark_bitmap,
+                                G1CardLiveData* act_live_data,
+                                G1CardLiveData* exp_live_data) :
+      _g1h(g1h),
+      _mark_bitmap(mark_bitmap),
+      _helper(exp_live_data, g1h->reserved_region().start()),
+      _act_live_data(act_live_data),
+      _exp_live_data(exp_live_data),
+      _failures(0) { }
+
+    int failures() const { return _failures; }
+
+    bool doHeapRegion(HeapRegion* hr) {
+      int failures = 0;
+
+      // Walk the marking bitmap for this region and set the corresponding bits
+      // in the expected region and card bitmaps.
+      size_t exp_marked_bytes = create_live_data_count(hr);
+      size_t act_marked_bytes = hr->next_marked_bytes();
+      // Verify the marked bytes for this region.
+
+      if (exp_marked_bytes != act_marked_bytes) {
+        failures += 1;
+      } else if (exp_marked_bytes > HeapRegion::GrainBytes) {
+        failures += 1;
+      }
+
+      // Verify the bit, for this region, in the actual and expected
+      // (which was just calculated) region bit maps.
+      // We're not OK if the bit in the calculated expected region
+      // bitmap is set and the bit in the actual region bitmap is not.
+      uint index = hr->hrm_index();
+
+      bool expected = _exp_live_data->is_region_live(index);
+      bool actual = _act_live_data->is_region_live(index);
+      if (expected && !actual) {
+        failures += 1;
+      }
+
+      // Verify that the card bit maps for the cards spanned by the current
+      // region match. We have an error if we have a set bit in the expected
+      // bit map and the corresponding bit in the actual bitmap is not set.
+
+      BitMap::idx_t start_idx = _helper.card_live_bitmap_index_for(hr->bottom());
+      BitMap::idx_t end_idx = _helper.card_live_bitmap_index_for(hr->top());
+
+      for (BitMap::idx_t i = start_idx; i < end_idx; i+=1) {
+        expected = _exp_live_data->is_card_live_at(i);
+        actual = _act_live_data->is_card_live_at(i);
+
+        if (expected && !actual) {
+          failures += 1;
+        }
+      }
+
+      _failures += failures;
+
+      // We could stop iteration over the heap when we
+      // find the first violating region by returning true.
+      return false;
+    }
+  };
+protected:
+  G1CollectedHeap* _g1h;
+  G1CMBitMap* _mark_bitmap;
+
+  G1CardLiveData* _act_live_data;
+
+  G1CardLiveData _exp_live_data;
+
+  int  _failures;
+
+  HeapRegionClaimer _hr_claimer;
+
+public:
+  G1VerifyCardLiveDataTask(G1CMBitMap* bitmap,
+                           G1CardLiveData* act_live_data,
+                           uint n_workers)
+  : AbstractGangTask("G1 Verify Card Live Data"),
+    _g1h(G1CollectedHeap::heap()),
+    _mark_bitmap(bitmap),
+    _act_live_data(act_live_data),
+    _exp_live_data(),
+    _failures(0),
+    _hr_claimer(n_workers) {
+    assert(VerifyDuringGC, "don't call this otherwise");
+    _exp_live_data.initialize(_g1h->max_capacity(), _g1h->max_regions());
+  }
+
+  void work(uint worker_id) {
+    G1VerifyCardLiveDataClosure cl(_g1h,
+                                   _mark_bitmap,
+                                   _act_live_data,
+                                   &_exp_live_data);
+    _g1h->heap_region_par_iterate(&cl, worker_id, &_hr_claimer);
+
+    Atomic::add(cl.failures(), &_failures);
+  }
+
+  int failures() const { return _failures; }
+};
+
+void G1CardLiveData::verify(WorkGang* workers, G1CMBitMap* actual_bitmap) {
+    ResourceMark rm;
+
+    G1VerifyCardLiveDataTask cl(actual_bitmap,
+                                this,
+                                workers->active_workers());
+    workers->run_task(&cl);
+
+    guarantee(cl.failures() == 0, "Unexpected accounting failures");
+}
+
+#ifndef PRODUCT
+void G1CardLiveData::verify_is_clear() {
+  assert(live_cards_bm().count_one_bits() == 0, "Live cards bitmap must be clear.");
+  assert(live_regions_bm().count_one_bits() == 0, "Live regions bitmap must be clear.");
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/gc/g1/g1CardLiveData.hpp	Wed Jul 05 21:37:42 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.
+ *
+ */
+
+#ifndef SHARE_VM_GC_G1_G1CARDLIVEDATA_HPP
+#define SHARE_VM_GC_G1_G1CARDLIVEDATA_HPP
+
+#include "gc/g1/g1CollectedHeap.hpp"
+#include "utilities/bitMap.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+class G1CollectedHeap;
+class G1CMBitMap;
+class WorkGang;
+
+// Information about object liveness on the Java heap on a "card" basis.
+// Can be used for various purposes, like as remembered set for completely
+// coarsened remembered sets, scrubbing remembered sets or estimating liveness.
+// This information is created as part of the concurrent marking cycle.
+class G1CardLiveData VALUE_OBJ_CLASS_SPEC {
+  friend class G1CardLiveDataHelper;
+  friend class G1VerifyCardLiveDataTask;
+private:
+  typedef BitMap::bm_word_t bm_word_t;
+  // Store some additional information about the covered area to be able to test.
+  size_t _max_capacity;
+  size_t _cards_per_region;
+
+  // The per-card liveness bitmap.
+  bm_word_t* _live_cards;
+  size_t _live_cards_size_in_bits;
+  // The per-region liveness bitmap.
+  bm_word_t* _live_regions;
+  size_t _live_regions_size_in_bits;
+  // The bits in this bitmap contain for every card whether it contains
+  // at least part of at least one live object.
+  BitMap live_cards_bm() const { return BitMap(_live_cards, _live_cards_size_in_bits); }
+  // The bits in this bitmap indicate that a given region contains some live objects.
+  BitMap live_regions_bm() const { return BitMap(_live_regions, _live_regions_size_in_bits); }
+
+  // Allocate a "large" bitmap from virtual memory with the given size in bits.
+  bm_word_t* allocate_large_bitmap(size_t size_in_bits);
+  void free_large_bitmap(bm_word_t* map, size_t size_in_bits);
+
+  inline BitMap live_card_bitmap(uint region);
+
+  inline bool is_card_live_at(BitMap::idx_t idx) const;
+
+  size_t live_region_bitmap_size_in_bits() const;
+  size_t live_card_bitmap_size_in_bits() const;
+public:
+  inline bool is_region_live(uint region) const;
+
+  inline void remove_nonlive_cards(uint region, BitMap* bm);
+  inline void remove_nonlive_regions(BitMap* bm);
+
+  G1CardLiveData();
+  ~G1CardLiveData();
+
+  void initialize(size_t max_capacity, uint num_max_regions);
+  void pretouch();
+
+  // Create the initial liveness data based on the marking result from the bottom
+  // to the ntams of every region in the heap and the marks in the given bitmap.
+  void create(WorkGang* workers, G1CMBitMap* mark_bitmap);
+  // Finalize the liveness data.
+  void finalize(WorkGang* workers, G1CMBitMap* mark_bitmap);
+
+  // Verify that the liveness count data created concurrently matches one created
+  // during this safepoint.
+  void verify(WorkGang* workers, G1CMBitMap* actual_bitmap);
+  // Clear all data structures, prepare for next processing.
+  void clear(WorkGang* workers);
+
+  void verify_is_clear() PRODUCT_RETURN;
+};
+
+#endif /* SHARE_VM_GC_G1_G1CARDLIVEDATA_HPP */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/gc/g1/g1CardLiveData.inline.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ *
+ */
+
+#ifndef SHARE_VM_GC_G1_G1CARDLIVEDATA_INLINE_HPP
+#define SHARE_VM_GC_G1_G1CARDLIVEDATA_INLINE_HPP
+
+#include "gc/g1/g1CardLiveData.hpp"
+#include "utilities/bitMap.inline.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+inline BitMap G1CardLiveData::live_card_bitmap(uint region) {
+  return BitMap(_live_cards + ((size_t)region * _cards_per_region >> LogBitsPerWord), _cards_per_region);
+}
+
+inline bool G1CardLiveData::is_card_live_at(BitMap::idx_t idx) const {
+  return live_cards_bm().at(idx);
+}
+
+inline bool G1CardLiveData::is_region_live(uint region) const {
+  return live_regions_bm().at(region);
+}
+
+inline void G1CardLiveData::remove_nonlive_cards(uint region, BitMap* bm) {
+  bm->set_intersection(live_card_bitmap(region));
+}
+
+inline void G1CardLiveData::remove_nonlive_regions(BitMap* bm) {
+  bm->set_intersection(live_regions_bm());
+}
+
+#endif /* SHARE_VM_GC_G1_G1CARDLIVEDATA_INLINE_HPP */
--- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -1425,6 +1425,7 @@
       // the full GC has compacted objects and updated TAMS but not updated
       // the prev bitmap.
       if (G1VerifyBitmaps) {
+        GCTraceTime(Debug, gc)("Clear Bitmap for Verification");
         _cm->clear_prev_bitmap(workers());
       }
       _verifier->check_bitmaps("Full GC End");
@@ -1828,10 +1829,14 @@
                                          HeapRegion::GrainBytes,
                                          translation_factor,
                                          mtGC);
-  if (TracePageSizes) {
-    tty->print_cr("G1 '%s': pg_sz=" SIZE_FORMAT " base=" PTR_FORMAT " size=" SIZE_FORMAT " alignment=" SIZE_FORMAT " reqsize=" SIZE_FORMAT,
-                  description, preferred_page_size, p2i(rs.base()), rs.size(), rs.alignment(), size);
-  }
+
+  os::trace_page_sizes_for_requested_size(description,
+                                          size,
+                                          preferred_page_size,
+                                          rs.alignment(),
+                                          rs.base(),
+                                          rs.size());
+
   return result;
 }
 
@@ -1905,26 +1910,28 @@
                                          HeapRegion::GrainBytes,
                                          1,
                                          mtJavaHeap);
-  os::trace_page_sizes("G1 Heap", collector_policy()->min_heap_byte_size(),
-                       max_byte_size, page_size,
+  os::trace_page_sizes("Heap",
+                       collector_policy()->min_heap_byte_size(),
+                       max_byte_size,
+                       page_size,
                        heap_rs.base(),
                        heap_rs.size());
   heap_storage->set_mapping_changed_listener(&_listener);
 
   // Create storage for the BOT, card table, card counts table (hot card cache) and the bitmaps.
   G1RegionToSpaceMapper* bot_storage =
-    create_aux_memory_mapper("Block offset table",
+    create_aux_memory_mapper("Block Offset Table",
                              G1BlockOffsetTable::compute_size(g1_rs.size() / HeapWordSize),
                              G1BlockOffsetTable::heap_map_factor());
 
   ReservedSpace cardtable_rs(G1SATBCardTableLoggingModRefBS::compute_size(g1_rs.size() / HeapWordSize));
   G1RegionToSpaceMapper* cardtable_storage =
-    create_aux_memory_mapper("Card table",
+    create_aux_memory_mapper("Card Table",
                              G1SATBCardTableLoggingModRefBS::compute_size(g1_rs.size() / HeapWordSize),
                              G1SATBCardTableLoggingModRefBS::heap_map_factor());
 
   G1RegionToSpaceMapper* card_counts_storage =
-    create_aux_memory_mapper("Card counts table",
+    create_aux_memory_mapper("Card Counts Table",
                              G1CardCounts::compute_size(g1_rs.size() / HeapWordSize),
                              G1CardCounts::heap_map_factor());
 
@@ -1944,7 +1951,7 @@
   const uint max_region_idx = (1U << (sizeof(RegionIdx_t)*BitsPerByte-1)) - 1;
   guarantee((max_regions() - 1) <= max_region_idx, "too many regions");
 
-  G1RemSet::initialize(max_regions());
+  g1_rem_set()->initialize(max_capacity(), max_regions());
 
   size_t max_cards_per_region = ((size_t)1 << (sizeof(CardIdx_t)*BitsPerByte-1)) - 1;
   guarantee(HeapRegion::CardsPerRegion > 0, "make sure it's initialized");
@@ -2735,7 +2742,7 @@
   _cmThread->print_on(st);
   st->cr();
   _cm->print_worker_threads_on(st);
-  _cg1r->print_worker_threads_on(st);
+  _cg1r->print_worker_threads_on(st); // also prints the sample thread
   if (G1StringDedup::is_enabled()) {
     G1StringDedup::print_worker_threads_on(st);
   }
@@ -2744,7 +2751,8 @@
 void G1CollectedHeap::gc_threads_do(ThreadClosure* tc) const {
   workers()->threads_do(tc);
   tc->do_thread(_cmThread);
-  _cg1r->threads_do(tc);
+  _cm->threads_do(tc);
+  _cg1r->threads_do(tc); // also iterates over the sample thread
   if (G1StringDedup::is_enabled()) {
     G1StringDedup::threads_do(tc);
   }
@@ -2939,13 +2947,17 @@
       : rset->is_empty();
   }
 
-  bool is_typeArray_region(HeapRegion* region) const {
-    return oop(region->bottom())->is_typeArray();
-  }
-
   bool humongous_region_is_candidate(G1CollectedHeap* heap, HeapRegion* region) const {
     assert(region->is_starts_humongous(), "Must start a humongous object");
 
+    oop obj = oop(region->bottom());
+
+    // Dead objects cannot be eager reclaim candidates. Due to class
+    // unloading it is unsafe to query their classes so we return early.
+    if (heap->is_obj_dead(obj, region)) {
+      return false;
+    }
+
     // Candidate selection must satisfy the following constraints
     // while concurrent marking is in progress:
     //
@@ -2982,7 +2994,7 @@
     // important use case for eager reclaim, and this special handling
     // may reduce needed headroom.
 
-    return is_typeArray_region(region) && is_remset_small(region);
+    return obj->is_typeArray() && is_remset_small(region);
   }
 
  public:
@@ -4440,7 +4452,6 @@
 }
 
 void G1CollectedHeap::preserve_cm_referents(G1ParScanThreadStateSet* per_thread_states) {
-  double preserve_cm_referents_start = os::elapsedTime();
   // Any reference objects, in the collection set, that were 'discovered'
   // by the CM ref processor should have already been copied (either by
   // applying the external root copy closure to the discovered lists, or
@@ -4461,16 +4472,24 @@
   // objects discovered by the STW ref processor in case one of these
   // referents points to another object which is also referenced by an
   // object discovered by the STW ref processor.
-
-  uint no_of_gc_workers = workers()->active_workers();
-
-  G1ParPreserveCMReferentsTask keep_cm_referents(this,
-                                                 per_thread_states,
-                                                 no_of_gc_workers,
-                                                 _task_queues);
-  workers()->run_task(&keep_cm_referents);
-
-  g1_policy()->phase_times()->record_preserve_cm_referents_time_ms((os::elapsedTime() - preserve_cm_referents_start) * 1000.0);
+  double preserve_cm_referents_time = 0.0;
+
+  // To avoid spawning task when there is no work to do, check that
+  // a concurrent cycle is active and that some references have been
+  // discovered.
+  if (concurrent_mark()->cmThread()->during_cycle() &&
+      ref_processor_cm()->has_discovered_references()) {
+    double preserve_cm_referents_start = os::elapsedTime();
+    uint no_of_gc_workers = workers()->active_workers();
+    G1ParPreserveCMReferentsTask keep_cm_referents(this,
+                                                   per_thread_states,
+                                                   no_of_gc_workers,
+                                                   _task_queues);
+    workers()->run_task(&keep_cm_referents);
+    preserve_cm_referents_time = os::elapsedTime() - preserve_cm_referents_start;
+  }
+
+  g1_policy()->phase_times()->record_preserve_cm_referents_time_ms(preserve_cm_referents_time * 1000.0);
 }
 
 // Weak Reference processing during an evacuation pause (part 1).
@@ -4787,27 +4806,23 @@
 class G1ParScrubRemSetTask: public AbstractGangTask {
 protected:
   G1RemSet* _g1rs;
-  BitMap* _region_bm;
-  BitMap* _card_bm;
   HeapRegionClaimer _hrclaimer;
 
 public:
-  G1ParScrubRemSetTask(G1RemSet* g1_rs, BitMap* region_bm, BitMap* card_bm, uint num_workers) :
+  G1ParScrubRemSetTask(G1RemSet* g1_rs, uint num_workers) :
     AbstractGangTask("G1 ScrubRS"),
     _g1rs(g1_rs),
-    _region_bm(region_bm),
-    _card_bm(card_bm),
     _hrclaimer(num_workers) {
   }
 
   void work(uint worker_id) {
-    _g1rs->scrub(_region_bm, _card_bm, worker_id, &_hrclaimer);
+    _g1rs->scrub(worker_id, &_hrclaimer);
   }
 };
 
-void G1CollectedHeap::scrub_rem_set(BitMap* region_bm, BitMap* card_bm) {
+void G1CollectedHeap::scrub_rem_set() {
   uint num_workers = workers()->active_workers();
-  G1ParScrubRemSetTask g1_par_scrub_rs_task(g1_rem_set(), region_bm, card_bm, num_workers);
+  G1ParScrubRemSetTask g1_par_scrub_rs_task(g1_rem_set(), num_workers);
   workers()->run_task(&g1_par_scrub_rs_task);
 }
 
@@ -4821,6 +4836,9 @@
 
     workers()->run_task(&cleanup_task);
 #ifndef PRODUCT
+    // Need to synchronize with concurrent cleanup since it needs to
+    // finish its card table clearing before we can verify.
+    wait_while_free_regions_coming();
     _verifier->verify_card_table_cleanup();
 #endif
   }
--- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -992,7 +992,8 @@
   // The rem set and barrier set.
   G1RemSet* g1_rem_set() const { return _g1_rem_set; }
 
-  void scrub_rem_set(BitMap* region_bm, BitMap* card_bm);
+  // Try to minimize the remembered set.
+  void scrub_rem_set();
 
   unsigned get_gc_time_stamp() {
     return _gc_time_stamp;
--- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.inline.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.inline.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -28,7 +28,7 @@
 #include "gc/g1/g1CollectedHeap.hpp"
 #include "gc/g1/g1CollectorPolicy.hpp"
 #include "gc/g1/g1CollectorState.hpp"
-#include "gc/g1/g1ConcurrentMark.hpp"
+#include "gc/g1/g1ConcurrentMark.inline.hpp"
 #include "gc/g1/g1SATBCardTableModRefBS.hpp"
 #include "gc/g1/heapRegionManager.inline.hpp"
 #include "gc/g1/heapRegionSet.inline.hpp"
--- a/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -33,6 +33,7 @@
 #include "gc/g1/g1ConcurrentMark.inline.hpp"
 #include "gc/g1/g1HeapVerifier.hpp"
 #include "gc/g1/g1OopClosures.inline.hpp"
+#include "gc/g1/g1CardLiveData.inline.hpp"
 #include "gc/g1/g1StringDedup.hpp"
 #include "gc/g1/heapRegion.inline.hpp"
 #include "gc/g1/heapRegionRemSet.hpp"
@@ -355,10 +356,6 @@
   _sleep_factor(0.0),
   _marking_task_overhead(1.0),
   _cleanup_list("Cleanup List"),
-  _region_bm((BitMap::idx_t)(g1h->max_regions()), false /* in_resource_area*/),
-  _card_bm((g1h->reserved_region().byte_size() + CardTableModRefBS::card_size - 1) >>
-            CardTableModRefBS::card_shift,
-            false /* in_resource_area*/),
 
   _prevMarkBitMap(&_markBitMap1),
   _nextMarkBitMap(&_markBitMap2),
@@ -390,8 +387,6 @@
 
   _parallel_workers(NULL),
 
-  _count_card_bitmaps(NULL),
-  _count_marked_bytes(NULL),
   _completed_initialization(false) {
 
   _markBitMap1.initialize(g1h->reserved_region(), prev_bitmap_storage);
@@ -505,40 +500,19 @@
   _tasks = NEW_C_HEAP_ARRAY(G1CMTask*, _max_worker_id, mtGC);
   _accum_task_vtime = NEW_C_HEAP_ARRAY(double, _max_worker_id, mtGC);
 
-  _count_card_bitmaps = NEW_C_HEAP_ARRAY(BitMap,  _max_worker_id, mtGC);
-  _count_marked_bytes = NEW_C_HEAP_ARRAY(size_t*, _max_worker_id, mtGC);
-
-  BitMap::idx_t card_bm_size = _card_bm.size();
-
   // so that the assertion in MarkingTaskQueue::task_queue doesn't fail
   _active_tasks = _max_worker_id;
 
-  uint max_regions = _g1h->max_regions();
   for (uint i = 0; i < _max_worker_id; ++i) {
     G1CMTaskQueue* task_queue = new G1CMTaskQueue();
     task_queue->initialize();
     _task_queues->register_queue(i, task_queue);
 
-    _count_card_bitmaps[i] = BitMap(card_bm_size, false);
-    _count_marked_bytes[i] = NEW_C_HEAP_ARRAY(size_t, max_regions, mtGC);
-
-    _tasks[i] = new G1CMTask(i, this,
-                             _count_marked_bytes[i],
-                             &_count_card_bitmaps[i],
-                             task_queue, _task_queues);
+    _tasks[i] = new G1CMTask(i, this, task_queue, _task_queues);
 
     _accum_task_vtime[i] = 0.0;
   }
 
-  // Calculate the card number for the bottom of the heap. Used
-  // in biasing indexes into the accounting card bitmaps.
-  _heap_bottom_card_num =
-    intptr_t(uintptr_t(_g1h->reserved_region().start()) >>
-                                CardTableModRefBS::card_shift);
-
-  // Clear all the liveness counting data
-  clear_all_count_data();
-
   // so that the call below can read a sensible value
   _heap_start = g1h->reserved_region().start();
   set_non_marking_state();
@@ -716,10 +690,11 @@
 
   clear_bitmap(_nextMarkBitMap, _parallel_workers, true);
 
-  // Clear the liveness counting data. If the marking has been aborted, the abort()
+  // Clear the live count data. If the marking has been aborted, the abort()
   // call already did that.
   if (!has_aborted()) {
-    clear_all_count_data();
+    clear_live_data(_parallel_workers);
+    DEBUG_ONLY(verify_live_data_clear());
   }
 
   // Repeat the asserts from above.
@@ -901,7 +876,7 @@
           double elapsed_vtime_sec = end_vtime_sec - start_vtime_sec;
           _cm->clear_has_overflown();
 
-          _cm->do_yield_check(worker_id);
+          _cm->do_yield_check();
 
           jlong sleep_time_ms;
           if (!_cm->has_aborted() && the_task->has_aborted()) {
@@ -951,10 +926,10 @@
   return n_conc_workers;
 }
 
-void G1ConcurrentMark::scanRootRegion(HeapRegion* hr, uint worker_id) {
+void G1ConcurrentMark::scanRootRegion(HeapRegion* hr) {
   // Currently, only survivors can be root regions.
   assert(hr->next_top_at_mark_start() == hr->bottom(), "invariant");
-  G1RootRegionScanClosure cl(_g1h, this, worker_id);
+  G1RootRegionScanClosure cl(_g1h, this);
 
   const uintx interval = PrefetchScanIntervalInBytes;
   HeapWord* curr = hr->bottom();
@@ -983,7 +958,7 @@
     G1CMRootRegions* root_regions = _cm->root_regions();
     HeapRegion* hr = root_regions->claim_next();
     while (hr != NULL) {
-      _cm->scanRootRegion(hr, worker_id);
+      _cm->scanRootRegion(hr);
       hr = root_regions->claim_next();
     }
   }
@@ -1107,14 +1082,6 @@
     // marking due to overflowing the global mark stack.
     reset_marking_state();
   } else {
-    {
-      GCTraceTime(Debug, gc, phases) trace("Aggregate Data", _gc_timer_cm);
-
-      // Aggregate the per-task counting data that we have accumulated
-      // while marking.
-      aggregate_count_data();
-    }
-
     SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set();
     // We're done with marking.
     // This is the end of  the marking cycle, we're expected all
@@ -1150,363 +1117,6 @@
   _gc_tracer_cm->report_object_count_after_gc(&is_alive);
 }
 
-// Base class of the closures that finalize and verify the
-// liveness counting data.
-class G1CMCountDataClosureBase: public HeapRegionClosure {
-protected:
-  G1CollectedHeap* _g1h;
-  G1ConcurrentMark* _cm;
-  CardTableModRefBS* _ct_bs;
-
-  BitMap* _region_bm;
-  BitMap* _card_bm;
-
-  // Takes a region that's not empty (i.e., it has at least one
-  // live object in it and sets its corresponding bit on the region
-  // bitmap to 1.
-  void set_bit_for_region(HeapRegion* hr) {
-    BitMap::idx_t index = (BitMap::idx_t) hr->hrm_index();
-    _region_bm->par_at_put(index, true);
-  }
-
-public:
-  G1CMCountDataClosureBase(G1CollectedHeap* g1h,
-                           BitMap* region_bm, BitMap* card_bm):
-    _g1h(g1h), _cm(g1h->concurrent_mark()),
-    _ct_bs(barrier_set_cast<CardTableModRefBS>(g1h->barrier_set())),
-    _region_bm(region_bm), _card_bm(card_bm) { }
-};
-
-// Closure that calculates the # live objects per region. Used
-// for verification purposes during the cleanup pause.
-class CalcLiveObjectsClosure: public G1CMCountDataClosureBase {
-  G1CMBitMapRO* _bm;
-  size_t _region_marked_bytes;
-
-public:
-  CalcLiveObjectsClosure(G1CMBitMapRO *bm, G1CollectedHeap* g1h,
-                         BitMap* region_bm, BitMap* card_bm) :
-    G1CMCountDataClosureBase(g1h, region_bm, card_bm),
-    _bm(bm), _region_marked_bytes(0) { }
-
-  bool doHeapRegion(HeapRegion* hr) {
-    HeapWord* ntams = hr->next_top_at_mark_start();
-    HeapWord* start = hr->bottom();
-
-    assert(start <= hr->end() && start <= ntams && ntams <= hr->end(),
-           "Preconditions not met - "
-           "start: " PTR_FORMAT ", ntams: " PTR_FORMAT ", end: " PTR_FORMAT,
-           p2i(start), p2i(ntams), p2i(hr->end()));
-
-    // Find the first marked object at or after "start".
-    start = _bm->getNextMarkedWordAddress(start, ntams);
-
-    size_t marked_bytes = 0;
-
-    while (start < ntams) {
-      oop obj = oop(start);
-      int obj_sz = obj->size();
-      HeapWord* obj_end = start + obj_sz;
-
-      BitMap::idx_t start_idx = _cm->card_bitmap_index_for(start);
-      BitMap::idx_t end_idx = _cm->card_bitmap_index_for(obj_end);
-
-      // Note: if we're looking at the last region in heap - obj_end
-      // could be actually just beyond the end of the heap; end_idx
-      // will then correspond to a (non-existent) card that is also
-      // just beyond the heap.
-      if (_g1h->is_in_g1_reserved(obj_end) && !_ct_bs->is_card_aligned(obj_end)) {
-        // end of object is not card aligned - increment to cover
-        // all the cards spanned by the object
-        end_idx += 1;
-      }
-
-      // Set the bits in the card BM for the cards spanned by this object.
-      _cm->set_card_bitmap_range(_card_bm, start_idx, end_idx, true /* is_par */);
-
-      // Add the size of this object to the number of marked bytes.
-      marked_bytes += (size_t)obj_sz * HeapWordSize;
-
-      // This will happen if we are handling a humongous object that spans
-      // several heap regions.
-      if (obj_end > hr->end()) {
-        break;
-      }
-      // Find the next marked object after this one.
-      start = _bm->getNextMarkedWordAddress(obj_end, ntams);
-    }
-
-    // Mark the allocated-since-marking portion...
-    HeapWord* top = hr->top();
-    if (ntams < top) {
-      BitMap::idx_t start_idx = _cm->card_bitmap_index_for(ntams);
-      BitMap::idx_t end_idx = _cm->card_bitmap_index_for(top);
-
-      // Note: if we're looking at the last region in heap - top
-      // could be actually just beyond the end of the heap; end_idx
-      // will then correspond to a (non-existent) card that is also
-      // just beyond the heap.
-      if (_g1h->is_in_g1_reserved(top) && !_ct_bs->is_card_aligned(top)) {
-        // end of object is not card aligned - increment to cover
-        // all the cards spanned by the object
-        end_idx += 1;
-      }
-      _cm->set_card_bitmap_range(_card_bm, start_idx, end_idx, true /* is_par */);
-
-      // This definitely means the region has live objects.
-      set_bit_for_region(hr);
-    }
-
-    // Update the live region bitmap.
-    if (marked_bytes > 0) {
-      set_bit_for_region(hr);
-    }
-
-    // Set the marked bytes for the current region so that
-    // it can be queried by a calling verification routine
-    _region_marked_bytes = marked_bytes;
-
-    return false;
-  }
-
-  size_t region_marked_bytes() const { return _region_marked_bytes; }
-};
-
-// Heap region closure used for verifying the counting data
-// that was accumulated concurrently and aggregated during
-// the remark pause. This closure is applied to the heap
-// regions during the STW cleanup pause.
-
-class VerifyLiveObjectDataHRClosure: public HeapRegionClosure {
-  G1CollectedHeap* _g1h;
-  G1ConcurrentMark* _cm;
-  CalcLiveObjectsClosure _calc_cl;
-  BitMap* _region_bm;   // Region BM to be verified
-  BitMap* _card_bm;     // Card BM to be verified
-
-  BitMap* _exp_region_bm; // Expected Region BM values
-  BitMap* _exp_card_bm;   // Expected card BM values
-
-  int _failures;
-
-public:
-  VerifyLiveObjectDataHRClosure(G1CollectedHeap* g1h,
-                                BitMap* region_bm,
-                                BitMap* card_bm,
-                                BitMap* exp_region_bm,
-                                BitMap* exp_card_bm) :
-    _g1h(g1h), _cm(g1h->concurrent_mark()),
-    _calc_cl(_cm->nextMarkBitMap(), g1h, exp_region_bm, exp_card_bm),
-    _region_bm(region_bm), _card_bm(card_bm),
-    _exp_region_bm(exp_region_bm), _exp_card_bm(exp_card_bm),
-    _failures(0) { }
-
-  int failures() const { return _failures; }
-
-  bool doHeapRegion(HeapRegion* hr) {
-    int failures = 0;
-
-    // Call the CalcLiveObjectsClosure to walk the marking bitmap for
-    // this region and set the corresponding bits in the expected region
-    // and card bitmaps.
-    bool res = _calc_cl.doHeapRegion(hr);
-    assert(res == false, "should be continuing");
-
-    // Verify the marked bytes for this region.
-    size_t exp_marked_bytes = _calc_cl.region_marked_bytes();
-    size_t act_marked_bytes = hr->next_marked_bytes();
-
-    if (exp_marked_bytes > act_marked_bytes) {
-      if (hr->is_starts_humongous()) {
-        // For start_humongous regions, the size of the whole object will be
-        // in exp_marked_bytes.
-        HeapRegion* region = hr;
-        int num_regions;
-        for (num_regions = 0; region != NULL; num_regions++) {
-          region = _g1h->next_region_in_humongous(region);
-        }
-        if ((num_regions-1) * HeapRegion::GrainBytes >= exp_marked_bytes) {
-          failures += 1;
-        } else if (num_regions * HeapRegion::GrainBytes < exp_marked_bytes) {
-          failures += 1;
-        }
-      } else {
-        // We're not OK if expected marked bytes > actual marked bytes. It means
-        // we have missed accounting some objects during the actual marking.
-        failures += 1;
-      }
-    }
-
-    // Verify the bit, for this region, in the actual and expected
-    // (which was just calculated) region bit maps.
-    // We're not OK if the bit in the calculated expected region
-    // bitmap is set and the bit in the actual region bitmap is not.
-    BitMap::idx_t index = (BitMap::idx_t) hr->hrm_index();
-
-    bool expected = _exp_region_bm->at(index);
-    bool actual = _region_bm->at(index);
-    if (expected && !actual) {
-      failures += 1;
-    }
-
-    // Verify that the card bit maps for the cards spanned by the current
-    // region match. We have an error if we have a set bit in the expected
-    // bit map and the corresponding bit in the actual bitmap is not set.
-
-    BitMap::idx_t start_idx = _cm->card_bitmap_index_for(hr->bottom());
-    BitMap::idx_t end_idx = _cm->card_bitmap_index_for(hr->top());
-
-    for (BitMap::idx_t i = start_idx; i < end_idx; i+=1) {
-      expected = _exp_card_bm->at(i);
-      actual = _card_bm->at(i);
-
-      if (expected && !actual) {
-        failures += 1;
-      }
-    }
-
-    _failures += failures;
-
-    // We could stop iteration over the heap when we
-    // find the first violating region by returning true.
-    return false;
-  }
-};
-
-class G1ParVerifyFinalCountTask: public AbstractGangTask {
-protected:
-  G1CollectedHeap* _g1h;
-  G1ConcurrentMark* _cm;
-  BitMap* _actual_region_bm;
-  BitMap* _actual_card_bm;
-
-  uint    _n_workers;
-
-  BitMap* _expected_region_bm;
-  BitMap* _expected_card_bm;
-
-  int  _failures;
-
-  HeapRegionClaimer _hrclaimer;
-
-public:
-  G1ParVerifyFinalCountTask(G1CollectedHeap* g1h,
-                            BitMap* region_bm, BitMap* card_bm,
-                            BitMap* expected_region_bm, BitMap* expected_card_bm)
-    : AbstractGangTask("G1 verify final counting"),
-      _g1h(g1h), _cm(_g1h->concurrent_mark()),
-      _actual_region_bm(region_bm), _actual_card_bm(card_bm),
-      _expected_region_bm(expected_region_bm), _expected_card_bm(expected_card_bm),
-      _failures(0),
-      _n_workers(_g1h->workers()->active_workers()), _hrclaimer(_n_workers) {
-    assert(VerifyDuringGC, "don't call this otherwise");
-    assert(_expected_card_bm->size() == _actual_card_bm->size(), "sanity");
-    assert(_expected_region_bm->size() == _actual_region_bm->size(), "sanity");
-  }
-
-  void work(uint worker_id) {
-    assert(worker_id < _n_workers, "invariant");
-
-    VerifyLiveObjectDataHRClosure verify_cl(_g1h,
-                                            _actual_region_bm, _actual_card_bm,
-                                            _expected_region_bm,
-                                            _expected_card_bm);
-
-    _g1h->heap_region_par_iterate(&verify_cl, worker_id, &_hrclaimer);
-
-    Atomic::add(verify_cl.failures(), &_failures);
-  }
-
-  int failures() const { return _failures; }
-};
-
-// Closure that finalizes the liveness counting data.
-// Used during the cleanup pause.
-// Sets the bits corresponding to the interval [NTAMS, top]
-// (which contains the implicitly live objects) in the
-// card liveness bitmap. Also sets the bit for each region,
-// containing live data, in the region liveness bitmap.
-
-class FinalCountDataUpdateClosure: public G1CMCountDataClosureBase {
- public:
-  FinalCountDataUpdateClosure(G1CollectedHeap* g1h,
-                              BitMap* region_bm,
-                              BitMap* card_bm) :
-    G1CMCountDataClosureBase(g1h, region_bm, card_bm) { }
-
-  bool doHeapRegion(HeapRegion* hr) {
-    HeapWord* ntams = hr->next_top_at_mark_start();
-    HeapWord* top   = hr->top();
-
-    assert(hr->bottom() <= ntams && ntams <= hr->end(), "Preconditions.");
-
-    // Mark the allocated-since-marking portion...
-    if (ntams < top) {
-      // This definitely means the region has live objects.
-      set_bit_for_region(hr);
-
-      // Now set the bits in the card bitmap for [ntams, top)
-      BitMap::idx_t start_idx = _cm->card_bitmap_index_for(ntams);
-      BitMap::idx_t end_idx = _cm->card_bitmap_index_for(top);
-
-      // Note: if we're looking at the last region in heap - top
-      // could be actually just beyond the end of the heap; end_idx
-      // will then correspond to a (non-existent) card that is also
-      // just beyond the heap.
-      if (_g1h->is_in_g1_reserved(top) && !_ct_bs->is_card_aligned(top)) {
-        // end of object is not card aligned - increment to cover
-        // all the cards spanned by the object
-        end_idx += 1;
-      }
-
-      assert(end_idx <= _card_bm->size(),
-             "oob: end_idx=  " SIZE_FORMAT ", bitmap size= " SIZE_FORMAT,
-             end_idx, _card_bm->size());
-      assert(start_idx < _card_bm->size(),
-             "oob: start_idx=  " SIZE_FORMAT ", bitmap size= " SIZE_FORMAT,
-             start_idx, _card_bm->size());
-
-      _cm->set_card_bitmap_range(_card_bm, start_idx, end_idx, true /* is_par */);
-    }
-
-    // Set the bit for the region if it contains live data
-    if (hr->next_marked_bytes() > 0) {
-      set_bit_for_region(hr);
-    }
-
-    return false;
-  }
-};
-
-class G1ParFinalCountTask: public AbstractGangTask {
-protected:
-  G1CollectedHeap* _g1h;
-  G1ConcurrentMark* _cm;
-  BitMap* _actual_region_bm;
-  BitMap* _actual_card_bm;
-
-  uint    _n_workers;
-  HeapRegionClaimer _hrclaimer;
-
-public:
-  G1ParFinalCountTask(G1CollectedHeap* g1h, BitMap* region_bm, BitMap* card_bm)
-    : AbstractGangTask("G1 final counting"),
-      _g1h(g1h), _cm(_g1h->concurrent_mark()),
-      _actual_region_bm(region_bm), _actual_card_bm(card_bm),
-      _n_workers(_g1h->workers()->active_workers()), _hrclaimer(_n_workers) {
-  }
-
-  void work(uint worker_id) {
-    assert(worker_id < _n_workers, "invariant");
-
-    FinalCountDataUpdateClosure final_update_cl(_g1h,
-                                                _actual_region_bm,
-                                                _actual_card_bm);
-
-    _g1h->heap_region_par_iterate(&final_update_cl, worker_id, &_hrclaimer);
-  }
-};
-
 class G1NoteEndOfConcMarkClosure : public HeapRegionClosure {
   G1CollectedHeap* _g1;
   size_t _freed_bytes;
@@ -1637,31 +1247,16 @@
 
   HeapRegionRemSet::reset_for_cleanup_tasks();
 
-  // Do counting once more with the world stopped for good measure.
-  G1ParFinalCountTask g1_par_count_task(g1h, &_region_bm, &_card_bm);
-
-  g1h->workers()->run_task(&g1_par_count_task);
+  {
+    GCTraceTime(Debug, gc)("Finalize Live Data");
+    finalize_live_data();
+  }
 
   if (VerifyDuringGC) {
-    // Verify that the counting data accumulated during marking matches
-    // that calculated by walking the marking bitmap.
-
-    // Bitmaps to hold expected values
-    BitMap expected_region_bm(_region_bm.size(), true);
-    BitMap expected_card_bm(_card_bm.size(), true);
-
-    G1ParVerifyFinalCountTask g1_par_verify_task(g1h,
-                                                 &_region_bm,
-                                                 &_card_bm,
-                                                 &expected_region_bm,
-                                                 &expected_card_bm);
-
-    g1h->workers()->run_task(&g1_par_verify_task);
-
-    guarantee(g1_par_verify_task.failures() == 0, "Unexpected accounting failures");
+    GCTraceTime(Debug, gc)("Verify Live Data");
+    verify_live_data();
   }
 
-  size_t start_used_bytes = g1h->used();
   g1h->collector_state()->set_mark_in_progress(false);
 
   double count_end = os::elapsedTime();
@@ -1696,7 +1291,7 @@
   // regions.
   if (G1ScrubRemSets) {
     double rs_scrub_start = os::elapsedTime();
-    g1h->scrub_rem_set(&_region_bm, &_card_bm);
+    g1h->scrub_rem_set();
     _total_rs_scrub_time += (os::elapsedTime() - rs_scrub_start);
   }
 
@@ -2160,7 +1755,7 @@
       oop obj = static_cast<oop>(entry);
       assert(obj->is_oop(true /* ignore mark word */),
              "Invalid oop in SATB buffer: " PTR_FORMAT, p2i(obj));
-      _task->make_reference_grey(obj, hr);
+      _task->make_reference_grey(obj);
     }
   }
 
@@ -2401,168 +1996,28 @@
   }
 }
 #endif // PRODUCT
-
-// Aggregate the counting data that was constructed concurrently
-// with marking.
-class AggregateCountDataHRClosure: public HeapRegionClosure {
-  G1CollectedHeap* _g1h;
-  G1ConcurrentMark* _cm;
-  CardTableModRefBS* _ct_bs;
-  BitMap* _cm_card_bm;
-  uint _max_worker_id;
-
- public:
-  AggregateCountDataHRClosure(G1CollectedHeap* g1h,
-                              BitMap* cm_card_bm,
-                              uint max_worker_id) :
-    _g1h(g1h), _cm(g1h->concurrent_mark()),
-    _ct_bs(barrier_set_cast<CardTableModRefBS>(g1h->barrier_set())),
-    _cm_card_bm(cm_card_bm), _max_worker_id(max_worker_id) { }
-
-  bool doHeapRegion(HeapRegion* hr) {
-    HeapWord* start = hr->bottom();
-    HeapWord* limit = hr->next_top_at_mark_start();
-    HeapWord* end = hr->end();
-
-    assert(start <= limit && limit <= hr->top() && hr->top() <= hr->end(),
-           "Preconditions not met - "
-           "start: " PTR_FORMAT ", limit: " PTR_FORMAT ", "
-           "top: " PTR_FORMAT ", end: " PTR_FORMAT,
-           p2i(start), p2i(limit), p2i(hr->top()), p2i(hr->end()));
-
-    assert(hr->next_marked_bytes() == 0, "Precondition");
-
-    if (start == limit) {
-      // NTAMS of this region has not been set so nothing to do.
-      return false;
-    }
-
-    // 'start' should be in the heap.
-    assert(_g1h->is_in_g1_reserved(start) && _ct_bs->is_card_aligned(start), "sanity");
-    // 'end' *may* be just beyond the end of the heap (if hr is the last region)
-    assert(!_g1h->is_in_g1_reserved(end) || _ct_bs->is_card_aligned(end), "sanity");
-
-    BitMap::idx_t start_idx = _cm->card_bitmap_index_for(start);
-    BitMap::idx_t limit_idx = _cm->card_bitmap_index_for(limit);
-    BitMap::idx_t end_idx = _cm->card_bitmap_index_for(end);
-
-    // If ntams is not card aligned then we bump card bitmap index
-    // for limit so that we get the all the cards spanned by
-    // the object ending at ntams.
-    // Note: if this is the last region in the heap then ntams
-    // could be actually just beyond the end of the the heap;
-    // limit_idx will then  correspond to a (non-existent) card
-    // that is also outside the heap.
-    if (_g1h->is_in_g1_reserved(limit) && !_ct_bs->is_card_aligned(limit)) {
-      limit_idx += 1;
-    }
-
-    assert(limit_idx <= end_idx, "or else use atomics");
-
-    // Aggregate the "stripe" in the count data associated with hr.
-    uint hrm_index = hr->hrm_index();
-    size_t marked_bytes = 0;
-
-    for (uint i = 0; i < _max_worker_id; i += 1) {
-      size_t* marked_bytes_array = _cm->count_marked_bytes_array_for(i);
-      BitMap* task_card_bm = _cm->count_card_bitmap_for(i);
-
-      // Fetch the marked_bytes in this region for task i and
-      // add it to the running total for this region.
-      marked_bytes += marked_bytes_array[hrm_index];
-
-      // Now union the bitmaps[0,max_worker_id)[start_idx..limit_idx)
-      // into the global card bitmap.
-      BitMap::idx_t scan_idx = task_card_bm->get_next_one_offset(start_idx, limit_idx);
-
-      while (scan_idx < limit_idx) {
-        assert(task_card_bm->at(scan_idx) == true, "should be");
-        _cm_card_bm->set_bit(scan_idx);
-        assert(_cm_card_bm->at(scan_idx) == true, "should be");
-
-        // BitMap::get_next_one_offset() can handle the case when
-        // its left_offset parameter is greater than its right_offset
-        // parameter. It does, however, have an early exit if
-        // left_offset == right_offset. So let's limit the value
-        // passed in for left offset here.
-        BitMap::idx_t next_idx = MIN2(scan_idx + 1, limit_idx);
-        scan_idx = task_card_bm->get_next_one_offset(next_idx, limit_idx);
-      }
-    }
-
-    // Update the marked bytes for this region.
-    hr->add_to_marked_bytes(marked_bytes);
-
-    // Next heap region
-    return false;
-  }
-};
-
-class G1AggregateCountDataTask: public AbstractGangTask {
-protected:
-  G1CollectedHeap* _g1h;
-  G1ConcurrentMark* _cm;
-  BitMap* _cm_card_bm;
-  uint _max_worker_id;
-  uint _active_workers;
-  HeapRegionClaimer _hrclaimer;
-
-public:
-  G1AggregateCountDataTask(G1CollectedHeap* g1h,
-                           G1ConcurrentMark* cm,
-                           BitMap* cm_card_bm,
-                           uint max_worker_id,
-                           uint n_workers) :
-      AbstractGangTask("Count Aggregation"),
-      _g1h(g1h), _cm(cm), _cm_card_bm(cm_card_bm),
-      _max_worker_id(max_worker_id),
-      _active_workers(n_workers),
-      _hrclaimer(_active_workers) {
-  }
-
-  void work(uint worker_id) {
-    AggregateCountDataHRClosure cl(_g1h, _cm_card_bm, _max_worker_id);
-
-    _g1h->heap_region_par_iterate(&cl, worker_id, &_hrclaimer);
-  }
-};
-
-
-void G1ConcurrentMark::aggregate_count_data() {
-  uint n_workers = _g1h->workers()->active_workers();
-
-  G1AggregateCountDataTask g1_par_agg_task(_g1h, this, &_card_bm,
-                                           _max_worker_id, n_workers);
-
-  _g1h->workers()->run_task(&g1_par_agg_task);
+void G1ConcurrentMark::create_live_data() {
+  _g1h->g1_rem_set()->create_card_live_data(_parallel_workers, _nextMarkBitMap);
+}
+
+void G1ConcurrentMark::finalize_live_data() {
+  _g1h->g1_rem_set()->finalize_card_live_data(_g1h->workers(), _nextMarkBitMap);
+}
+
+void G1ConcurrentMark::verify_live_data() {
+  _g1h->g1_rem_set()->verify_card_live_data(_g1h->workers(), _nextMarkBitMap);
 }
 
-// Clear the per-worker arrays used to store the per-region counting data
-void G1ConcurrentMark::clear_all_count_data() {
-  // Clear the global card bitmap - it will be filled during
-  // liveness count aggregation (during remark) and the
-  // final counting task.
-  _card_bm.clear();
-
-  // Clear the global region bitmap - it will be filled as part
-  // of the final counting task.
-  _region_bm.clear();
-
-  uint max_regions = _g1h->max_regions();
-  assert(_max_worker_id > 0, "uninitialized");
-
-  for (uint i = 0; i < _max_worker_id; i += 1) {
-    BitMap* task_card_bm = count_card_bitmap_for(i);
-    size_t* marked_bytes_array = count_marked_bytes_array_for(i);
-
-    assert(task_card_bm->size() == _card_bm.size(), "size mismatch");
-    assert(marked_bytes_array != NULL, "uninitialized");
-
-    memset(marked_bytes_array, 0, (size_t) max_regions * sizeof(size_t));
-    task_card_bm->clear();
-  }
+void G1ConcurrentMark::clear_live_data(WorkGang* workers) {
+  _g1h->g1_rem_set()->clear_card_live_data(workers);
 }
 
+#ifdef ASSERT
+void G1ConcurrentMark::verify_live_data_clear() {
+  _g1h->g1_rem_set()->verify_card_live_data_is_clear();
+}
+#endif
+
 void G1ConcurrentMark::print_stats() {
   if (!log_is_enabled(Debug, gc, stats)) {
     return;
@@ -2574,7 +2029,6 @@
   }
 }
 
-// abandon current marking iteration due to a Full GC
 void G1ConcurrentMark::abort() {
   if (!cmThread()->during_cycle() || _has_aborted) {
     // We haven't started a concurrent cycle or we have already aborted it. No need to do anything.
@@ -2583,14 +2037,22 @@
 
   // Clear all marks in the next bitmap for the next marking cycle. This will allow us to skip the next
   // concurrent bitmap clearing.
-  clear_bitmap(_nextMarkBitMap, _g1h->workers(), false);
-
+  {
+    GCTraceTime(Debug, gc)("Clear Next Bitmap");
+    clear_bitmap(_nextMarkBitMap, _g1h->workers(), false);
+  }
   // Note we cannot clear the previous marking bitmap here
   // since VerifyDuringGC verifies the objects marked during
   // a full GC against the previous bitmap.
 
-  // Clear the liveness counting data
-  clear_all_count_data();
+  {
+    GCTraceTime(Debug, gc)("Clear Live Data");
+    clear_live_data(_g1h->workers());
+  }
+  DEBUG_ONLY({
+    GCTraceTime(Debug, gc)("Verify Live Data Clear");
+    verify_live_data_clear();
+  })
   // Empty mark stack
   reset_marking_state();
   for (uint i = 0; i < _max_worker_id; ++i) {
@@ -2634,7 +2096,7 @@
 
   }
   print_ms_time_info("  ", "cleanups", _cleanup_times);
-  log.trace("    Final counting total time = %8.2f s (avg = %8.2f ms).",
+  log.trace("    Finalize live data total time = %8.2f s (avg = %8.2f ms).",
             _total_counting_time, (_cleanup_times.num() > 0 ? _total_counting_time * 1000.0 / (double)_cleanup_times.num() : 0.0));
   if (G1ScrubRemSets) {
     log.trace("    RS scrub total time = %8.2f s (avg = %8.2f ms).",
@@ -2650,6 +2112,10 @@
   _parallel_workers->print_worker_threads_on(st);
 }
 
+void G1ConcurrentMark::threads_do(ThreadClosure* tc) const {
+  _parallel_workers->threads_do(tc);
+}
+
 void G1ConcurrentMark::print_on_error(outputStream* st) const {
   st->print_cr("Marking Bits (Prev, Next): (CMBitMap*) " PTR_FORMAT ", (CMBitMap*) " PTR_FORMAT,
       p2i(_prevMarkBitMap), p2i(_nextMarkBitMap));
@@ -2657,16 +2123,6 @@
   _nextMarkBitMap->print_on_error(st, " Next Bits: ");
 }
 
-// We take a break if someone is trying to stop the world.
-bool G1ConcurrentMark::do_yield_check(uint worker_id) {
-  if (SuspendibleThreadSet::should_yield()) {
-    SuspendibleThreadSet::yield();
-    return true;
-  } else {
-    return false;
-  }
-}
-
 // Closure for iteration over bitmaps
 class G1CMBitMapClosure : public BitMapClosure {
 private:
@@ -3473,8 +2929,6 @@
 
 G1CMTask::G1CMTask(uint worker_id,
                    G1ConcurrentMark* cm,
-                   size_t* marked_bytes,
-                   BitMap* card_bm,
                    G1CMTaskQueue* task_queue,
                    G1CMTaskQueueSet* task_queues)
   : _g1h(G1CollectedHeap::heap()),
@@ -3483,9 +2937,7 @@
     _nextMarkBitMap(NULL), _hash_seed(17),
     _task_queue(task_queue),
     _task_queues(task_queues),
-    _cm_oop_closure(NULL),
-    _marked_bytes_array(marked_bytes),
-    _card_bm(card_bm) {
+    _cm_oop_closure(NULL) {
   guarantee(task_queue != NULL, "invariant");
   guarantee(task_queues != NULL, "invariant");
 
--- a/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -266,7 +266,7 @@
 class G1ConcurrentMark: public CHeapObj<mtGC> {
   friend class ConcurrentMarkThread;
   friend class G1ParNoteEndTask;
-  friend class CalcLiveObjectsClosure;
+  friend class G1VerifyLiveDataClosure;
   friend class G1CMRefProcTaskProxy;
   friend class G1CMRefProcTaskExecutor;
   friend class G1CMKeepAliveAndDrainClosure;
@@ -298,9 +298,6 @@
   G1CMBitMapRO*           _prevMarkBitMap; // Completed mark bitmap
   G1CMBitMap*             _nextMarkBitMap; // Under-construction mark bitmap
 
-  BitMap                  _region_bm;
-  BitMap                  _card_bm;
-
   // Heap bounds
   HeapWord*               _heap_start;
   HeapWord*               _heap_end;
@@ -461,23 +458,6 @@
   void enter_first_sync_barrier(uint worker_id);
   void enter_second_sync_barrier(uint worker_id);
 
-  // Live Data Counting data structures...
-  // These data structures are initialized at the start of
-  // marking. They are written to while marking is active.
-  // They are aggregated during remark; the aggregated values
-  // are then used to populate the _region_bm, _card_bm, and
-  // the total live bytes, which are then subsequently updated
-  // during cleanup.
-
-  // An array of bitmaps (one bit map per task). Each bitmap
-  // is used to record the cards spanned by the live objects
-  // marked by that task/worker.
-  BitMap*  _count_card_bitmaps;
-
-  // Used to record the number of marked live bytes
-  // (for each region, by worker thread).
-  size_t** _count_marked_bytes;
-
   // Card index of the bottom of the G1 heap. Used for biasing indices into
   // the card bitmaps.
   intptr_t _heap_bottom_card_num;
@@ -563,18 +543,10 @@
   // G1CollectedHeap
 
   // This notifies CM that a root during initial-mark needs to be
-  // grayed. It is MT-safe. word_size is the size of the object in
-  // words. It is passed explicitly as sometimes we cannot calculate
-  // it from the given object because it might be in an inconsistent
-  // state (e.g., in to-space and being copied). So the caller is
-  // responsible for dealing with this issue (e.g., get the size from
-  // the from-space image when the to-space image might be
-  // inconsistent) and always passing the size. hr is the region that
+  // grayed. It is MT-safe. hr is the region that
   // contains the object and it's passed optionally from callers who
   // might already have it (no point in recalculating it).
   inline void grayRoot(oop obj,
-                       size_t word_size,
-                       uint worker_id,
                        HeapRegion* hr = NULL);
 
   // Prepare internal data structures for the next mark cycle. This includes clearing
@@ -603,7 +575,7 @@
   void scan_root_regions();
 
   // Scan a single root region and mark everything reachable from it.
-  void scanRootRegion(HeapRegion* hr, uint worker_id);
+  void scanRootRegion(HeapRegion* hr);
 
   // Do concurrent phase of marking, to a tentative transitive closure.
   void mark_from_roots();
@@ -639,9 +611,9 @@
 
   inline bool isPrevMarked(oop p) const;
 
-  inline bool do_yield_check(uint worker_i = 0);
+  inline bool do_yield_check();
 
-  // Called to abort the marking cycle after a Full GC takes place.
+  // Abandon current marking iteration due to a Full GC.
   void abort();
 
   bool has_aborted()      { return _has_aborted; }
@@ -649,78 +621,12 @@
   void print_summary_info();
 
   void print_worker_threads_on(outputStream* st) const;
+  void threads_do(ThreadClosure* tc) const;
 
   void print_on_error(outputStream* st) const;
 
-  // Liveness counting
-
-  // Utility routine to set an exclusive range of cards on the given
-  // card liveness bitmap
-  inline void set_card_bitmap_range(BitMap* card_bm,
-                                    BitMap::idx_t start_idx,
-                                    BitMap::idx_t end_idx,
-                                    bool is_par);
-
-  // Returns the card number of the bottom of the G1 heap.
-  // Used in biasing indices into accounting card bitmaps.
-  intptr_t heap_bottom_card_num() const {
-    return _heap_bottom_card_num;
-  }
-
-  // Returns the card bitmap for a given task or worker id.
-  BitMap* count_card_bitmap_for(uint worker_id) {
-    assert(worker_id < _max_worker_id, "oob");
-    assert(_count_card_bitmaps != NULL, "uninitialized");
-    BitMap* task_card_bm = &_count_card_bitmaps[worker_id];
-    assert(task_card_bm->size() == _card_bm.size(), "size mismatch");
-    return task_card_bm;
-  }
-
-  // Returns the array containing the marked bytes for each region,
-  // for the given worker or task id.
-  size_t* count_marked_bytes_array_for(uint worker_id) {
-    assert(worker_id < _max_worker_id, "oob");
-    assert(_count_marked_bytes != NULL, "uninitialized");
-    size_t* marked_bytes_array = _count_marked_bytes[worker_id];
-    assert(marked_bytes_array != NULL, "uninitialized");
-    return marked_bytes_array;
-  }
-
-  // Returns the index in the liveness accounting card table bitmap
-  // for the given address
-  inline BitMap::idx_t card_bitmap_index_for(HeapWord* addr);
-
-  // Counts the size of the given memory region in the the given
-  // marked_bytes array slot for the given HeapRegion.
-  // Sets the bits in the given card bitmap that are associated with the
-  // cards that are spanned by the memory region.
-  inline void count_region(MemRegion mr,
-                           HeapRegion* hr,
-                           size_t* marked_bytes_array,
-                           BitMap* task_card_bm);
-
-  // Counts the given object in the given task/worker counting
-  // data structures.
-  inline void count_object(oop obj,
-                           HeapRegion* hr,
-                           size_t* marked_bytes_array,
-                           BitMap* task_card_bm,
-                           size_t word_size);
-
-  // Attempts to mark the given object and, if successful, counts
-  // the object in the given task/worker counting structures.
-  inline bool par_mark_and_count(oop obj,
-                                 HeapRegion* hr,
-                                 size_t* marked_bytes_array,
-                                 BitMap* task_card_bm);
-
-  // Attempts to mark the given object and, if successful, counts
-  // the object in the task/worker counting structures for the
-  // given worker id.
-  inline bool par_mark_and_count(oop obj,
-                                 size_t word_size,
-                                 HeapRegion* hr,
-                                 uint worker_id);
+  // Attempts to mark the given object on the next mark bitmap.
+  inline bool par_mark(oop obj);
 
   // Returns true if initialization was successfully completed.
   bool completed_initialization() const {
@@ -730,19 +636,22 @@
   ConcurrentGCTimer* gc_timer_cm() const { return _gc_timer_cm; }
   G1OldTracer* gc_tracer_cm() const { return _gc_tracer_cm; }
 
-protected:
-  // Clear all the per-task bitmaps and arrays used to store the
-  // counting data.
-  void clear_all_count_data();
+private:
+  // Clear (Reset) all liveness count data.
+  void clear_live_data(WorkGang* workers);
 
-  // Aggregates the counting data for each worker/task
-  // that was constructed while marking. Also sets
-  // the amount of marked bytes for each region and
-  // the top at concurrent mark count.
-  void aggregate_count_data();
+#ifdef ASSERT
+  // Verify all of the above data structures that they are in initial state.
+  void verify_live_data_clear();
+#endif
 
-  // Verification routine
-  void verify_count_data();
+  // Aggregates the per-card liveness data based on the current marking. Also sets
+  // the amount of marked bytes for each region.
+  void create_live_data();
+
+  void finalize_live_data();
+
+  void verify_live_data();
 };
 
 // A class representing a marking task.
@@ -844,12 +753,6 @@
 
   TruncatedSeq                _marking_step_diffs_ms;
 
-  // Counting data structures. Embedding the task's marked_bytes_array
-  // and card bitmap into the actual task saves having to go through
-  // the ConcurrentMark object.
-  size_t*                     _marked_bytes_array;
-  BitMap*                     _card_bm;
-
   // it updates the local fields after this task has claimed
   // a new region to scan
   void setup_for_region(HeapRegion* hr);
@@ -936,9 +839,8 @@
 
   // Grey the object by marking it.  If not already marked, push it on
   // the local queue if below the finger.
-  // Precondition: obj is in region.
-  // Precondition: obj is below region's NTAMS.
-  inline void make_reference_grey(oop obj, HeapRegion* region);
+  // obj is below its region's NTAMS.
+  inline void make_reference_grey(oop obj);
 
   // Grey the object (by calling make_grey_reference) if required,
   // e.g. obj is below its containing region's NTAMS.
@@ -976,8 +878,6 @@
 
   G1CMTask(uint worker_id,
            G1ConcurrentMark *cm,
-           size_t* marked_bytes,
-           BitMap* card_bm,
            G1CMTaskQueue* task_queue,
            G1CMTaskQueueSet* task_queues);
 
--- a/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.inline.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.inline.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -27,140 +27,11 @@
 
 #include "gc/g1/g1CollectedHeap.inline.hpp"
 #include "gc/g1/g1ConcurrentMark.hpp"
+#include "gc/g1/suspendibleThreadSet.hpp"
 #include "gc/shared/taskqueue.inline.hpp"
 
-// Utility routine to set an exclusive range of cards on the given
-// card liveness bitmap
-inline void G1ConcurrentMark::set_card_bitmap_range(BitMap* card_bm,
-                                                    BitMap::idx_t start_idx,
-                                                    BitMap::idx_t end_idx,
-                                                    bool is_par) {
-
-  // Set the exclusive bit range [start_idx, end_idx).
-  assert((end_idx - start_idx) > 0, "at least one card");
-  assert(end_idx <= card_bm->size(), "sanity");
-
-  // Silently clip the end index
-  end_idx = MIN2(end_idx, card_bm->size());
-
-  // For small ranges use a simple loop; otherwise use set_range or
-  // use par_at_put_range (if parallel). The range is made up of the
-  // cards that are spanned by an object/mem region so 8 cards will
-  // allow up to object sizes up to 4K to be handled using the loop.
-  if ((end_idx - start_idx) <= 8) {
-    for (BitMap::idx_t i = start_idx; i < end_idx; i += 1) {
-      if (is_par) {
-        card_bm->par_set_bit(i);
-      } else {
-        card_bm->set_bit(i);
-      }
-    }
-  } else {
-    // Note BitMap::par_at_put_range() and BitMap::set_range() are exclusive.
-    if (is_par) {
-      card_bm->par_at_put_range(start_idx, end_idx, true);
-    } else {
-      card_bm->set_range(start_idx, end_idx);
-    }
-  }
-}
-
-// Returns the index in the liveness accounting card bitmap
-// for the given address
-inline BitMap::idx_t G1ConcurrentMark::card_bitmap_index_for(HeapWord* addr) {
-  // Below, the term "card num" means the result of shifting an address
-  // by the card shift -- address 0 corresponds to card number 0.  One
-  // must subtract the card num of the bottom of the heap to obtain a
-  // card table index.
-  intptr_t card_num = intptr_t(uintptr_t(addr) >> CardTableModRefBS::card_shift);
-  return card_num - heap_bottom_card_num();
-}
-
-// Counts the given memory region in the given task/worker
-// counting data structures.
-inline void G1ConcurrentMark::count_region(MemRegion mr, HeapRegion* hr,
-                                           size_t* marked_bytes_array,
-                                           BitMap* task_card_bm) {
-  G1CollectedHeap* g1h = _g1h;
-  CardTableModRefBS* ct_bs = g1h->g1_barrier_set();
-
-  HeapWord* start = mr.start();
-  HeapWord* end = mr.end();
-  size_t region_size_bytes = mr.byte_size();
-  uint index = hr->hrm_index();
-
-  assert(hr == g1h->heap_region_containing(start), "sanity");
-  assert(marked_bytes_array != NULL, "pre-condition");
-  assert(task_card_bm != NULL, "pre-condition");
-
-  // Add to the task local marked bytes for this region.
-  marked_bytes_array[index] += region_size_bytes;
-
-  BitMap::idx_t start_idx = card_bitmap_index_for(start);
-  BitMap::idx_t end_idx = card_bitmap_index_for(end);
-
-  // Note: if we're looking at the last region in heap - end
-  // could be actually just beyond the end of the heap; end_idx
-  // will then correspond to a (non-existent) card that is also
-  // just beyond the heap.
-  if (g1h->is_in_g1_reserved(end) && !ct_bs->is_card_aligned(end)) {
-    // end of region is not card aligned - increment to cover
-    // all the cards spanned by the region.
-    end_idx += 1;
-  }
-  // The card bitmap is task/worker specific => no need to use
-  // the 'par' BitMap routines.
-  // Set bits in the exclusive bit range [start_idx, end_idx).
-  set_card_bitmap_range(task_card_bm, start_idx, end_idx, false /* is_par */);
-}
-
-// Counts the given object in the given task/worker counting data structures.
-inline void G1ConcurrentMark::count_object(oop obj,
-                                           HeapRegion* hr,
-                                           size_t* marked_bytes_array,
-                                           BitMap* task_card_bm,
-                                           size_t word_size) {
-  assert(!hr->is_continues_humongous(), "Cannot enter count_object with continues humongous");
-  if (!hr->is_starts_humongous()) {
-    MemRegion mr((HeapWord*)obj, word_size);
-    count_region(mr, hr, marked_bytes_array, task_card_bm);
-  } else {
-    do {
-      MemRegion mr(hr->bottom(), hr->top());
-      count_region(mr, hr, marked_bytes_array, task_card_bm);
-      hr = _g1h->next_region_in_humongous(hr);
-    } while (hr != NULL);
-  }
-}
-
-// Attempts to mark the given object and, if successful, counts
-// the object in the given task/worker counting structures.
-inline bool G1ConcurrentMark::par_mark_and_count(oop obj,
-                                                 HeapRegion* hr,
-                                                 size_t* marked_bytes_array,
-                                                 BitMap* task_card_bm) {
-  if (_nextMarkBitMap->parMark((HeapWord*)obj)) {
-    // Update the task specific count data for the object.
-    count_object(obj, hr, marked_bytes_array, task_card_bm, obj->size());
-    return true;
-  }
-  return false;
-}
-
-// Attempts to mark the given object and, if successful, counts
-// the object in the task/worker counting structures for the
-// given worker id.
-inline bool G1ConcurrentMark::par_mark_and_count(oop obj,
-                                                 size_t word_size,
-                                                 HeapRegion* hr,
-                                                 uint worker_id) {
-  if (_nextMarkBitMap->parMark((HeapWord*)obj)) {
-    size_t* marked_bytes_array = count_marked_bytes_array_for(worker_id);
-    BitMap* task_card_bm = count_card_bitmap_for(worker_id);
-    count_object(obj, hr, marked_bytes_array, task_card_bm, word_size);
-    return true;
-  }
-  return false;
+inline bool G1ConcurrentMark::par_mark(oop obj) {
+  return _nextMarkBitMap->parMark((HeapWord*)obj);
 }
 
 inline bool G1CMBitMapRO::iterate(BitMapClosure* cl, MemRegion mr) {
@@ -294,10 +165,8 @@
   check_limits();
 }
 
-
-
-inline void G1CMTask::make_reference_grey(oop obj, HeapRegion* hr) {
-  if (_cm->par_mark_and_count(obj, hr, _marked_bytes_array, _card_bm)) {
+inline void G1CMTask::make_reference_grey(oop obj) {
+  if (_cm->par_mark(obj)) {
     // No OrderAccess:store_load() is needed. It is implicit in the
     // CAS done in G1CMBitMap::parMark() call in the routine above.
     HeapWord* global_finger = _cm->finger();
@@ -348,7 +217,7 @@
       // anything with it).
       HeapRegion* hr = _g1h->heap_region_containing(obj);
       if (!hr->obj_allocated_since_next_marking(obj)) {
-        make_reference_grey(obj, hr);
+        make_reference_grey(obj);
       }
     }
   }
@@ -370,8 +239,7 @@
   return _prevMarkBitMap->isMarked(addr);
 }
 
-inline void G1ConcurrentMark::grayRoot(oop obj, size_t word_size,
-                                       uint worker_id, HeapRegion* hr) {
+inline void G1ConcurrentMark::grayRoot(oop obj, HeapRegion* hr) {
   assert(obj != NULL, "pre-condition");
   HeapWord* addr = (HeapWord*) obj;
   if (hr == NULL) {
@@ -386,9 +254,18 @@
 
   if (addr < hr->next_top_at_mark_start()) {
     if (!_nextMarkBitMap->isMarked(addr)) {
-      par_mark_and_count(obj, word_size, hr, worker_id);
+      par_mark(obj);
     }
   }
 }
 
+inline bool G1ConcurrentMark::do_yield_check() {
+  if (SuspendibleThreadSet::should_yield()) {
+    SuspendibleThreadSet::yield();
+    return true;
+  } else {
+    return false;
+  }
+}
+
 #endif // SHARE_VM_GC_G1_G1CONCURRENTMARK_INLINE_HPP
--- a/hotspot/src/share/vm/gc/g1/g1EvacFailure.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1EvacFailure.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -95,8 +95,6 @@
   void do_object(oop obj) {
     HeapWord* obj_addr = (HeapWord*) obj;
     assert(_hr->is_in(obj_addr), "sanity");
-    size_t obj_size = obj->size();
-    HeapWord* obj_end = obj_addr + obj_size;
 
     if (obj->is_forwarded() && obj->forwardee() == obj) {
       // The object failed to move.
@@ -119,8 +117,10 @@
         // explicitly and all objects in the CSet are considered
         // (implicitly) live. So, we won't mark them explicitly and
         // we'll leave them over NTAMS.
-        _cm->grayRoot(obj, obj_size, _worker_id, _hr);
+        _cm->grayRoot(obj, _hr);
       }
+      size_t obj_size = obj->size();
+
       _marked_bytes += (obj_size * HeapWordSize);
       obj->set_mark(markOopDesc::prototype());
 
@@ -138,6 +138,7 @@
       // the collection set. So, we'll recreate such entries now.
       obj->oop_iterate(_update_rset_cl);
 
+      HeapWord* obj_end = obj_addr + obj_size;
       _last_forwarded_object_end = obj_end;
       _hr->cross_threshold(obj_addr, obj_end);
     }
--- a/hotspot/src/share/vm/gc/g1/g1OopClosures.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1OopClosures.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -186,11 +186,9 @@
 private:
   G1CollectedHeap* _g1h;
   G1ConcurrentMark* _cm;
-  uint _worker_id;
 public:
-  G1RootRegionScanClosure(G1CollectedHeap* g1h, G1ConcurrentMark* cm,
-                          uint worker_id) :
-    _g1h(g1h), _cm(cm), _worker_id(worker_id) { }
+  G1RootRegionScanClosure(G1CollectedHeap* g1h, G1ConcurrentMark* cm) :
+    _g1h(g1h), _cm(cm) { }
   template <class T> void do_oop_nv(T* p);
   virtual void do_oop(      oop* p) { do_oop_nv(p); }
   virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
--- a/hotspot/src/share/vm/gc/g1/g1OopClosures.inline.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1OopClosures.inline.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -131,7 +131,7 @@
   if (!oopDesc::is_null(heap_oop)) {
     oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
     HeapRegion* hr = _g1h->heap_region_containing((HeapWord*) obj);
-    _cm->grayRoot(obj, obj->size(), _worker_id, hr);
+    _cm->grayRoot(obj, hr);
   }
 }
 
@@ -246,7 +246,7 @@
   assert(!_g1->heap_region_containing(obj)->in_collection_set(), "should not mark objects in the CSet");
 
   // We know that the object is not moving so it's safe to read its size.
-  _cm->grayRoot(obj, (size_t) obj->size(), _worker_id);
+  _cm->grayRoot(obj);
 }
 
 void G1ParCopyHelper::mark_forwarded_object(oop from_obj, oop to_obj) {
@@ -261,7 +261,7 @@
   // worker so we cannot trust that its to-space image is
   // well-formed. So we have to read its size from its from-space
   // image which we know should not be changing.
-  _cm->grayRoot(to_obj, (size_t) from_obj->size(), _worker_id);
+  _cm->grayRoot(to_obj);
 }
 
 template <G1Barrier barrier, G1Mark do_mark_object, bool use_ext>
--- a/hotspot/src/share/vm/gc/g1/g1RemSet.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1RemSet.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -38,6 +38,7 @@
 #include "gc/g1/heapRegion.inline.hpp"
 #include "gc/g1/heapRegionManager.inline.hpp"
 #include "gc/g1/heapRegionRemSet.hpp"
+#include "gc/shared/gcTraceTime.inline.hpp"
 #include "memory/iterator.hpp"
 #include "memory/resourceArea.hpp"
 #include "oops/oop.inline.hpp"
@@ -84,8 +85,16 @@
   return MAX2(DirtyCardQueueSet::num_par_ids() + ConcurrentG1Refine::thread_num(), ParallelGCThreads);
 }
 
-void G1RemSet::initialize(uint max_regions) {
+void G1RemSet::initialize(size_t capacity, uint max_regions) {
   G1FromCardCache::initialize(num_par_rem_sets(), max_regions);
+  {
+    GCTraceTime(Debug, gc, marking)("Initialize Card Live Data");
+    _card_live_data.initialize(capacity, max_regions);
+  }
+  if (G1PretouchAuxiliaryMemory) {
+    GCTraceTime(Debug, gc, marking)("Pre-Touch Card Live Data");
+    _card_live_data.pretouch();
+  }
 }
 
 ScanRSClosure::ScanRSClosure(G1ParPushHeapRSClosure* oc,
@@ -312,27 +321,24 @@
   _into_cset_dirty_card_queue_set.clear_n_completed_buffers();
 }
 
-class ScrubRSClosure: public HeapRegionClosure {
+class G1ScrubRSClosure: public HeapRegionClosure {
   G1CollectedHeap* _g1h;
-  BitMap* _region_bm;
-  BitMap* _card_bm;
-  CardTableModRefBS* _ctbs;
+  G1CardLiveData* _live_data;
 public:
-  ScrubRSClosure(BitMap* region_bm, BitMap* card_bm) :
+  G1ScrubRSClosure(G1CardLiveData* live_data) :
     _g1h(G1CollectedHeap::heap()),
-    _region_bm(region_bm), _card_bm(card_bm),
-    _ctbs(_g1h->g1_barrier_set()) {}
+    _live_data(live_data) { }
 
   bool doHeapRegion(HeapRegion* r) {
     if (!r->is_continues_humongous()) {
-      r->rem_set()->scrub(_ctbs, _region_bm, _card_bm);
+      r->rem_set()->scrub(_live_data);
     }
     return false;
   }
 };
 
-void G1RemSet::scrub(BitMap* region_bm, BitMap* card_bm, uint worker_num, HeapRegionClaimer *hrclaimer) {
-  ScrubRSClosure scrub_cl(region_bm, card_bm);
+void G1RemSet::scrub(uint worker_num, HeapRegionClaimer *hrclaimer) {
+  G1ScrubRSClosure scrub_cl(&_card_live_data);
   _g1->heap_region_par_iterate(&scrub_cl, worker_num, hrclaimer);
 }
 
@@ -580,3 +586,25 @@
     assert(JavaThread::dirty_card_queue_set().completed_buffers_num() == 0, "All should be consumed");
   }
 }
+
+void G1RemSet::create_card_live_data(WorkGang* workers, G1CMBitMap* mark_bitmap) {
+  _card_live_data.create(workers, mark_bitmap);
+}
+
+void G1RemSet::finalize_card_live_data(WorkGang* workers, G1CMBitMap* mark_bitmap) {
+  _card_live_data.finalize(workers, mark_bitmap);
+}
+
+void G1RemSet::verify_card_live_data(WorkGang* workers, G1CMBitMap* bitmap) {
+  _card_live_data.verify(workers, bitmap);
+}
+
+void G1RemSet::clear_card_live_data(WorkGang* workers) {
+  _card_live_data.clear(workers);
+}
+
+#ifdef ASSERT
+void G1RemSet::verify_card_live_data_is_clear() {
+  _card_live_data.verify_is_clear();
+}
+#endif
--- a/hotspot/src/share/vm/gc/g1/g1RemSet.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1RemSet.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -26,6 +26,7 @@
 #define SHARE_VM_GC_G1_G1REMSET_HPP
 
 #include "gc/g1/dirtyCardQueue.hpp"
+#include "gc/g1/g1CardLiveData.hpp"
 #include "gc/g1/g1RemSetSummary.hpp"
 #include "gc/g1/heapRegion.hpp"
 #include "memory/allocation.hpp"
@@ -48,9 +49,10 @@
 // A G1RemSet in which each heap region has a rem set that records the
 // external heap references into it.  Uses a mod ref bs to track updates,
 // so that they can be used to update the individual region remsets.
-
 class G1RemSet: public CHeapObj<mtGC> {
 private:
+  G1CardLiveData _card_live_data;
+
   G1RemSetSummary _prev_period_summary;
 
   // A DirtyCardQueueSet that is used to hold cards that contain
@@ -83,7 +85,7 @@
   static uint num_par_rem_sets();
 
   // Initialize data that depends on the heap size being known.
-  static void initialize(uint max_regions);
+  void initialize(size_t capacity, uint max_regions);
 
   // This is called to reset dual hash tables after the gc pause
   // is finished and the initial hash table is no longer being
@@ -140,7 +142,7 @@
   // set entries that correspond to dead heap ranges. "worker_num" is the
   // parallel thread id of the current thread, and "hrclaimer" is the
   // HeapRegionClaimer that should be used.
-  void scrub(BitMap* region_bm, BitMap* card_bm, uint worker_num, HeapRegionClaimer* hrclaimer);
+  void scrub(uint worker_num, HeapRegionClaimer* hrclaimer);
 
   // Refine the card corresponding to "card_ptr".
   // If check_for_refs_into_cset is true, a true result is returned
@@ -162,6 +164,19 @@
   size_t conc_refine_cards() const {
     return _conc_refine_cards;
   }
+
+  void create_card_live_data(WorkGang* workers, G1CMBitMap* mark_bitmap);
+  void finalize_card_live_data(WorkGang* workers, G1CMBitMap* mark_bitmap);
+
+  // Verify that the liveness count data created concurrently matches one created
+  // during this safepoint.
+  void verify_card_live_data(WorkGang* workers, G1CMBitMap* actual_bitmap);
+
+  void clear_card_live_data(WorkGang* workers);
+
+#ifdef ASSERT
+  void verify_card_live_data_is_clear();
+#endif
 };
 
 class ScanRSClosure : public HeapRegionClosure {
--- a/hotspot/src/share/vm/gc/g1/g1YoungGenSizer.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1YoungGenSizer.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -25,12 +25,13 @@
 #include "precompiled.hpp"
 #include "gc/g1/g1YoungGenSizer.hpp"
 #include "gc/g1/heapRegion.hpp"
+#include "logging/log.hpp"
 
 G1YoungGenSizer::G1YoungGenSizer() : _sizer_kind(SizerDefaults), _adaptive_size(true),
         _min_desired_young_length(0), _max_desired_young_length(0) {
   if (FLAG_IS_CMDLINE(NewRatio)) {
     if (FLAG_IS_CMDLINE(NewSize) || FLAG_IS_CMDLINE(MaxNewSize)) {
-      warning("-XX:NewSize and -XX:MaxNewSize override -XX:NewRatio");
+      log_warning(gc, ergo)("-XX:NewSize and -XX:MaxNewSize override -XX:NewRatio");
     } else {
       _sizer_kind = SizerNewRatio;
       _adaptive_size = false;
@@ -40,9 +41,9 @@
 
   if (NewSize > MaxNewSize) {
     if (FLAG_IS_CMDLINE(MaxNewSize)) {
-      warning("NewSize (" SIZE_FORMAT "k) is greater than the MaxNewSize (" SIZE_FORMAT "k). "
-              "A new max generation size of " SIZE_FORMAT "k will be used.",
-              NewSize/K, MaxNewSize/K, NewSize/K);
+      log_warning(gc, ergo)("NewSize (" SIZE_FORMAT "k) is greater than the MaxNewSize (" SIZE_FORMAT "k). "
+                            "A new max generation size of " SIZE_FORMAT "k will be used.",
+                            NewSize/K, MaxNewSize/K, NewSize/K);
     }
     MaxNewSize = NewSize;
   }
--- a/hotspot/src/share/vm/gc/g1/g1_globals.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1_globals.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -112,8 +112,7 @@
   product(size_t, G1ConcRefinementRedZone, 0,                               \
           "Maximum number of enqueued update buffers before mutator "       \
           "threads start processing new ones instead of enqueueing them. "  \
-          "Will be selected ergonomically by default. Zero will disable "   \
-          "concurrent processing.")                                         \
+          "Will be selected ergonomically by default.")                     \
           range(0, max_intx)                                                \
                                                                             \
   product(size_t, G1ConcRefinementGreenZone, 0,                             \
@@ -127,11 +126,12 @@
           "specified number of milliseconds to do miscellaneous work.")     \
           range(0, max_jint)                                                \
                                                                             \
-  product(size_t, G1ConcRefinementThresholdStep, 0,                         \
+  product(size_t, G1ConcRefinementThresholdStep, 2,                         \
           "Each time the rset update queue increases by this amount "       \
           "activate the next refinement thread if available. "              \
-          "Will be selected ergonomically by default.")                     \
-          range(0, SIZE_MAX)                                                \
+          "The actual step size will be selected ergonomically by "         \
+          "default, with this value used to determine a lower bound.")      \
+          range(1, SIZE_MAX)                                                \
                                                                             \
   product(intx, G1RSetUpdatingPauseTimePercent, 10,                         \
           "A target percentage of time that is allowed to be spend on "     \
@@ -201,9 +201,9 @@
           range(0, 32*M)                                                    \
           constraint(G1HeapRegionSizeConstraintFunc,AfterMemoryInit)        \
                                                                             \
-  product(uintx, G1ConcRefinementThreads, 0,                                \
-          "If non-0 is the number of parallel rem set update threads, "     \
-          "otherwise the value is determined ergonomically.")               \
+  product(uint, G1ConcRefinementThreads, 0,                                 \
+          "The number of parallel rem set update threads. "                 \
+          "Will be set ergonomically by default.")                          \
           range(0, (max_jint-1)/wordSize)                                   \
                                                                             \
   develop(bool, G1VerifyCTCleanup, false,                                   \
@@ -260,6 +260,9 @@
           "The target number of mixed GCs after a marking cycle.")          \
           range(0, max_uintx)                                               \
                                                                             \
+  experimental(bool, G1PretouchAuxiliaryMemory, false,                      \
+          "Pre-touch large auxiliary data structures used by the GC.")      \
+                                                                            \
   experimental(bool, G1EagerReclaimHumongousObjects, true,                  \
           "Try to reclaim dead large objects at every young GC.")           \
                                                                             \
--- a/hotspot/src/share/vm/gc/g1/heapRegionRemSet.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/heapRegionRemSet.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -26,6 +26,7 @@
 #include "gc/g1/concurrentG1Refine.hpp"
 #include "gc/g1/g1BlockOffsetTable.inline.hpp"
 #include "gc/g1/g1CollectedHeap.inline.hpp"
+#include "gc/g1/g1CardLiveData.inline.hpp"
 #include "gc/g1/heapRegionManager.inline.hpp"
 #include "gc/g1/heapRegionRemSet.hpp"
 #include "gc/shared/space.inline.hpp"
@@ -141,10 +142,8 @@
     add_reference_work(from, /*parallel*/ false);
   }
 
-  void scrub(CardTableModRefBS* ctbs, BitMap* card_bm) {
-    HeapWord* hr_bot = hr()->bottom();
-    size_t hr_first_card_index = ctbs->index_for(hr_bot);
-    bm()->set_intersection_at_offset(*card_bm, hr_first_card_index);
+  void scrub(G1CardLiveData* live_data) {
+    live_data->remove_nonlive_cards(hr()->hrm_index(), &_bm);
     recount_occupied();
   }
 
@@ -515,14 +514,12 @@
   return max;
 }
 
-void OtherRegionsTable::scrub(CardTableModRefBS* ctbs,
-                              BitMap* region_bm, BitMap* card_bm) {
+void OtherRegionsTable::scrub(G1CardLiveData* live_data) {
   // First eliminated garbage regions from the coarse map.
   log_develop_trace(gc, remset, scrub)("Scrubbing region %u:", _hr->hrm_index());
 
-  assert(_coarse_map.size() == region_bm->size(), "Precondition");
   log_develop_trace(gc, remset, scrub)("   Coarse map: before = " SIZE_FORMAT "...", _n_coarse_entries);
-  _coarse_map.set_intersection(*region_bm);
+  live_data->remove_nonlive_regions(&_coarse_map);
   _n_coarse_entries = _coarse_map.count_one_bits();
   log_develop_trace(gc, remset, scrub)("   after = " SIZE_FORMAT ".", _n_coarse_entries);
 
@@ -534,7 +531,7 @@
       PerRegionTable* nxt = cur->collision_list_next();
       // If the entire region is dead, eliminate.
       log_develop_trace(gc, remset, scrub)("     For other region %u:", cur->hr()->hrm_index());
-      if (!region_bm->at((size_t) cur->hr()->hrm_index())) {
+      if (!live_data->is_region_live(cur->hr()->hrm_index())) {
         *prev = nxt;
         cur->set_collision_list_next(NULL);
         _n_fine_entries--;
@@ -544,7 +541,7 @@
       } else {
         // Do fine-grain elimination.
         log_develop_trace(gc, remset, scrub)("          occ: before = %4d.", cur->occupied());
-        cur->scrub(ctbs, card_bm);
+        cur->scrub(live_data);
         log_develop_trace(gc, remset, scrub)("          after = %4d.", cur->occupied());
         // Did that empty the table completely?
         if (cur->occupied() == 0) {
@@ -773,9 +770,8 @@
   assert(verify_ready_for_par_iteration(), "post-condition");
 }
 
-void HeapRegionRemSet::scrub(CardTableModRefBS* ctbs,
-                             BitMap* region_bm, BitMap* card_bm) {
-  _other_regions.scrub(ctbs, region_bm, card_bm);
+void HeapRegionRemSet::scrub(G1CardLiveData* live_data) {
+  _other_regions.scrub(live_data);
 }
 
 // Code roots support
--- a/hotspot/src/share/vm/gc/g1/heapRegionRemSet.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/heapRegionRemSet.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -35,6 +35,7 @@
 
 class G1CollectedHeap;
 class G1BlockOffsetTable;
+class G1CardLiveData;
 class HeapRegion;
 class HeapRegionRemSetIterator;
 class PerRegionTable;
@@ -143,7 +144,7 @@
   // Removes any entries shown by the given bitmaps to contain only dead
   // objects. Not thread safe.
   // Set bits in the bitmaps indicate that the given region or card is live.
-  void scrub(CardTableModRefBS* ctbs, BitMap* region_bm, BitMap* card_bm);
+  void scrub(G1CardLiveData* live_data);
 
   // Returns whether this remembered set (and all sub-sets) does not contain any entry.
   bool is_empty() const;
@@ -230,10 +231,9 @@
     _other_regions.add_reference(from, tid);
   }
 
-  // Removes any entries in the remembered set shown by the given bitmaps to
+  // Removes any entries in the remembered set shown by the given card live data to
   // contain only dead objects. Not thread safe.
-  // One bits in the bitmaps indicate that the given region or card is live.
-  void scrub(CardTableModRefBS* ctbs, BitMap* region_bm, BitMap* card_bm);
+  void scrub(G1CardLiveData* live_data);
 
   // The region is being reclaimed; clear its remset, and any mention of
   // entries for this region in other remsets.
--- a/hotspot/src/share/vm/gc/parallel/generationSizer.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/gc/parallel/generationSizer.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -26,18 +26,6 @@
 #include "gc/parallel/generationSizer.hpp"
 #include "gc/shared/collectorPolicy.hpp"
 
-void GenerationSizer::trace_gen_sizes(const char* const str) {
-  if (TracePageSizes) {
-    tty->print_cr("%s:  " SIZE_FORMAT "," SIZE_FORMAT " "
-                  SIZE_FORMAT "," SIZE_FORMAT " "
-                  SIZE_FORMAT,
-                  str,
-                  _min_old_size / K, _max_old_size / K,
-                  _min_young_size / K, _max_young_size / K,
-                  _max_heap_byte_size / K);
-  }
-}
-
 void GenerationSizer::initialize_alignments() {
   _space_alignment = _gen_alignment = default_gen_alignment();
   _heap_alignment = compute_heap_alignment();
@@ -60,7 +48,6 @@
 }
 
 void GenerationSizer::initialize_size_info() {
-  trace_gen_sizes("ps heap raw");
   const size_t max_page_sz = os::page_size_for_region_aligned(_max_heap_byte_size, 8);
   const size_t min_pages = 4; // 1 for eden + 1 for each survivor + 1 for old
   const size_t min_page_sz = os::page_size_for_region_aligned(_min_heap_byte_size, min_pages);
@@ -76,6 +63,4 @@
     initialize_flags();
   }
   GenCollectorPolicy::initialize_size_info();
-
-  trace_gen_sizes("ps heap rnd");
 }
--- a/hotspot/src/share/vm/gc/parallel/generationSizer.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/gc/parallel/generationSizer.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -33,8 +33,6 @@
 class GenerationSizer : public GenCollectorPolicy {
  private:
 
-  void trace_gen_sizes(const char* const str);
-
   // The alignment used for boundary between young gen and old gen
   static size_t default_gen_alignment() { return 64 * K * HeapWordSize; }
 
--- a/hotspot/src/share/vm/gc/parallel/parMarkBitMap.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/gc/parallel/parMarkBitMap.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -49,7 +49,7 @@
   const size_t rs_align = page_sz == (size_t) os::vm_page_size() ? 0 :
     MAX2(page_sz, granularity);
   ReservedSpace rs(_reserved_byte_size, rs_align, rs_align > 0);
-  os::trace_page_sizes("par bitmap", raw_bytes, raw_bytes, page_sz,
+  os::trace_page_sizes("Mark Bitmap", raw_bytes, raw_bytes, page_sz,
                        rs.base(), rs.size());
 
   MemTracker::record_virtual_memory_type((address)rs.base(), mtGC);
--- a/hotspot/src/share/vm/gc/parallel/parallelScavengeHeap.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/gc/parallel/parallelScavengeHeap.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -60,8 +60,10 @@
 
   ReservedSpace heap_rs = Universe::reserve_heap(heap_size, _collector_policy->heap_alignment());
 
-  os::trace_page_sizes("ps main", _collector_policy->min_heap_byte_size(),
-                       heap_size, generation_alignment(),
+  os::trace_page_sizes("Heap",
+                       _collector_policy->min_heap_byte_size(),
+                       heap_size,
+                       generation_alignment(),
                        heap_rs.base(),
                        heap_rs.size());
 
--- a/hotspot/src/share/vm/gc/parallel/psAdaptiveSizePolicy.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/gc/parallel/psAdaptiveSizePolicy.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -32,7 +32,6 @@
 #include "gc/shared/gcPolicyCounters.hpp"
 #include "logging/log.hpp"
 #include "runtime/timer.hpp"
-#include "utilities/top.hpp"
 
 #include <math.h>
 
--- a/hotspot/src/share/vm/gc/parallel/psParallelCompact.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/gc/parallel/psParallelCompact.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -426,7 +426,7 @@
   const size_t rs_align = page_sz == (size_t) os::vm_page_size() ? 0 :
     MAX2(page_sz, granularity);
   ReservedSpace rs(_reserved_byte_size, rs_align, rs_align > 0);
-  os::trace_page_sizes("par compact", raw_bytes, raw_bytes, page_sz, rs.base(),
+  os::trace_page_sizes("Parallel Compact Data", raw_bytes, raw_bytes, page_sz, rs.base(),
                        rs.size());
 
   MemTracker::record_virtual_memory_type((address)rs.base(), mtGC);
--- a/hotspot/src/share/vm/gc/serial/defNewGeneration.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/gc/serial/defNewGeneration.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -692,7 +692,7 @@
     _promo_failure_scan_stack.clear(true); // Clear cached segments.
 
     remove_forwarding_pointers();
-    log_debug(gc)("Promotion failed");
+    log_info(gc, promotion)("Promotion failed");
     // Add to-space to the list of space to compact
     // when a promotion failure has occurred.  In that
     // case there can be live objects in to-space
@@ -739,8 +739,7 @@
   eden()->object_iterate(&rspc);
   from()->object_iterate(&rspc);
 
-  // Now restore saved marks, if any.
-  _preserved_marks_set.restore();
+  _preserved_marks_set.restore(GenCollectedHeap::heap()->workers());
 }
 
 void DefNewGeneration::handle_promotion_failure(oop old) {
--- a/hotspot/src/share/vm/gc/shared/cardTableModRefBS.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/gc/shared/cardTableModRefBS.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -93,7 +93,7 @@
 
   MemTracker::record_virtual_memory_type((address)heap_rs.base(), mtGC);
 
-  os::trace_page_sizes("card table", _guard_index + 1, _guard_index + 1,
+  os::trace_page_sizes("Card Table", _guard_index + 1, _guard_index + 1,
                        _page_size, heap_rs.base(), heap_rs.size());
   if (!heap_rs.is_reserved()) {
     vm_exit_during_initialization("Could not reserve enough space for the "
--- a/hotspot/src/share/vm/gc/shared/genCollectedHeap.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/gc/shared/genCollectedHeap.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -167,6 +167,14 @@
          SIZE_FORMAT, total_reserved, alignment);
 
   *heap_rs = Universe::reserve_heap(total_reserved, alignment);
+
+  os::trace_page_sizes("Heap",
+                       collector_policy()->min_heap_byte_size(),
+                       total_reserved,
+                       alignment,
+                       heap_rs->base(),
+                       heap_rs->size());
+
   return heap_rs->base();
 }
 
--- a/hotspot/src/share/vm/gc/shared/preservedMarks.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/gc/shared/preservedMarks.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -24,24 +24,30 @@
 
 #include "precompiled.hpp"
 #include "gc/shared/preservedMarks.inline.hpp"
+#include "gc/shared/workgroup.hpp"
 #include "memory/allocation.inline.hpp"
-#include "oops/oop.inline.hpp"
 
 void PreservedMarks::restore() {
-  // First, iterate over the stack and restore all marks.
-  StackIterator<OopAndMarkOop, mtGC> iter(_stack);
-  while (!iter.is_empty()) {
-    OopAndMarkOop elem = iter.next();
+  while (!_stack.is_empty()) {
+    const OopAndMarkOop elem = _stack.pop();
     elem.set_mark();
   }
+  assert_empty();
+}
 
-  // Second, reclaim all the stack memory
-  _stack.clear(true /* clear_cache */);
+#ifndef PRODUCT
+void PreservedMarks::assert_empty() {
+  assert(_stack.is_empty(), "stack expected to be empty, size = "SIZE_FORMAT,
+         _stack.size());
+  assert(_stack.cache_size() == 0,
+         "stack expected to have no cached segments, cache size = "SIZE_FORMAT,
+         _stack.cache_size());
 }
+#endif // ndef PRODUCT
 
 void RemoveForwardedPointerClosure::do_object(oop obj) {
   if (obj->is_forwarded()) {
-    obj->init_mark();
+    PreservedMarks::init_forwarded_mark(obj);
   }
 }
 
@@ -61,15 +67,48 @@
   assert_empty();
 }
 
+class ParRestoreTask : public AbstractGangTask {
+private:
+  PreservedMarksSet* const _preserved_marks_set;
+  SequentialSubTasksDone _sub_tasks;
+  volatile size_t* const _total_size_addr;
+
+public:
+  virtual void work(uint worker_id) {
+    uint task_id = 0;
+    while (!_sub_tasks.is_task_claimed(/* reference */ task_id)) {
+      PreservedMarks* const preserved_marks = _preserved_marks_set->get(task_id);
+      const size_t size = preserved_marks->size();
+      preserved_marks->restore();
+      // Only do the atomic add if the size is > 0.
+      if (size > 0) {
+        Atomic::add(size, _total_size_addr);
+      }
+    }
+    _sub_tasks.all_tasks_completed();
+  }
+
+  ParRestoreTask(uint worker_num,
+                 PreservedMarksSet* preserved_marks_set,
+                 volatile size_t* total_size_addr)
+      : AbstractGangTask("Parallel Preserved Mark Restoration"),
+        _preserved_marks_set(preserved_marks_set),
+        _total_size_addr(total_size_addr) {
+    _sub_tasks.set_n_threads(worker_num);
+    _sub_tasks.set_n_tasks(preserved_marks_set->num());
+  }
+};
+
+void PreservedMarksSet::restore_internal(WorkGang* workers,
+                                         volatile size_t* total_size_addr) {
+  assert(workers != NULL, "pre-condition");
+  ParRestoreTask task(workers->active_workers(), this, total_size_addr);
+  workers->run_task(&task);
+}
+
+// temporary, used by PS
 void PreservedMarksSet::restore() {
-  size_t total_size = 0;
-  for (uint i = 0; i < _num; i += 1) {
-    total_size += get(i)->size();
-    get(i)->restore();
-  }
-  assert_empty();
-
-  log_trace(gc)("Restored " SIZE_FORMAT " marks", total_size);
+  restore<WorkGang>(NULL);
 }
 
 void PreservedMarksSet::reclaim() {
@@ -92,7 +131,7 @@
 void PreservedMarksSet::assert_empty() {
   assert(_stacks != NULL && _num > 0, "should have been initialized");
   for (uint i = 0; i < _num; i += 1) {
-    assert(get(i)->is_empty(), "stack should be empty");
+    get(i)->assert_empty();
   }
 }
 #endif // ndef PRODUCT
--- a/hotspot/src/share/vm/gc/shared/preservedMarks.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/gc/shared/preservedMarks.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -44,6 +44,8 @@
 };
 typedef Stack<OopAndMarkOop, mtGC> OopAndMarkOopStack;
 
+class WorkGang;
+
 class PreservedMarks VALUE_OBJ_CLASS_SPEC {
 private:
   OopAndMarkOopStack _stack;
@@ -52,13 +54,19 @@
   inline void push(oop obj, markOop m);
 
 public:
-  bool is_empty() const { return _stack.is_empty(); }
   size_t size() const { return _stack.size(); }
   inline void push_if_necessary(oop obj, markOop m);
-  // Iterate over the stack, restore the preserved marks, then reclaim
-  // the memory taken up by stack chunks.
+  // Iterate over the stack, restore all preserved marks, and
+  // reclaim the memory taken up by the stack segments.
   void restore();
-  ~PreservedMarks() { assert(is_empty(), "should have been cleared"); }
+
+  inline static void init_forwarded_mark(oop obj);
+
+  // Assert the stack is empty and has no cached segments.
+  void assert_empty() PRODUCT_RETURN;
+
+  inline PreservedMarks();
+  ~PreservedMarks() { assert_empty(); }
 };
 
 class RemoveForwardedPointerClosure: public ObjectClosure {
@@ -82,7 +90,12 @@
   // or == NULL if they have not.
   Padded<PreservedMarks>* _stacks;
 
+  // Internal version of restore() that uses a WorkGang for parallelism.
+  void restore_internal(WorkGang* workers, volatile size_t* total_size_addr);
+
 public:
+  uint num() const { return _num; }
+
   // Return the i'th stack.
   PreservedMarks* get(uint i = 0) const {
     assert(_num > 0 && _stacks != NULL, "stacks should have been initialized");
@@ -92,13 +105,23 @@
 
   // Allocate stack array.
   void init(uint num);
-  // Iterate over all stacks, restore all preserved marks, then
-  // reclaim the memory taken up by stack chunks.
+
+  // Itrerate over all stacks, restore all presered marks, and reclaim
+  // the memory taken up by the stack segments. If the executor is
+  // NULL, restoration will be done serially. If the executor is not
+  // NULL, restoration could be done in parallel (when it makes
+  // sense). Supported executors: WorkGang (Serial, CMS, G1)
+  template <class E>
+  inline void restore(E* executor);
+
+  // Do the restoration serially. Temporary, to be used by PS until we
+  // can support GCTaskManager in restore(E*).
   void restore();
+
   // Reclaim stack array.
   void reclaim();
 
-  // Assert all the stacks are empty.
+  // Assert all the stacks are empty and have no cached segments.
   void assert_empty() PRODUCT_RETURN;
 
   PreservedMarksSet(bool in_c_heap)
--- a/hotspot/src/share/vm/gc/shared/preservedMarks.inline.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/gc/shared/preservedMarks.inline.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -22,13 +22,13 @@
  *
  */
 
-#include "gc/shared/preservedMarks.hpp"
-#include "oops/markOop.inline.hpp"
-#include "utilities/stack.inline.hpp"
-
 #ifndef SHARE_VM_GC_SHARED_PRESERVEDMARKS_INLINE_HPP
 #define SHARE_VM_GC_SHARED_PRESERVEDMARKS_INLINE_HPP
 
+#include "gc/shared/preservedMarks.hpp"
+#include "oops/oop.inline.hpp"
+#include "utilities/stack.inline.hpp"
+
 inline bool PreservedMarks::should_preserve_mark(oop obj, markOop m) const {
   return m->must_be_preserved_for_promotion_failure(obj);
 }
@@ -45,4 +45,48 @@
   }
 }
 
+inline void PreservedMarks::init_forwarded_mark(oop obj) {
+  obj->init_mark();
+}
+
+template <class E>
+inline void PreservedMarksSet::restore(E* executor) {
+  volatile size_t total_size = 0;
+
+#ifdef ASSERT
+  // This is to make sure the total_size we'll calculate below is correct.
+  size_t total_size_before = 0;
+  for (uint i = 0; i < _num; i += 1) {
+    total_size_before += get(i)->size();
+  }
+#endif // def ASSERT
+
+  if (executor == NULL) {
+    for (uint i = 0; i < _num; i += 1) {
+      total_size += get(i)->size();
+      get(i)->restore();
+    }
+  } else {
+    // Right now, if the executor is not NULL we do the work in
+    // parallel. In the future we might want to do the restoration
+    // serially, if there's only a small number of marks per stack.
+    restore_internal(executor, &total_size);
+  }
+  assert_empty();
+
+  assert(total_size == total_size_before,
+         "total_size = " SIZE_FORMAT " before = " SIZE_FORMAT,
+         total_size, total_size_before);
+
+  log_trace(gc)("Restored " SIZE_FORMAT " marks", total_size);
+}
+
+inline PreservedMarks::PreservedMarks()
+    : _stack(OopAndMarkOopStack::default_segment_size(),
+             // This stack should be used very infrequently so there's
+             // no point in caching stack segments (there will be a
+             // waste of space most of the time). So we set the max
+             // cache size to 0.
+             0 /* max_cache_size */) { }
+
 #endif // SHARE_VM_GC_SHARED_PRESERVEDMARKS_INLINE_HPP
--- a/hotspot/src/share/vm/gc/shared/referenceProcessor.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/gc/shared/referenceProcessor.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -1090,6 +1090,15 @@
   return true;
 }
 
+bool ReferenceProcessor::has_discovered_references() {
+  for (uint i = 0; i < _max_num_q * number_of_subclasses_of_ref(); i++) {
+    if (!_discovered_refs[i].is_empty()) {
+      return true;
+    }
+  }
+  return false;
+}
+
 // Preclean the discovered references by removing those
 // whose referents are alive, and by marking from those that
 // are not active. These lists can be handled here
--- a/hotspot/src/share/vm/gc/shared/referenceProcessor.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/gc/shared/referenceProcessor.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -412,6 +412,9 @@
   // Discover a Reference object, using appropriate discovery criteria
   bool discover_reference(oop obj, ReferenceType rt);
 
+  // Has discovered references that need handling
+  bool has_discovered_references();
+
   // Process references found during GC (called by the garbage collector)
   ReferenceProcessorStats
   process_discovered_references(BoolObjectClosure*           is_alive,
--- a/hotspot/src/share/vm/gc/shared/space.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/gc/shared/space.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -411,22 +411,6 @@
   return compact_top;
 }
 
-
-bool CompactibleSpace::insert_deadspace(size_t& allowed_deadspace_words,
-                                        HeapWord* q, size_t deadlength) {
-  if (allowed_deadspace_words >= deadlength) {
-    allowed_deadspace_words -= deadlength;
-    CollectedHeap::fill_with_object(q, deadlength);
-    oop(q)->set_mark(oop(q)->mark()->set_marked());
-    assert((int) deadlength == oop(q)->size(), "bad filler object size");
-    // Recall that we required "q == compaction_top".
-    return true;
-  } else {
-    allowed_deadspace_words = 0;
-    return false;
-  }
-}
-
 void ContiguousSpace::prepare_for_compaction(CompactPoint* cp) {
   scan_and_forward(this, cp);
 }
--- a/hotspot/src/share/vm/gc/shared/space.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/gc/shared/space.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -362,6 +362,12 @@
 
   inline size_t obj_size(const HeapWord* addr) const;
 
+  template <class SpaceType>
+  static inline void verify_up_to_first_dead(SpaceType* space) NOT_DEBUG_RETURN;
+
+  template <class SpaceType>
+  static inline void clear_empty_region(SpaceType* space);
+
 public:
   CompactibleSpace() :
    _compaction_top(NULL), _next_compaction_space(NULL) {}
@@ -455,16 +461,6 @@
     return end();
   }
 
-  // Requires "allowed_deadspace_words > 0", that "q" is the start of a
-  // free block of the given "word_len", and that "q", were it an object,
-  // would not move if forwarded.  If the size allows, fill the free
-  // block with an object, to prevent excessive compaction.  Returns "true"
-  // iff the free region was made deadspace, and modifies
-  // "allowed_deadspace_words" to reflect the number of available deadspace
-  // words remaining after this operation.
-  bool insert_deadspace(size_t& allowed_deadspace_words, HeapWord* q,
-                        size_t word_len);
-
   // Below are template functions for scan_and_* algorithms (avoiding virtual calls).
   // The space argument should be a subclass of CompactibleSpace, implementing
   // scan_limit(), scanned_block_is_obj(), and scanned_block_size(),
--- a/hotspot/src/share/vm/gc/shared/space.inline.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/gc/shared/space.inline.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -31,6 +31,7 @@
 #include "gc/shared/space.hpp"
 #include "gc/shared/spaceDecorator.hpp"
 #include "memory/universe.hpp"
+#include "oops/oopsHierarchy.hpp"
 #include "runtime/prefetch.inline.hpp"
 #include "runtime/safepoint.hpp"
 
@@ -75,11 +76,61 @@
   return oop(addr)->size();
 }
 
+class DeadSpacer : StackObj {
+  size_t _allowed_deadspace_words;
+  bool _active;
+  CompactibleSpace* _space;
+
+public:
+  DeadSpacer(CompactibleSpace* space) : _space(space), _allowed_deadspace_words(0) {
+    size_t ratio = _space->allowed_dead_ratio();
+    _active = ratio > 0;
+
+    if (_active) {
+      assert(!UseG1GC, "G1 should not be using dead space");
+
+      // We allow some amount of garbage towards the bottom of the space, so
+      // we don't start compacting before there is a significant gain to be made.
+      // Occasionally, we want to ensure a full compaction, which is determined
+      // by the MarkSweepAlwaysCompactCount parameter.
+      if ((MarkSweep::total_invocations() % MarkSweepAlwaysCompactCount) != 0) {
+        _allowed_deadspace_words = (space->capacity() * ratio / 100) / HeapWordSize;
+      } else {
+        _active = false;
+      }
+    }
+  }
+
+
+  bool insert_deadspace(HeapWord* dead_start, HeapWord* dead_end) {
+    if (!_active) {
+      return false;
+    }
+
+    size_t dead_length = pointer_delta(dead_end, dead_start);
+    if (_allowed_deadspace_words >= dead_length) {
+      _allowed_deadspace_words -= dead_length;
+      CollectedHeap::fill_with_object(dead_start, dead_length);
+      oop obj = oop(dead_start);
+      obj->set_mark(obj->mark()->set_marked());
+
+      assert(dead_length == (size_t)obj->size(), "bad filler object size");
+      log_develop_trace(gc, compaction)("Inserting object to dead space: " PTR_FORMAT ", " PTR_FORMAT ", " SIZE_FORMAT "b",
+          p2i(dead_start), p2i(dead_end), dead_length * HeapWordSize);
+
+      return true;
+    } else {
+      _active = false;
+      return false;
+    }
+  }
+
+};
+
 template <class SpaceType>
 inline void CompactibleSpace::scan_and_forward(SpaceType* space, CompactPoint* cp) {
   // Compute the new addresses for the live objects and store it in the mark
   // Used by universe::mark_sweep_phase2()
-  HeapWord* compact_top; // This is where we are currently compacting to.
 
   // We're sure to be here before any objects are compacted into this
   // space, so this is a good time to initialize this:
@@ -90,89 +141,73 @@
     assert(cp->threshold == NULL, "just checking");
     assert(cp->gen->first_compaction_space() == space, "just checking");
     cp->space = cp->gen->first_compaction_space();
-    compact_top = cp->space->bottom();
-    cp->space->set_compaction_top(compact_top);
     cp->threshold = cp->space->initialize_threshold();
-  } else {
-    compact_top = cp->space->compaction_top();
+    cp->space->set_compaction_top(cp->space->bottom());
   }
 
-  // We allow some amount of garbage towards the bottom of the space, so
-  // we don't start compacting before there is a significant gain to be made.
-  // Occasionally, we want to ensure a full compaction, which is determined
-  // by the MarkSweepAlwaysCompactCount parameter.
-  uint invocations = MarkSweep::total_invocations();
-  bool skip_dead = ((invocations % MarkSweepAlwaysCompactCount) != 0);
+  HeapWord* compact_top = cp->space->compaction_top(); // This is where we are currently compacting to.
 
-  size_t allowed_deadspace = 0;
-  if (skip_dead) {
-    const size_t ratio = space->allowed_dead_ratio();
-    allowed_deadspace = (space->capacity() * ratio / 100) / HeapWordSize;
-  }
+  DeadSpacer dead_spacer(space);
 
-  HeapWord* q = space->bottom();
-  HeapWord* t = space->scan_limit();
-
-  HeapWord*  end_of_live= q;            // One byte beyond the last byte of the last
-                                        // live object.
-  HeapWord*  first_dead = space->end(); // The first dead object.
+  HeapWord*  end_of_live = space->bottom();  // One byte beyond the last byte of the last live object.
+  HeapWord*  first_dead = NULL; // The first dead object.
 
   const intx interval = PrefetchScanIntervalInBytes;
 
-  while (q < t) {
-    assert(!space->scanned_block_is_obj(q) ||
-           oop(q)->mark()->is_marked() || oop(q)->mark()->is_unlocked() ||
-           oop(q)->mark()->has_bias_pattern(),
+  HeapWord* cur_obj = space->bottom();
+  HeapWord* scan_limit = space->scan_limit();
+
+  while (cur_obj < scan_limit) {
+    assert(!space->scanned_block_is_obj(cur_obj) ||
+           oop(cur_obj)->mark()->is_marked() || oop(cur_obj)->mark()->is_unlocked() ||
+           oop(cur_obj)->mark()->has_bias_pattern(),
            "these are the only valid states during a mark sweep");
-    if (space->scanned_block_is_obj(q) && oop(q)->is_gc_marked()) {
-      // prefetch beyond q
-      Prefetch::write(q, interval);
-      size_t size = space->scanned_block_size(q);
-      compact_top = cp->space->forward(oop(q), size, cp, compact_top);
-      q += size;
-      end_of_live = q;
+    if (space->scanned_block_is_obj(cur_obj) && oop(cur_obj)->is_gc_marked()) {
+      // prefetch beyond cur_obj
+      Prefetch::write(cur_obj, interval);
+      size_t size = space->scanned_block_size(cur_obj);
+      compact_top = cp->space->forward(oop(cur_obj), size, cp, compact_top);
+      cur_obj += size;
+      end_of_live = cur_obj;
     } else {
       // run over all the contiguous dead objects
-      HeapWord* end = q;
+      HeapWord* end = cur_obj;
       do {
         // prefetch beyond end
         Prefetch::write(end, interval);
         end += space->scanned_block_size(end);
-      } while (end < t && (!space->scanned_block_is_obj(end) || !oop(end)->is_gc_marked()));
+      } while (end < scan_limit && (!space->scanned_block_is_obj(end) || !oop(end)->is_gc_marked()));
 
       // see if we might want to pretend this object is alive so that
       // we don't have to compact quite as often.
-      if (allowed_deadspace > 0 && q == compact_top) {
-        size_t sz = pointer_delta(end, q);
-        if (space->insert_deadspace(allowed_deadspace, q, sz)) {
-          compact_top = cp->space->forward(oop(q), sz, cp, compact_top);
-          q = end;
-          end_of_live = end;
-          continue;
+      if (cur_obj == compact_top && dead_spacer.insert_deadspace(cur_obj, end)) {
+        oop obj = oop(cur_obj);
+        compact_top = cp->space->forward(obj, obj->size(), cp, compact_top);
+        end_of_live = end;
+      } else {
+        // otherwise, it really is a free region.
+
+        // cur_obj is a pointer to a dead object. Use this dead memory to store a pointer to the next live object.
+        *(HeapWord**)cur_obj = end;
+
+        // see if this is the first dead region.
+        if (first_dead == NULL) {
+          first_dead = cur_obj;
         }
       }
 
-      // otherwise, it really is a free region.
-
-      // q is a pointer to a dead object. Use this dead memory to store a pointer to the next live object.
-      (*(HeapWord**)q) = end;
-
-      // see if this is the first dead region.
-      if (q < first_dead) {
-        first_dead = q;
-      }
-
       // move on to the next object
-      q = end;
+      cur_obj = end;
     }
   }
 
-  assert(q == t, "just checking");
+  assert(cur_obj == scan_limit, "just checking");
   space->_end_of_live = end_of_live;
-  if (end_of_live < first_dead) {
-    first_dead = end_of_live;
+  if (first_dead != NULL) {
+    space->_first_dead = first_dead;
+  } else {
+    space->_first_dead = end_of_live;
   }
-  space->_first_dead = first_dead;
 
   // save the compaction_top of the compaction space.
   cp->space->set_compaction_top(compact_top);
@@ -183,127 +218,58 @@
   // adjust all the interior pointers to point at the new locations of objects
   // Used by MarkSweep::mark_sweep_phase3()
 
-  HeapWord* q = space->bottom();
-  HeapWord* t = space->_end_of_live;  // Established by "prepare_for_compaction".
-
-  assert(space->_first_dead <= space->_end_of_live, "Stands to reason, no?");
-
-  if (q < t && space->_first_dead > q && !oop(q)->is_gc_marked()) {
-    // we have a chunk of the space which hasn't moved and we've
-    // reinitialized the mark word during the previous pass, so we can't
-    // use is_gc_marked for the traversal.
-    HeapWord* end = space->_first_dead;
+  HeapWord* cur_obj = space->bottom();
+  HeapWord* const end_of_live = space->_end_of_live;  // Established by "scan_and_forward".
+  HeapWord* const first_dead = space->_first_dead;    // Established by "scan_and_forward".
 
-    while (q < end) {
-      // I originally tried to conjoin "block_start(q) == q" to the
-      // assertion below, but that doesn't work, because you can't
-      // accurately traverse previous objects to get to the current one
-      // after their pointers have been
-      // updated, until the actual compaction is done.  dld, 4/00
-      assert(space->block_is_obj(q), "should be at block boundaries, and should be looking at objs");
-
-      // point all the oops to the new location
-      size_t size = MarkSweep::adjust_pointers(oop(q));
-      size = space->adjust_obj_size(size);
-
-      q += size;
-    }
-
-    if (space->_first_dead == t) {
-      q = t;
-    } else {
-      // The first dead object is no longer an object. At that memory address,
-      // there is a pointer to the first live object that the previous phase found.
-      q = *((HeapWord**)(space->_first_dead));
-    }
-  }
+  assert(first_dead <= end_of_live, "Stands to reason, no?");
 
   const intx interval = PrefetchScanIntervalInBytes;
 
-  debug_only(HeapWord* prev_q = NULL);
-  while (q < t) {
-    // prefetch beyond q
-    Prefetch::write(q, interval);
-    if (oop(q)->is_gc_marked()) {
-      // q is alive
+  debug_only(HeapWord* prev_obj = NULL);
+  while (cur_obj < end_of_live) {
+    Prefetch::write(cur_obj, interval);
+    if (cur_obj < first_dead || oop(cur_obj)->is_gc_marked()) {
+      // cur_obj is alive
       // point all the oops to the new location
-      size_t size = MarkSweep::adjust_pointers(oop(q));
+      size_t size = MarkSweep::adjust_pointers(oop(cur_obj));
       size = space->adjust_obj_size(size);
-      debug_only(prev_q = q);
-      q += size;
+      debug_only(prev_obj = cur_obj);
+      cur_obj += size;
     } else {
-      debug_only(prev_q = q);
-      // q is not a live object, instead it points at the next live object
-      q = *(HeapWord**)q;
-      assert(q > prev_q, "we should be moving forward through memory, q: " PTR_FORMAT ", prev_q: " PTR_FORMAT, p2i(q), p2i(prev_q));
+      debug_only(prev_obj = cur_obj);
+      // cur_obj is not a live object, instead it points at the next live object
+      cur_obj = *(HeapWord**)cur_obj;
+      assert(cur_obj > prev_obj, "we should be moving forward through memory, cur_obj: " PTR_FORMAT ", prev_obj: " PTR_FORMAT, p2i(cur_obj), p2i(prev_obj));
     }
   }
 
-  assert(q == t, "just checking");
+  assert(cur_obj == end_of_live, "just checking");
 }
 
+#ifdef ASSERT
+template <class SpaceType>
+inline void CompactibleSpace::verify_up_to_first_dead(SpaceType* space) {
+  HeapWord* cur_obj = space->bottom();
+
+  if (cur_obj < space->_end_of_live && space->_first_dead > cur_obj && !oop(cur_obj)->is_gc_marked()) {
+     // we have a chunk of the space which hasn't moved and we've reinitialized
+     // the mark word during the previous pass, so we can't use is_gc_marked for
+     // the traversal.
+     HeapWord* prev_obj = NULL;
+
+     while (cur_obj < space->_first_dead) {
+       size_t size = space->obj_size(cur_obj);
+       assert(!oop(cur_obj)->is_gc_marked(), "should be unmarked (special dense prefix handling)");
+       prev_obj = cur_obj;
+       cur_obj += size;
+     }
+  }
+}
+#endif
+
 template <class SpaceType>
-inline void CompactibleSpace::scan_and_compact(SpaceType* space) {
-  // Copy all live objects to their new location
-  // Used by MarkSweep::mark_sweep_phase4()
-
-  HeapWord*       q = space->bottom();
-  HeapWord* const t = space->_end_of_live;
-  debug_only(HeapWord* prev_q = NULL);
-
-  if (q < t && space->_first_dead > q && !oop(q)->is_gc_marked()) {
-    #ifdef ASSERT // Debug only
-      // we have a chunk of the space which hasn't moved and we've reinitialized
-      // the mark word during the previous pass, so we can't use is_gc_marked for
-      // the traversal.
-      HeapWord* const end = space->_first_dead;
-
-      while (q < end) {
-        size_t size = space->obj_size(q);
-        assert(!oop(q)->is_gc_marked(), "should be unmarked (special dense prefix handling)");
-        prev_q = q;
-        q += size;
-      }
-    #endif
-
-    if (space->_first_dead == t) {
-      q = t;
-    } else {
-      // $$$ Funky
-      q = (HeapWord*) oop(space->_first_dead)->mark()->decode_pointer();
-    }
-  }
-
-  const intx scan_interval = PrefetchScanIntervalInBytes;
-  const intx copy_interval = PrefetchCopyIntervalInBytes;
-  while (q < t) {
-    if (!oop(q)->is_gc_marked()) {
-      // mark is pointer to next marked oop
-      debug_only(prev_q = q);
-      q = (HeapWord*) oop(q)->mark()->decode_pointer();
-      assert(q > prev_q, "we should be moving forward through memory");
-    } else {
-      // prefetch beyond q
-      Prefetch::read(q, scan_interval);
-
-      // size and destination
-      size_t size = space->obj_size(q);
-      HeapWord* compaction_top = (HeapWord*)oop(q)->forwardee();
-
-      // prefetch beyond compaction_top
-      Prefetch::write(compaction_top, copy_interval);
-
-      // copy object and reinit its mark
-      assert(q != compaction_top, "everything in this pass should be moving");
-      Copy::aligned_conjoint_words(q, compaction_top, size);
-      oop(compaction_top)->init_mark();
-      assert(oop(compaction_top)->klass() != NULL, "should have a class");
-
-      debug_only(prev_q = q);
-      q += size;
-    }
-  }
-
+inline void CompactibleSpace::clear_empty_region(SpaceType* space) {
   // Let's remember if we were empty before we did the compaction.
   bool was_empty = space->used_region().is_empty();
   // Reset space after compaction is complete
@@ -320,6 +286,65 @@
   }
 }
 
+template <class SpaceType>
+inline void CompactibleSpace::scan_and_compact(SpaceType* space) {
+  // Copy all live objects to their new location
+  // Used by MarkSweep::mark_sweep_phase4()
+
+  verify_up_to_first_dead(space);
+
+  HeapWord* const end_of_live = space->_end_of_live;
+
+  assert(space->_first_dead <= end_of_live, "Invariant. _first_dead: " PTR_FORMAT " <= end_of_live: " PTR_FORMAT, p2i(space->_first_dead), p2i(end_of_live));
+  if (space->_first_dead == end_of_live && !oop(space->bottom())->is_gc_marked()) {
+    // Nothing to compact. The space is either empty or all live object should be left in place.
+    clear_empty_region(space);
+    return;
+  }
+
+  const intx scan_interval = PrefetchScanIntervalInBytes;
+  const intx copy_interval = PrefetchCopyIntervalInBytes;
+
+  assert(space->bottom() < end_of_live, "bottom: " PTR_FORMAT " should be < end_of_live: " PTR_FORMAT, p2i(space->bottom()), p2i(end_of_live));
+  HeapWord* cur_obj = space->bottom();
+  if (space->_first_dead > cur_obj && !oop(cur_obj)->is_gc_marked()) {
+    // All object before _first_dead can be skipped. They should not be moved.
+    // A pointer to the first live object is stored at the memory location for _first_dead.
+    cur_obj = *(HeapWord**)(space->_first_dead);
+  }
+
+  debug_only(HeapWord* prev_obj = NULL);
+  while (cur_obj < end_of_live) {
+    if (!oop(cur_obj)->is_gc_marked()) {
+      debug_only(prev_obj = cur_obj);
+      // The first word of the dead object contains a pointer to the next live object or end of space.
+      cur_obj = *(HeapWord**)cur_obj;
+      assert(cur_obj > prev_obj, "we should be moving forward through memory");
+    } else {
+      // prefetch beyond q
+      Prefetch::read(cur_obj, scan_interval);
+
+      // size and destination
+      size_t size = space->obj_size(cur_obj);
+      HeapWord* compaction_top = (HeapWord*)oop(cur_obj)->forwardee();
+
+      // prefetch beyond compaction_top
+      Prefetch::write(compaction_top, copy_interval);
+
+      // copy object and reinit its mark
+      assert(cur_obj != compaction_top, "everything in this pass should be moving");
+      Copy::aligned_conjoint_words(cur_obj, compaction_top, size);
+      oop(compaction_top)->init_mark();
+      assert(oop(compaction_top)->klass() != NULL, "should have a class");
+
+      debug_only(prev_obj = cur_obj);
+      cur_obj += size;
+    }
+  }
+
+  clear_empty_region(space);
+}
+
 size_t ContiguousSpace::scanned_block_size(const HeapWord* addr) const {
   return oop(addr)->size();
 }
--- a/hotspot/src/share/vm/interpreter/abstractInterpreter.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/interpreter/abstractInterpreter.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -25,6 +25,7 @@
 #include "precompiled.hpp"
 #include "asm/macroAssembler.hpp"
 #include "asm/macroAssembler.inline.hpp"
+#include "compiler/disassembler.hpp"
 #include "interpreter/bytecodeHistogram.hpp"
 #include "interpreter/bytecodeInterpreter.hpp"
 #include "interpreter/interpreter.hpp"
@@ -32,6 +33,7 @@
 #include "interpreter/interp_masm.hpp"
 #include "interpreter/templateTable.hpp"
 #include "memory/allocation.inline.hpp"
+#include "memory/metaspaceShared.hpp"
 #include "memory/resourceArea.hpp"
 #include "oops/arrayOop.hpp"
 #include "oops/methodData.hpp"
@@ -93,6 +95,7 @@
 address    AbstractInterpreter::_native_entry_end                           = NULL;
 address    AbstractInterpreter::_slow_signature_handler;
 address    AbstractInterpreter::_entry_table            [AbstractInterpreter::number_of_method_entries];
+address    AbstractInterpreter::_cds_entry_table        [AbstractInterpreter::number_of_method_entries];
 address    AbstractInterpreter::_native_abi_to_tosca    [AbstractInterpreter::number_of_result_handlers];
 
 //------------------------------------------------------------------------------------------------------------------------
@@ -204,15 +207,42 @@
   return zerolocals;
 }
 
+#if INCLUDE_CDS
+
+address AbstractInterpreter::get_trampoline_code_buffer(AbstractInterpreter::MethodKind kind) {
+  const size_t trampoline_size = SharedRuntime::trampoline_size();
+  address addr = MetaspaceShared::cds_i2i_entry_code_buffers((size_t)(AbstractInterpreter::number_of_method_entries) * trampoline_size);
+  addr += (size_t)(kind) * trampoline_size;
+
+  return addr;
+}
+
+void AbstractInterpreter::update_cds_entry_table(AbstractInterpreter::MethodKind kind) {
+  if (DumpSharedSpaces || UseSharedSpaces) {
+    address trampoline = get_trampoline_code_buffer(kind);
+    _cds_entry_table[kind] = trampoline;
+
+    CodeBuffer buffer(trampoline, (int)(SharedRuntime::trampoline_size()));
+    MacroAssembler _masm(&buffer);
+    SharedRuntime::generate_trampoline(&_masm, _entry_table[kind]);
+
+    if (PrintInterpreter) {
+      Disassembler::decode(buffer.insts_begin(), buffer.insts_end());
+    }
+  }
+}
+
+#endif
 
 void AbstractInterpreter::set_entry_for_kind(AbstractInterpreter::MethodKind kind, address entry) {
   assert(kind >= method_handle_invoke_FIRST &&
          kind <= method_handle_invoke_LAST, "late initialization only for MH entry points");
   assert(_entry_table[kind] == _entry_table[abstract], "previous value must be AME entry");
   _entry_table[kind] = entry;
+
+  update_cds_entry_table(kind);
 }
 
-
 // Return true if the interpreter can prove that the given bytecode has
 // not yet been executed (in Java semantics, not in actual operation).
 bool AbstractInterpreter::is_not_reached(const methodHandle& method, int bci) {
@@ -416,5 +446,6 @@
   for (int i = method_handle_invoke_FIRST; i <= method_handle_invoke_LAST; i++) {
     MethodKind kind = (MethodKind) i;
     _entry_table[kind] = _entry_table[Interpreter::abstract];
+    Interpreter::update_cds_entry_table(kind);
   }
 }
--- a/hotspot/src/share/vm/interpreter/abstractInterpreter.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/interpreter/abstractInterpreter.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -28,9 +28,8 @@
 #include "asm/macroAssembler.hpp"
 #include "code/stubs.hpp"
 #include "interpreter/bytecodes.hpp"
-#include "runtime/thread.inline.hpp"
+#include "runtime/thread.hpp"
 #include "runtime/vmThread.hpp"
-#include "utilities/top.hpp"
 
 // This file contains the platform-independent parts
 // of the abstract interpreter and the abstract interpreter generator.
@@ -113,6 +112,7 @@
 
   // method entry points
   static address    _entry_table[number_of_method_entries];     // entry points for a given method
+  static address    _cds_entry_table[number_of_method_entries]; // entry points for methods in the CDS archive
   static address    _native_abi_to_tosca[number_of_result_handlers];  // for native method result handlers
   static address    _slow_signature_handler;                              // the native method generic (slow) signature handler
 
@@ -132,6 +132,17 @@
   static address    entry_for_kind(MethodKind k)                { assert(0 <= k && k < number_of_method_entries, "illegal kind"); return _entry_table[k]; }
   static address    entry_for_method(methodHandle m)            { return entry_for_kind(method_kind(m)); }
 
+  static address entry_for_cds_method(methodHandle m) {
+    MethodKind k = method_kind(m);
+    assert(0 <= k && k < number_of_method_entries, "illegal kind");
+    return _cds_entry_table[k];
+  }
+
+  // used by class data sharing
+  static void       update_cds_entry_table(MethodKind kind) NOT_CDS_RETURN;
+
+  static address    get_trampoline_code_buffer(AbstractInterpreter::MethodKind kind) NOT_CDS_RETURN_(0);
+
   // used for bootstrapping method handles:
   static void       set_entry_for_kind(MethodKind k, address e);
 
--- a/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -1767,8 +1767,19 @@
           ((objArrayOop) arrObj)->obj_at_put(index, rhsObject);
           UPDATE_PC_AND_TOS_AND_CONTINUE(1, -3);
       }
-      CASE(_bastore):
-          ARRAY_STOREFROM32(T_BYTE, jbyte,  "%d",   STACK_INT, 0);
+      CASE(_bastore): {
+          ARRAY_INTRO(-3);
+          int item = STACK_INT(-1);
+          // if it is a T_BOOLEAN array, mask the stored value to 0/1
+          if (arrObj->klass() == Universe::boolArrayKlassObj()) {
+            item &= 1;
+          } else {
+            assert(arrObj->klass() == Universe::byteArrayKlassObj(),
+                   "should be byte array otherwise");
+          }
+          ((typeArrayOop)arrObj)->byte_at_put(index, item);
+          UPDATE_PC_AND_TOS_AND_CONTINUE(1, -3);
+      }
       CASE(_castore):
           ARRAY_STOREFROM32(T_CHAR, jchar,  "%d",   STACK_INT, 0);
       CASE(_sastore):
@@ -1999,7 +2010,7 @@
             } else if (tos_type == ltos) {
               SET_STACK_LONG(obj->long_field_acquire(field_offset), 0);
               MORE_STACK(1);
-            } else if (tos_type == btos) {
+            } else if (tos_type == btos || tos_type == ztos) {
               SET_STACK_INT(obj->byte_field_acquire(field_offset), -1);
             } else if (tos_type == ctos) {
               SET_STACK_INT(obj->char_field_acquire(field_offset), -1);
@@ -2020,7 +2031,7 @@
             } else if (tos_type == ltos) {
               SET_STACK_LONG(obj->long_field(field_offset), 0);
               MORE_STACK(1);
-            } else if (tos_type == btos) {
+            } else if (tos_type == btos || tos_type == ztos) {
               SET_STACK_INT(obj->byte_field(field_offset), -1);
             } else if (tos_type == ctos) {
               SET_STACK_INT(obj->char_field(field_offset), -1);
@@ -2109,6 +2120,9 @@
               obj->release_obj_field_put(field_offset, STACK_OBJECT(-1));
             } else if (tos_type == btos) {
               obj->release_byte_field_put(field_offset, STACK_INT(-1));
+            } else if (tos_type == ztos) {
+              int bool_field = STACK_INT(-1);  // only store LSB
+              obj->release_byte_field_put(field_offset, (bool_field & 1));
             } else if (tos_type == ltos) {
               obj->release_long_field_put(field_offset, STACK_LONG(-1));
             } else if (tos_type == ctos) {
@@ -2129,6 +2143,9 @@
               obj->obj_field_put(field_offset, STACK_OBJECT(-1));
             } else if (tos_type == btos) {
               obj->byte_field_put(field_offset, STACK_INT(-1));
+            } else if (tos_type == ztos) {
+              int bool_field = STACK_INT(-1);  // only store LSB
+              obj->byte_field_put(field_offset, (bool_field & 1));
             } else if (tos_type == ltos) {
               obj->long_field_put(field_offset, STACK_LONG(-1));
             } else if (tos_type == ctos) {
--- a/hotspot/src/share/vm/interpreter/bytecodeTracer.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/interpreter/bytecodeTracer.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -26,6 +26,7 @@
 #define SHARE_VM_INTERPRETER_BYTECODETRACER_HPP
 
 #include "memory/allocation.hpp"
+#include "utilities/ostream.hpp"
 
 // The BytecodeTracer is a helper class used by the interpreter for run-time
 // bytecode tracing. If bytecode tracing is turned on, trace() will be called
--- a/hotspot/src/share/vm/interpreter/bytecodes.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/interpreter/bytecodes.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -496,6 +496,7 @@
 
   def(_fast_aputfield      , "fast_aputfield"      , "bJJ"  , NULL    , T_OBJECT ,  0, true , _putfield       );
   def(_fast_bputfield      , "fast_bputfield"      , "bJJ"  , NULL    , T_INT    ,  0, true , _putfield       );
+  def(_fast_zputfield      , "fast_zputfield"      , "bJJ"  , NULL    , T_INT    ,  0, true , _putfield       );
   def(_fast_cputfield      , "fast_cputfield"      , "bJJ"  , NULL    , T_CHAR   ,  0, true , _putfield       );
   def(_fast_dputfield      , "fast_dputfield"      , "bJJ"  , NULL    , T_DOUBLE ,  0, true , _putfield       );
   def(_fast_fputfield      , "fast_fputfield"      , "bJJ"  , NULL    , T_FLOAT  ,  0, true , _putfield       );
--- a/hotspot/src/share/vm/interpreter/bytecodes.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/interpreter/bytecodes.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -26,11 +26,12 @@
 #define SHARE_VM_INTERPRETER_BYTECODES_HPP
 
 #include "memory/allocation.hpp"
-#include "utilities/top.hpp"
 
 // Bytecodes specifies all bytecodes used in the VM and
 // provides utility functions to get bytecode attributes.
 
+class Method;
+
 // NOTE: replicated in SA in vm/agent/sun/jvm/hotspot/interpreter/Bytecodes.java
 class Bytecodes: AllStatic {
  public:
@@ -256,6 +257,7 @@
 
     _fast_aputfield       ,
     _fast_bputfield       ,
+    _fast_zputfield       ,
     _fast_cputfield       ,
     _fast_dputfield       ,
     _fast_fputfield       ,
--- a/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -313,18 +313,7 @@
   THROW_HANDLE(exception);
 IRT_END
 
-IRT_ENTRY(address, InterpreterRuntime::check_ReservedStackAccess_annotated_methods(JavaThread* thread))
-  frame fr = thread->last_frame();
-  assert(fr.is_java_frame(), "Must be a Java frame");
-  frame activation = SharedRuntime::look_for_reserved_stack_annotated_method(thread, fr);
-  if (activation.sp() != NULL) {
-    thread->disable_stack_reserved_zone();
-    thread->set_reserved_stack_activation((address)activation.unextended_sp());
-  }
-  return (address)activation.sp();
-IRT_END
-
- IRT_ENTRY(void, InterpreterRuntime::throw_delayed_StackOverflowError(JavaThread* thread))
+IRT_ENTRY(void, InterpreterRuntime::throw_delayed_StackOverflowError(JavaThread* thread))
   Handle exception = get_preinitialized_exception(
                                  SystemDictionary::StackOverflowError_klass(),
                                  CHECK);
@@ -1088,7 +1077,8 @@
   char sig_type = '\0';
 
   switch(cp_entry->flag_state()) {
-    case btos: sig_type = 'Z'; break;
+    case btos: sig_type = 'B'; break;
+    case ztos: sig_type = 'Z'; break;
     case ctos: sig_type = 'C'; break;
     case stos: sig_type = 'S'; break;
     case itos: sig_type = 'I'; break;
--- a/hotspot/src/share/vm/interpreter/interpreterRuntime.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -31,8 +31,7 @@
 #include "oops/method.hpp"
 #include "runtime/frame.inline.hpp"
 #include "runtime/signature.hpp"
-#include "runtime/thread.inline.hpp"
-#include "utilities/top.hpp"
+#include "runtime/thread.hpp"
 
 // The InterpreterRuntime is called by the interpreter for everything
 // that cannot/should not be dealt with in assembly and needs C support.
@@ -91,8 +90,6 @@
   // Quicken instance-of and check-cast bytecodes
   static void    quicken_io_cc(JavaThread* thread);
 
-  static address check_ReservedStackAccess_annotated_methods(JavaThread* thread);
-
   // Exceptions thrown by the interpreter
   static void    throw_AbstractMethodError(JavaThread* thread);
   static void    throw_IncompatibleClassChangeError(JavaThread* thread);
--- a/hotspot/src/share/vm/interpreter/linkResolver.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/interpreter/linkResolver.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -26,7 +26,6 @@
 #define SHARE_VM_INTERPRETER_LINKRESOLVER_HPP
 
 #include "oops/method.hpp"
-#include "utilities/top.hpp"
 
 // All the necessary definitions for run-time link resolution.
 
--- a/hotspot/src/share/vm/interpreter/templateInterpreter.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/interpreter/templateInterpreter.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -89,8 +89,9 @@
 // Implementation of EntryPoint
 
 EntryPoint::EntryPoint() {
-  assert(number_of_states == 9, "check the code below");
+  assert(number_of_states == 10, "check the code below");
   _entry[btos] = NULL;
+  _entry[ztos] = NULL;
   _entry[ctos] = NULL;
   _entry[stos] = NULL;
   _entry[atos] = NULL;
@@ -102,9 +103,10 @@
 }
 
 
-EntryPoint::EntryPoint(address bentry, address centry, address sentry, address aentry, address ientry, address lentry, address fentry, address dentry, address ventry) {
-  assert(number_of_states == 9, "check the code below");
+EntryPoint::EntryPoint(address bentry, address zentry, address centry, address sentry, address aentry, address ientry, address lentry, address fentry, address dentry, address ventry) {
+  assert(number_of_states == 10, "check the code below");
   _entry[btos] = bentry;
+  _entry[ztos] = zentry;
   _entry[ctos] = centry;
   _entry[stos] = sentry;
   _entry[atos] = aentry;
@@ -155,6 +157,7 @@
   return
     EntryPoint(
       _table[btos][i],
+      _table[ztos][i],
       _table[ctos][i],
       _table[stos][i],
       _table[atos][i],
@@ -169,8 +172,9 @@
 
 void DispatchTable::set_entry(int i, EntryPoint& entry) {
   assert(0 <= i && i < length, "index out of bounds");
-  assert(number_of_states == 9, "check the code below");
+  assert(number_of_states == 10, "check the code below");
   _table[btos][i] = entry.entry(btos);
+  _table[ztos][i] = entry.entry(ztos);
   _table[ctos][i] = entry.entry(ctos);
   _table[stos][i] = entry.entry(stos);
   _table[atos][i] = entry.entry(atos);
--- a/hotspot/src/share/vm/interpreter/templateInterpreter.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/interpreter/templateInterpreter.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -47,7 +47,7 @@
  public:
   // Construction
   EntryPoint();
-  EntryPoint(address bentry, address centry, address sentry, address aentry, address ientry, address lentry, address fentry, address dentry, address ventry);
+  EntryPoint(address bentry, address zentry, address centry, address sentry, address aentry, address ientry, address lentry, address fentry, address dentry, address ventry);
 
   // Attributes
   address entry(TosState state) const;                // return target address for a given tosca state
--- a/hotspot/src/share/vm/interpreter/templateInterpreterGenerator.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/interpreter/templateInterpreterGenerator.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -74,6 +74,7 @@
         Interpreter::_trace_code =
           EntryPoint(
                      generate_trace_code(btos),
+                     generate_trace_code(ztos),
                      generate_trace_code(ctos),
                      generate_trace_code(stos),
                      generate_trace_code(atos),
@@ -94,6 +95,7 @@
                        generate_return_entry_for(itos, i, index_size),
                        generate_return_entry_for(itos, i, index_size),
                        generate_return_entry_for(itos, i, index_size),
+                       generate_return_entry_for(itos, i, index_size),
                        generate_return_entry_for(atos, i, index_size),
                        generate_return_entry_for(itos, i, index_size),
                        generate_return_entry_for(ltos, i, index_size),
@@ -105,13 +107,16 @@
       }
 
       { CodeletMark cm(_masm, "invoke return entry points");
-        const TosState states[] = {itos, itos, itos, itos, ltos, ftos, dtos, atos, vtos};
+        // These states are in order specified in TosState, except btos/ztos/ctos/stos are
+        // really the same as itos since there is no top of stack optimization for these types
+        const TosState states[] = {itos, itos, itos, itos, itos, ltos, ftos, dtos, atos, vtos, ilgl};
         const int invoke_length = Bytecodes::length_for(Bytecodes::_invokestatic);
         const int invokeinterface_length = Bytecodes::length_for(Bytecodes::_invokeinterface);
         const int invokedynamic_length = Bytecodes::length_for(Bytecodes::_invokedynamic);
 
         for (int i = 0; i < Interpreter::number_of_return_addrs; i++) {
           TosState state = states[i];
+          assert(state != ilgl, "states array is wrong above");
           Interpreter::_invoke_return_entry[i] = generate_return_entry_for(state, invoke_length, sizeof(u2));
           Interpreter::_invokeinterface_return_entry[i] = generate_return_entry_for(state, invokeinterface_length, sizeof(u2));
           Interpreter::_invokedynamic_return_entry[i] = generate_return_entry_for(state, invokedynamic_length, sizeof(u4));
@@ -122,6 +127,7 @@
         Interpreter::_earlyret_entry =
           EntryPoint(
                      generate_earlyret_entry_for(btos),
+                     generate_earlyret_entry_for(ztos),
                      generate_earlyret_entry_for(ctos),
                      generate_earlyret_entry_for(stos),
                      generate_earlyret_entry_for(atos),
@@ -140,6 +146,7 @@
                        generate_deopt_entry_for(itos, i),
                        generate_deopt_entry_for(itos, i),
                        generate_deopt_entry_for(itos, i),
+                       generate_deopt_entry_for(itos, i),
                        generate_deopt_entry_for(atos, i),
                        generate_deopt_entry_for(itos, i),
                        generate_deopt_entry_for(ltos, i),
@@ -167,6 +174,7 @@
         Interpreter::_continuation_entry =
           EntryPoint(
                      generate_continuation_for(btos),
+                     generate_continuation_for(ztos),
                      generate_continuation_for(ctos),
                      generate_continuation_for(stos),
                      generate_continuation_for(atos),
@@ -182,6 +190,7 @@
         Interpreter::_safept_entry =
           EntryPoint(
                      generate_safept_entry_for(btos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
+                     generate_safept_entry_for(ztos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
                      generate_safept_entry_for(ctos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
                      generate_safept_entry_for(stos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
                      generate_safept_entry_for(atos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
@@ -212,6 +221,7 @@
 #define method_entry(kind)                                              \
       { CodeletMark cm(_masm, "method entry point (kind = " #kind ")"); \
         Interpreter::_entry_table[Interpreter::kind] = generate_method_entry(Interpreter::kind); \
+        Interpreter::update_cds_entry_table(Interpreter::kind); \
       }
 
       // all non-native method kinds
@@ -300,7 +310,7 @@
 
 void TemplateInterpreterGenerator::set_unimplemented(int i) {
   address e = _unimplemented_bytecode;
-  EntryPoint entry(e, e, e, e, e, e, e, e, e);
+  EntryPoint entry(e, e, e, e, e, e, e, e, e, e);
   Interpreter::_normal_table.set_entry(i, entry);
   Interpreter::_wentry_point[i] = _unimplemented_bytecode;
 }
@@ -315,6 +325,7 @@
   assert(_unimplemented_bytecode    != NULL, "should have been generated before");
   assert(_illegal_bytecode_sequence != NULL, "should have been generated before");
   address bep = _illegal_bytecode_sequence;
+  address zep = _illegal_bytecode_sequence;
   address cep = _illegal_bytecode_sequence;
   address sep = _illegal_bytecode_sequence;
   address aep = _illegal_bytecode_sequence;
@@ -336,7 +347,7 @@
     set_wide_entry_point(t, wep);
   }
   // set entry points
-  EntryPoint entry(bep, cep, sep, aep, iep, lep, fep, dep, vep);
+  EntryPoint entry(bep, zep, cep, sep, aep, iep, lep, fep, dep, vep);
   Interpreter::_normal_table.set_entry(code, entry);
   Interpreter::_wentry_point[code] = wep;
   CodeCacheExtensions::completed_template_interpreter_entries(_masm, code);
@@ -354,6 +365,7 @@
   assert(t->is_valid(), "template must exist");
   switch (t->tos_in()) {
     case btos:
+    case ztos:
     case ctos:
     case stos:
       ShouldNotReachHere();  // btos/ctos/stos should use itos.
--- a/hotspot/src/share/vm/interpreter/templateTable.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/interpreter/templateTable.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -488,6 +488,7 @@
 
   def(Bytecodes::_fast_aputfield      , ubcp|____|____|____, atos, vtos, fast_storefield ,   atos        );
   def(Bytecodes::_fast_bputfield      , ubcp|____|____|____, itos, vtos, fast_storefield ,   itos        );
+  def(Bytecodes::_fast_zputfield      , ubcp|____|____|____, itos, vtos, fast_storefield ,   itos        );
   def(Bytecodes::_fast_cputfield      , ubcp|____|____|____, itos, vtos, fast_storefield  ,  itos        );
   def(Bytecodes::_fast_dputfield      , ubcp|____|____|____, dtos, vtos, fast_storefield  ,  dtos        );
   def(Bytecodes::_fast_fputfield      , ubcp|____|____|____, ftos, vtos, fast_storefield  ,  ftos        );
--- a/hotspot/src/share/vm/logging/log.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/logging/log.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -31,7 +31,10 @@
 #include "gc/shared/gcTraceTime.inline.hpp"
 #include "logging/log.hpp"
 #include "logging/logConfiguration.hpp"
+#include "logging/logFileOutput.hpp"
 #include "logging/logOutput.hpp"
+#include "logging/logTagLevelExpression.hpp"
+#include "logging/logTagSet.hpp"
 #include "logging/logStream.inline.hpp"
 #include "memory/resourceArea.hpp"
 
@@ -44,6 +47,13 @@
 #define assert_char_not_in(c, s) \
   assert(strchr(s, c) == NULL, "Expected '%s' to *not* contain character '%c'", s, c)
 
+void Test_log_tag_combinations_limit() {
+  assert(LogTagLevelExpression::MaxCombinations > LogTagSet::ntagsets(),
+      "Combination limit (" SIZE_FORMAT ") not sufficient "
+      "for configuring all available tag sets (" SIZE_FORMAT ")",
+      LogTagLevelExpression::MaxCombinations, LogTagSet::ntagsets());
+}
+
 class TestLogFile {
  private:
   char file_name[256];
@@ -129,6 +139,131 @@
   assert_str_eq("all=off", stdoutput->config_string());
 }
 
+static size_t number_of_lines_with_substring_in_file(const char* filename,
+                                                     const char* substr) {
+  ResourceMark rm;
+  size_t ret = 0;
+  FILE* fp = fopen(filename, "r");
+  assert(fp != NULL, "error opening file %s: %s", filename, strerror(errno));
+
+  int buflen = 512;
+  char* buf = NEW_RESOURCE_ARRAY(char, buflen);
+  long pos = 0;
+
+  while (fgets(buf, buflen, fp) != NULL) {
+    if (buf[strlen(buf) - 1] != '\n' && !feof(fp)) {
+      // retry with a larger buffer
+      buf = REALLOC_RESOURCE_ARRAY(char, buf, buflen, buflen * 2);
+      buflen *= 2;
+      // rewind to beginning of line
+      fseek(fp, pos, SEEK_SET);
+      continue;
+    }
+    pos = ftell(fp);
+    if (strstr(buf, substr) != NULL) {
+      ret++;
+    }
+  }
+
+  fclose(fp);
+  return ret;
+}
+
+static bool file_exists(const char* filename) {
+  struct stat st;
+  return os::stat(filename, &st) == 0;
+}
+
+static void delete_file(const char* filename) {
+  if (!file_exists(filename)) {
+    return;
+  }
+  int ret = remove(filename);
+  assert(ret == 0, "failed to remove file '%s': %s", filename, strerror(errno));
+}
+
+static void create_directory(const char* name) {
+  assert(!file_exists(name), "can't create directory: %s already exists", name);
+  bool failed;
+#ifdef _WINDOWS
+  failed = !CreateDirectory(name, NULL);
+#else
+  failed = mkdir(name, 0777);
+#endif
+  assert(!failed, "failed to create directory %s", name);
+}
+
+static const char* ExpectedLine = "a (hopefully) unique log line for testing";
+
+static void init_file(const char* filename, const char* options = "") {
+  LogConfiguration::parse_log_arguments(filename, "logging=trace", "", options,
+                                        Log(logging)::error_stream());
+  log_debug(logging)("%s", ExpectedLine);
+  LogConfiguration::parse_log_arguments(filename, "all=off", "", "",
+                                        Log(logging)::error_stream());
+}
+
+void Test_log_file_startup_rotation() {
+  ResourceMark rm;
+  const size_t rotations = 5;
+  const char* filename = "start-rotate-test";
+  char* rotated_file[rotations];
+  for (size_t i = 0; i < rotations; i++) {
+    size_t len = strlen(filename) + 3;
+    rotated_file[i] = NEW_RESOURCE_ARRAY(char, len);
+    jio_snprintf(rotated_file[i], len, "%s." SIZE_FORMAT, filename, i);
+    delete_file(rotated_file[i]);
+  };
+
+  delete_file(filename);
+  init_file(filename);
+  assert(file_exists(filename),
+         "configured logging to file '%s' but file was not found", filename);
+
+  // Initialize the same file a bunch more times to trigger rotations
+  for (size_t i = 0; i < rotations; i++) {
+    init_file(filename);
+    assert(file_exists(rotated_file[i]), "existing file was not rotated");
+  }
+
+  // Remove a file and expect its slot to be re-used
+  delete_file(rotated_file[1]);
+  init_file(filename);
+  assert(file_exists(rotated_file[1]), "log file not properly rotated");
+
+  // Clean up after test
+  delete_file(filename);
+  for (size_t i = 0; i < rotations; i++) {
+    delete_file(rotated_file[i]);
+  }
+}
+
+void Test_log_file_startup_truncation() {
+  ResourceMark rm;
+  const char* filename = "start-truncate-test";
+  const char* archived_filename = "start-truncate-test.0";
+
+  delete_file(filename);
+  delete_file(archived_filename);
+
+  // Use the same log file twice and expect it to be overwritten/truncated
+  init_file(filename, "filecount=0");
+  assert(file_exists(filename), "couldn't find log file: %s", filename);
+
+  init_file(filename, "filecount=0");
+  assert(file_exists(filename), "couldn't find log file: %s", filename);
+  assert(!file_exists(archived_filename),
+         "existing log file %s was not properly truncated when filecount was 0",
+         filename);
+
+  // Verify that the file was really truncated and not just appended
+  assert(number_of_lines_with_substring_in_file(filename, ExpectedLine) == 1,
+         "log file %s appended rather than truncated", filename);
+
+  delete_file(filename);
+  delete_file(archived_filename);
+}
+
 static int Test_logconfiguration_subscribe_triggered = 0;
 
 static void Test_logconfiguration_subscribe_helper() {
@@ -361,11 +496,32 @@
   Test_logstream_helper(stream);
 }
 
+static void Test_logstreamcheap_log() {
+  Log(gc) log;
+  LogStreamCHeap stream(log.debug());
+
+  Test_logstream_helper(&stream);
+}
+
+static void Test_logstreamcheap_logtarget() {
+  LogTarget(Debug, gc) log;
+  LogStreamCHeap stream(log);
+
+  Test_logstream_helper(&stream);
+}
+
 void Test_logstream() {
+  // Test LogStreams with embedded ResourceMark.
   Test_logstream_log();
   Test_logstream_logtarget();
   Test_logstream_logstreamhandle();
+
+  // Test LogStreams without embedded ResourceMark.
   Test_logstream_no_rm();
+
+  // Test LogStreams backed by CHeap memory.
+  Test_logstreamcheap_log();
+  Test_logstreamcheap_logtarget();
 }
 
 void Test_loghandle_on() {
@@ -377,7 +533,7 @@
 
   assert(log_handle.is_debug(), "assert");
 
-  // Try to log trough a LogHandle.
+  // Try to log through a LogHandle.
   log_handle.debug("%d workers", 3);
 
   FILE* fp = fopen(log_file.name(), "r");
@@ -408,7 +564,7 @@
     return;
   }
 
-  // Try to log trough a LogHandle. Should fail, since only info is turned on.
+  // Try to log through a LogHandle. Should fail, since only info is turned on.
   log_handle.debug("%d workers", 3);
 
   // Log a dummy line so that fgets doesn't return NULL because the file is empty.
@@ -440,7 +596,7 @@
 
   assert(log_handle.is_enabled(), "assert");
 
-  // Try to log trough a LogHandle.
+  // Try to log through a LogHandle.
   log_handle.print("%d workers", 3);
 
   FILE* fp = fopen(log_file.name(), "r");
@@ -471,7 +627,7 @@
     return;
   }
 
-  // Try to log trough a LogHandle. Should fail, since only info is turned on.
+  // Try to log through a LogHandle. Should fail, since only info is turned on.
   log_handle.print("%d workers", 3);
 
   // Log a dummy line so that fgets doesn't return NULL because the file is empty.
@@ -711,4 +867,20 @@
   Test_log_gctracetime_no_heap_no_cause();
 }
 
+void Test_invalid_log_file() {
+  ResourceMark rm;
+  stringStream ss;
+  const char* target_name = "tmplogdir";
+
+  // Attempt to log to a directory (existing log not a regular file)
+  create_directory(target_name);
+  LogFileOutput bad_file("tmplogdir");
+  assert(bad_file.initialize("", &ss) == false, "file was initialized "
+         "when there was an existing directory with the same name");
+  assert(strstr(ss.as_string(), "tmplogdir is not a regular file") != NULL,
+         "missing expected error message, received msg: %s", ss.as_string());
+  ss.reset();
+  remove(target_name);
+}
+
 #endif // PRODUCT
--- a/hotspot/src/share/vm/logging/logConfiguration.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/logging/logConfiguration.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -145,7 +145,7 @@
     return NULL;
   }
 
-  bool success = output->initialize(options);
+  bool success = output->initialize(options, errstream);
   if (!success) {
     errstream->print_cr("Initialization of output '%s' using options '%s' failed.", name, options);
     delete output;
--- a/hotspot/src/share/vm/logging/logFileOutput.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/logging/logFileOutput.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -41,8 +41,9 @@
 
 LogFileOutput::LogFileOutput(const char* name)
     : LogFileStreamOutput(NULL), _name(os::strdup_check_oom(name, mtLogging)),
-      _file_name(NULL), _archive_name(NULL), _archive_name_len(0), _current_size(0),
-      _rotate_size(0), _current_file(1), _file_count(0), _rotation_semaphore(1) {
+      _file_name(NULL), _archive_name(NULL), _archive_name_len(0),
+      _rotate_size(DefaultFileSize), _file_count(DefaultFileCount),
+      _current_size(0), _current_file(0), _rotation_semaphore(1) {
   _file_name = make_file_name(name, _pid_str, _vm_start_time_str);
 }
 
@@ -59,9 +60,6 @@
 
 LogFileOutput::~LogFileOutput() {
   if (_stream != NULL) {
-    if (_archive_name != NULL) {
-      archive();
-    }
     if (fclose(_stream) != 0) {
       jio_fprintf(defaultStream::error_stream(), "Could not close log file '%s' (%s).\n",
                   _file_name, os::strerror(errno));
@@ -72,7 +70,7 @@
   os::free(const_cast<char*>(_name));
 }
 
-size_t LogFileOutput::parse_value(const char* value_str) {
+static size_t parse_value(const char* value_str) {
   char* end;
   unsigned long long value = strtoull(value_str, &end, 10);
   if (!isdigit(*value_str) || end != value_str + strlen(value_str) || value >= SIZE_MAX) {
@@ -81,7 +79,80 @@
   return value;
 }
 
-bool LogFileOutput::configure_rotation(const char* options) {
+static bool file_exists(const char* filename) {
+  struct stat dummy_stat;
+  return os::stat(filename, &dummy_stat) == 0;
+}
+
+static uint number_of_digits(uint number) {
+  return number < 10 ? 1 : (number < 100 ? 2 : 3);
+}
+
+static bool is_regular_file(const char* filename) {
+  struct stat st;
+  int ret = os::stat(filename, &st);
+  if (ret != 0) {
+    return false;
+  }
+#ifdef _WINDOWS
+  return (st.st_mode & S_IFMT) == _S_IFREG;
+#else
+  return S_ISREG(st.st_mode);
+#endif
+}
+
+// Try to find the next number that should be used for file rotation.
+// Return UINT_MAX on error.
+static uint next_file_number(const char* filename,
+                             uint number_of_digits,
+                             uint filecount,
+                             outputStream* errstream) {
+  bool found = false;
+  uint next_num = 0;
+
+  // len is filename + dot + digits + null char
+  size_t len = strlen(filename) + number_of_digits + 2;
+  char* archive_name = NEW_C_HEAP_ARRAY(char, len, mtLogging);
+  char* oldest_name = NEW_C_HEAP_ARRAY(char, len, mtLogging);
+
+  for (uint i = 0; i < filecount; i++) {
+    int ret = jio_snprintf(archive_name, len, "%s.%0*u",
+                           filename, number_of_digits, i);
+    assert(ret > 0 && static_cast<size_t>(ret) == len - 1,
+           "incorrect buffer length calculation");
+
+    if (file_exists(archive_name) && !is_regular_file(archive_name)) {
+      // We've encountered something that's not a regular file among the
+      // possible file rotation targets. Fail immediately to prevent
+      // problems later.
+      errstream->print_cr("Possible rotation target file '%s' already exists "
+                          "but is not a regular file.", archive_name);
+      next_num = UINT_MAX;
+      break;
+    }
+
+    // Stop looking if we find an unused file name
+    if (!file_exists(archive_name)) {
+      next_num = i;
+      found = true;
+      break;
+    }
+
+    // Keep track of oldest existing log file
+    if (!found
+        || os::compare_file_modified_times(oldest_name, archive_name) > 0) {
+      strcpy(oldest_name, archive_name);
+      next_num = i;
+      found = true;
+    }
+  }
+
+  FREE_C_HEAP_ARRAY(char, oldest_name);
+  FREE_C_HEAP_ARRAY(char, archive_name);
+  return next_num;
+}
+
+bool LogFileOutput::parse_options(const char* options, outputStream* errstream) {
   if (options == NULL || strlen(options) == 0) {
     return true;
   }
@@ -107,22 +178,25 @@
 
     if (strcmp(FileCountOptionKey, key) == 0) {
       size_t value = parse_value(value_str);
-      if (value == SIZE_MAX || value >= UINT_MAX) {
+      if (value > MaxRotationFileCount) {
+        errstream->print_cr("Invalid option: %s must be in range [0, %u]",
+                            FileCountOptionKey,
+                            MaxRotationFileCount);
         success = false;
         break;
       }
       _file_count = static_cast<uint>(value);
-      _file_count_max_digits = static_cast<uint>(log10(static_cast<double>(_file_count)) + 1);
-      _archive_name_len = 2 + strlen(_file_name) + _file_count_max_digits;
-      _archive_name = NEW_C_HEAP_ARRAY(char, _archive_name_len, mtLogging);
     } else if (strcmp(FileSizeOptionKey, key) == 0) {
       size_t value = parse_value(value_str);
       if (value == SIZE_MAX || value > SIZE_MAX / K) {
+        errstream->print_cr("Invalid option: %s must be in range [0, "
+                            SIZE_FORMAT "]", FileSizeOptionKey, SIZE_MAX / K);
         success = false;
         break;
       }
       _rotate_size = value * K;
     } else {
+      errstream->print_cr("Invalid option '%s' for log file output.", key);
       success = false;
       break;
     }
@@ -133,15 +207,54 @@
   return success;
 }
 
-bool LogFileOutput::initialize(const char* options) {
-  if (!configure_rotation(options)) {
+bool LogFileOutput::initialize(const char* options, outputStream* errstream) {
+  if (!parse_options(options, errstream)) {
     return false;
   }
+
+  if (_file_count > 0) {
+    // compute digits with filecount - 1 since numbers will start from 0
+    _file_count_max_digits = number_of_digits(_file_count - 1);
+    _archive_name_len = 2 + strlen(_file_name) + _file_count_max_digits;
+    _archive_name = NEW_C_HEAP_ARRAY(char, _archive_name_len, mtLogging);
+  }
+
+  log_trace(logging)("Initializing logging to file '%s' (filecount: %u"
+                     ", filesize: " SIZE_FORMAT " KiB).",
+                     _file_name, _file_count, _rotate_size / K);
+
+  if (_file_count > 0 && file_exists(_file_name)) {
+    if (!is_regular_file(_file_name)) {
+      errstream->print_cr("Unable to log to file %s with log file rotation: "
+                          "%s is not a regular file",
+                          _file_name, _file_name);
+      return false;
+    }
+    _current_file = next_file_number(_file_name,
+                                     _file_count_max_digits,
+                                     _file_count,
+                                     errstream);
+    if (_current_file == UINT_MAX) {
+      return false;
+    }
+    log_trace(logging)("Existing log file found, saving it as '%s.%0*u'",
+                       _file_name, _file_count_max_digits, _current_file);
+    archive();
+    increment_file_count();
+  }
+
   _stream = fopen(_file_name, FileOpenMode);
   if (_stream == NULL) {
-    log_error(logging)("Could not open log file '%s' (%s).\n", _file_name, os::strerror(errno));
+    errstream->print_cr("Error opening log file '%s': %s",
+                        _file_name, strerror(errno));
     return false;
   }
+
+  if (_file_count == 0 && is_regular_file(_file_name)) {
+    log_trace(logging)("Truncating log file");
+    os::ftruncate(os::fileno(_stream), 0);
+  }
+
   return true;
 }
 
@@ -210,7 +323,7 @@
 
   // Reset accumulated size, increase current file counter, and check for file count wrap-around.
   _current_size = 0;
-  _current_file = (_current_file >= _file_count ? 1 : _current_file + 1);
+  increment_file_count();
 }
 
 char* LogFileOutput::make_file_name(const char* file_name,
--- a/hotspot/src/share/vm/logging/logFileOutput.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/logging/logFileOutput.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -39,8 +39,11 @@
   static const char*  PidFilenamePlaceholder;
   static const char*  TimestampFilenamePlaceholder;
   static const char*  TimestampFormat;
+  static const size_t DefaultFileCount = 5;
+  static const size_t DefaultFileSize = 20 * M;
   static const size_t StartTimeBufferSize = 20;
-  static const size_t PidBufferSize       = 21;
+  static const size_t PidBufferSize = 21;
+  static const uint   MaxRotationFileCount = 1000;
   static char         _pid_str[PidBufferSize];
   static char         _vm_start_time_str[StartTimeBufferSize];
 
@@ -61,18 +64,24 @@
 
   void archive();
   void rotate();
-  bool configure_rotation(const char* options);
+  bool parse_options(const char* options, outputStream* errstream);
   char *make_file_name(const char* file_name, const char* pid_string, const char* timestamp_string);
-  static size_t parse_value(const char* value_str);
 
   bool should_rotate() {
     return _file_count > 0 && _rotate_size > 0 && _current_size >= _rotate_size;
   }
 
+  void increment_file_count() {
+    _current_file++;
+    if (_current_file == _file_count) {
+      _current_file = 0;
+    }
+  }
+
  public:
   LogFileOutput(const char *name);
   virtual ~LogFileOutput();
-  virtual bool initialize(const char* options);
+  virtual bool initialize(const char* options, outputStream* errstream);
   virtual int write(const LogDecorations& decorations, const char* msg);
   virtual void force_rotate();
 
--- a/hotspot/src/share/vm/logging/logFileStreamOutput.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/logging/logFileStreamOutput.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -53,7 +53,7 @@
   LogStdoutOutput() : LogFileStreamOutput(stdout) {
     set_config_string("all=off");
   }
-  virtual bool initialize(const char* options) {
+  virtual bool initialize(const char* options, outputStream* errstream) {
     return false;
   }
  public:
@@ -69,7 +69,7 @@
   LogStderrOutput() : LogFileStreamOutput(stderr) {
     set_config_string("all=warning");
   }
-  virtual bool initialize(const char* options) {
+  virtual bool initialize(const char* options, outputStream* errstream) {
     return false;
   }
  public:
--- a/hotspot/src/share/vm/logging/logHandle.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/logging/logHandle.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -67,13 +67,13 @@
 // This can be used to pass a Log instance as a parameter without
 // polluting the surrounding API with template functions.
 class LogTargetHandle {
-  friend class LogStream;
-
 private:
   const LogLevelType _level;
   LogTagSet*         _tagset;
 
 public:
+  LogTargetHandle(LogLevelType level, LogTagSet* tagset) : _level(level), _tagset(tagset) {}
+
   template <LogLevelType level, LogTagType T0, LogTagType T1, LogTagType T2, LogTagType T3, LogTagType T4, LogTagType GuardTag>
   LogTargetHandle(const LogTargetImpl<level, T0, T1, T2, T3, T4, GuardTag>& type_carrier) :
       _level(level),
--- a/hotspot/src/share/vm/logging/logOutput.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/logging/logOutput.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -82,7 +82,7 @@
   }
 
   virtual const char* name() const = 0;
-  virtual bool initialize(const char* options) = 0;
+  virtual bool initialize(const char* options, outputStream* errstream) = 0;
   virtual int write(const LogDecorations &decorations, const char* msg) = 0;
 };
 
--- a/hotspot/src/share/vm/logging/logPrefix.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/logging/logPrefix.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -55,6 +55,7 @@
   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, ergo, cset)) \
   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, ergo, heap)) \
   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, ergo, ihop)) \
+  LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, ergo, refine)) \
   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, heap)) \
   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, heap, region)) \
   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, freelist)) \
--- a/hotspot/src/share/vm/logging/logStream.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/logging/logStream.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -24,7 +24,7 @@
 
 #include "precompiled.hpp"
 #include "logging/log.hpp"
-#include "logging/logStream.hpp"
+#include "logging/logStream.inline.hpp"
 
 // Create a log stream without an embedded ResourceMark.
 // The function is placed here to be called out-of-line in log.hpp.
--- a/hotspot/src/share/vm/logging/logStream.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/logging/logStream.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -26,23 +26,100 @@
 #define SHARE_VM_LOGGING_LOGSTREAM_HPP
 
 #include "logging/log.hpp"
+#include "logging/logHandle.hpp"
+#include "memory/resourceArea.hpp"
 #include "utilities/ostream.hpp"
 
-// An output stream that logs to the logging framework.
-// Requires a ResourceMark on the stack.
-class LogStreamNoResourceMark : public outputStream {
-private:
-  stringStream _current_line;
-  LogLevelType _level;
-  LogTagSet*   _tagset;
+// The base class of an output stream that logs to the logging framework.
+template <class streamClass>
+class LogStreamBase : public outputStream {
+  streamClass     _current_line;
+  LogTargetHandle _log_handle;
 
 public:
-  LogStreamNoResourceMark(LogLevelType level, LogTagSet* tagset) : _level(level), _tagset(tagset) {}
-  ~LogStreamNoResourceMark() {
+  // Constructor to support creation from a LogTarget instance.
+  //
+  // LogTarget(Debug, gc) log;
+  // LogStreamBase(log) stream;
+  template <LogLevelType level, LogTagType T0, LogTagType T1, LogTagType T2, LogTagType T3, LogTagType T4, LogTagType GuardTag>
+  LogStreamBase(const LogTargetImpl<level, T0, T1, T2, T3, T4, GuardTag>& type_carrier) :
+      _log_handle(level, &LogTagSetMapping<T0, T1, T2, T3, T4>::tagset()) {}
+
+  // Constructor to support creation from typed (likely NULL) pointer. Mostly used by the logging framework.
+  //
+  // LogStreamBase stream(log.debug());
+  //  or
+  // LogStreamBase stream((LogTargetImpl<level, T0, T1, T2, T3, T4, GuardTag>*)NULL);
+  template <LogLevelType level, LogTagType T0, LogTagType T1, LogTagType T2, LogTagType T3, LogTagType T4, LogTagType GuardTag>
+  LogStreamBase(const LogTargetImpl<level, T0, T1, T2, T3, T4, GuardTag>* type_carrier) :
+      _log_handle(level, &LogTagSetMapping<T0, T1, T2, T3, T4>::tagset()) {}
+
+  // Constructor to support creation from a LogTargetHandle.
+  //
+  // LogTarget(Debug, gc) log;
+  // LogTargetHandle(log) handle;
+  // LogStreamBase stream(handle);
+  LogStreamBase(LogTargetHandle handle) : _log_handle(handle) {}
+
+  // Constructor to support creation from a log level and tagset.
+  //
+  // LogStreamBase(level, tageset);
+  LogStreamBase(LogLevelType level, LogTagSet* tagset) : _log_handle(level, tagset) {}
+
+  ~LogStreamBase() {
     guarantee(_current_line.size() == 0, "Buffer not flushed. Missing call to print_cr()?");
   }
 
+public:
   void write(const char* s, size_t len);
 };
 
+// A stringStream with an embedded ResourceMark.
+class stringStreamWithResourceMark : outputStream {
+ private:
+  // The stringStream Resource allocate in the constructor,
+  // so the order of the fields is important.
+  ResourceMark _embedded_resource_mark;
+  stringStream _stream;
+
+ public:
+  stringStreamWithResourceMark(size_t initial_bufsize = 256) :
+      _embedded_resource_mark(),
+      _stream(initial_bufsize) {}
+
+  virtual void write(const char* c, size_t len) { _stream.write(c, len); }
+  size_t      size()                            { return _stream.size(); }
+  const char* base()                            { return _stream.base(); }
+  void  reset()                                 { _stream.reset(); }
+  char* as_string()                             { return _stream.as_string(); }
+};
+
+// An output stream that logs to the logging framework.
+//
+// The backing buffer is allocated in Resource memory.
+// The caller is required to have a ResourceMark on the stack.
+typedef LogStreamBase<stringStream> LogStreamNoResourceMark;
+
+// An output stream that logs to the logging framework.
+//
+// The backing buffer is allocated in CHeap memory.
+typedef LogStreamBase<bufferedStream> LogStreamCHeap;
+
+// An output stream that logs to the logging framework, and embeds a ResourceMark.
+//
+// The backing buffer is allocated in Resource memory.
+// The class is intended to be stack allocated.
+// The class provides its own ResourceMark,
+//  so care needs to be taken when nested ResourceMarks are used.
+typedef LogStreamBase<stringStreamWithResourceMark> LogStream;
+
+// Support creation of a LogStream without having to provide a LogTarget pointer.
+#define LogStreamHandle(level, ...) LogStreamTemplate<LogLevel::level, LOG_TAGS(__VA_ARGS__)>
+
+template <LogLevelType level, LogTagType T0, LogTagType T1, LogTagType T2, LogTagType T3, LogTagType T4, LogTagType GuardTag>
+class LogStreamTemplate : public LogStream {
+public:
+  LogStreamTemplate() : LogStream((LogTargetImpl<level, T0, T1, T2, T3, T4, GuardTag>*)NULL) {}
+};
+
 #endif // SHARE_VM_LOGGING_LOGSTREAM_HPP
--- a/hotspot/src/share/vm/logging/logStream.inline.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/logging/logStream.inline.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -30,10 +30,12 @@
 #include "memory/resourceArea.hpp"
 #include "utilities/ostream.hpp"
 
-inline void LogStreamNoResourceMark::write(const char* s, size_t len) {
+template <class streamClass>
+inline void LogStreamBase<streamClass>::write(const char* s, size_t len) {
   if (len > 0 && s[len - 1] == '\n') {
     _current_line.write(s, len - 1);
-    _tagset->write(_level, "%s", _current_line.as_string());
+    _current_line.write("\0", 1);
+    _log_handle.print("%s", _current_line.base());
     _current_line.reset();
   } else {
     _current_line.write(s, len);
@@ -41,54 +43,4 @@
   update_position(s, len);
 }
 
-// An output stream that logs to the logging framework, and embeds a ResourceMark.
-//
-//  The class is intended to be stack allocated.
-//  Care needs to be taken when nested ResourceMarks are used.
-class LogStream : public outputStream {
-private:
-  ResourceMark            _embedded_resource_mark;
-  LogStreamNoResourceMark _stream;
-
-public:
-  // Constructor to support creation from a LogTarget instance.
-  //
-  // LogTarget(Debug, gc) log;
-  // LogStream(log) stream;
-  template <LogLevelType level, LogTagType T0, LogTagType T1, LogTagType T2, LogTagType T3, LogTagType T4, LogTagType GuardTag>
-  LogStream(const LogTargetImpl<level, T0, T1, T2, T3, T4, GuardTag>& type_carrier) :
-      _embedded_resource_mark(),
-      _stream(level, &LogTagSetMapping<T0, T1, T2, T3, T4>::tagset()) {}
-
-  // Constructor to support creation from typed (likely NULL) pointer. Mostly used by the logging framework.
-  //
-  // LogStream stream(log.debug());
-  // LogStream stream((LogTargetImpl<level, T0, T1, T2, T3, T4, GuardTag>*)NULL);
-  template <LogLevelType level, LogTagType T0, LogTagType T1, LogTagType T2, LogTagType T3, LogTagType T4, LogTagType GuardTag>
-  LogStream(const LogTargetImpl<level, T0, T1, T2, T3, T4, GuardTag>* type_carrier) :
-      _embedded_resource_mark(),
-      _stream(level, &LogTagSetMapping<T0, T1, T2, T3, T4>::tagset()) {}
-
-  // Constructor to support creation from a LogTargetHandle.
-  //
-  // LogTarget(Debug, gc) log;
-  // LogTargetHandle(log) handle;
-  // LogStream stream(handle);
-  LogStream(LogTargetHandle handle) :
-      _embedded_resource_mark(),
-      _stream(handle._level, handle._tagset) {}
-
-  // Override of outputStream::write.
-  void write(const char* s, size_t len) { _stream.write(s, len); }
-};
-
-// Support creation of a LogStream without having to provide a LogTarget pointer.
-#define LogStreamHandle(level, ...) LogStreamTemplate<LogLevel::level, LOG_TAGS(__VA_ARGS__)>
-
-template <LogLevelType level, LogTagType T0, LogTagType T1, LogTagType T2, LogTagType T3, LogTagType T4, LogTagType GuardTag>
-class LogStreamTemplate : public LogStream {
-public:
-  LogStreamTemplate() : LogStream((LogTargetImpl<level, T0, T1, T2, T3, T4, GuardTag>*)NULL) {}
-};
-
 #endif // SHARE_VM_LOGGING_LOGSTREAM_INLINE_HPP
--- a/hotspot/src/share/vm/logging/logTag.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/logging/logTag.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -48,6 +48,7 @@
   LOG_TAG(classpath) \
   LOG_TAG(compaction) \
   LOG_TAG(constraints) \
+  LOG_TAG(coops) \
   LOG_TAG(cpu) \
   LOG_TAG(cset) \
   LOG_TAG(defaultmethods) \
@@ -69,6 +70,7 @@
   LOG_TAG(monitorinflation) \
   LOG_TAG(monitormismatch) \
   LOG_TAG(os) \
+  LOG_TAG(pagesize) \
   LOG_TAG(phases) \
   LOG_TAG(plab) \
   LOG_TAG(promotion) \
--- a/hotspot/src/share/vm/logging/logTagLevelExpression.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/logging/logTagLevelExpression.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -36,9 +36,12 @@
 // Class used to temporary encode a 'what'-expression during log configuration.
 // Consists of a combination of tags and levels, e.g. "tag1+tag2=level1,tag3*=level2".
 class LogTagLevelExpression : public StackObj {
-  friend void LogConfiguration::configure_stdout(LogLevelType, bool, ...);
+ public:
+  static const size_t MaxCombinations = 256;
+
  private:
-  static const size_t MaxCombinations = 32;
+  friend void LogConfiguration::configure_stdout(LogLevelType, bool, ...);
+
   static const char* DefaultExpressionString;
 
   size_t        _ntags, _ncombinations;
--- a/hotspot/src/share/vm/logging/logTagSet.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/logging/logTagSet.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -98,6 +98,7 @@
 const size_t vwrite_buffer_size = 512;
 
 void LogTagSet::vwrite(LogLevelType level, const char* fmt, va_list args) {
+  assert(level >= LogLevel::First && level <= LogLevel::Last, "Log level:%d is incorrect", level);
   char buf[vwrite_buffer_size];
   va_list saved_args;           // For re-format on buf overflow.
   va_copy(saved_args, args);
--- a/hotspot/src/share/vm/logging/logTagSet.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/logging/logTagSet.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -64,6 +64,10 @@
     return _list;
   }
 
+  static size_t ntagsets() {
+    return _ntagsets;
+  }
+
   LogTagSet* next() {
     return _next;
   }
--- a/hotspot/src/share/vm/memory/allocation.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/memory/allocation.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -143,8 +143,9 @@
   mtTest              = 0x0D,  // Test type for verifying NMT
   mtTracing           = 0x0E,  // memory used for Tracing
   mtLogging           = 0x0F,  // memory for logging
-  mtNone              = 0x10,  // undefined
-  mt_number_of_types  = 0x11   // number of memory types (mtDontTrack
+  mtArguments         = 0x10,  // memory for argument processing
+  mtNone              = 0x11,  // undefined
+  mt_number_of_types  = 0x12   // number of memory types (mtDontTrack
                                  // is not included as validate type)
 };
 
--- a/hotspot/src/share/vm/memory/filemap.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/memory/filemap.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -959,6 +959,16 @@
   return false;
 }
 
+// Check if a given address is within one of the shared regions (ro, rw, md, mc)
+bool FileMapInfo::is_in_shared_region(const void* p, int idx) {
+  assert((idx >= MetaspaceShared::ro) && (idx <= MetaspaceShared::mc), "invalid region index");
+  char* base = _header->region_addr(idx);
+  if (p >= base && p < base + _header->_space[idx]._used) {
+    return true;
+  }
+  return false;
+}
+
 void FileMapInfo::print_shared_spaces() {
   tty->print_cr("Shared Spaces:");
   for (int i = 0; i < MetaspaceShared::n_regions; i++) {
--- a/hotspot/src/share/vm/memory/filemap.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/memory/filemap.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -107,6 +107,8 @@
     int     _narrow_klass_shift;      // save narrow klass base and shift
     address _narrow_klass_base;
     char*   _misc_data_patching_start;
+    address _cds_i2i_entry_code_buffers;
+    size_t  _cds_i2i_entry_code_buffers_size;
 
     struct space_info {
       int    _crc;           // crc checksum of the current space
@@ -195,6 +197,19 @@
   char* misc_data_patching_start()            { return _header->_misc_data_patching_start; }
   void set_misc_data_patching_start(char* p)  { _header->_misc_data_patching_start = p; }
 
+  address cds_i2i_entry_code_buffers() {
+    return _header->_cds_i2i_entry_code_buffers;
+  }
+  void set_cds_i2i_entry_code_buffers(address addr) {
+    _header->_cds_i2i_entry_code_buffers = addr;
+  }
+  size_t cds_i2i_entry_code_buffers_size() {
+    return _header->_cds_i2i_entry_code_buffers_size;
+  }
+  void set_cds_i2i_entry_code_buffers_size(size_t s) {
+    _header->_cds_i2i_entry_code_buffers_size = s;
+  }
+
   static FileMapInfo* current_info() {
     CDS_ONLY(return _current_info;)
     NOT_CDS(return NULL;)
@@ -234,6 +249,7 @@
 
   // Return true if given address is in the mapped shared space.
   bool is_in_shared_space(const void* p) NOT_CDS_RETURN_(false);
+  bool is_in_shared_region(const void* p, int idx) NOT_CDS_RETURN_(false);
   void print_shared_spaces() NOT_CDS_RETURN;
 
   static size_t shared_spaces_size() {
--- a/hotspot/src/share/vm/memory/iterator.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/memory/iterator.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -27,7 +27,7 @@
 
 #include "memory/allocation.hpp"
 #include "memory/memRegion.hpp"
-#include "utilities/top.hpp"
+#include "oops/oopsHierarchy.hpp"
 
 class CodeBlob;
 class nmethod;
@@ -35,6 +35,7 @@
 class DataLayout;
 class KlassClosure;
 class ClassLoaderData;
+class Symbol;
 
 // The following classes are C++ `closures` for iterating over objects, roots and spaces
 
--- a/hotspot/src/share/vm/memory/metaspaceShared.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/memory/metaspaceShared.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -59,6 +59,8 @@
 bool MetaspaceShared::_check_classes_made_progress;
 bool MetaspaceShared::_has_error_classes;
 bool MetaspaceShared::_archive_loading_failed = false;
+address MetaspaceShared::_cds_i2i_entry_code_buffers = NULL;
+size_t MetaspaceShared::_cds_i2i_entry_code_buffers_size = 0;
 SharedMiscRegion MetaspaceShared::_mc;
 SharedMiscRegion MetaspaceShared::_md;
 
@@ -129,6 +131,21 @@
   soc->do_tag(666);
 }
 
+address MetaspaceShared::cds_i2i_entry_code_buffers(size_t total_size) {
+  if (DumpSharedSpaces) {
+    if (_cds_i2i_entry_code_buffers == NULL) {
+      _cds_i2i_entry_code_buffers = (address)misc_data_space_alloc(total_size);
+      _cds_i2i_entry_code_buffers_size = total_size;
+    }
+  } else if (UseSharedSpaces) {
+    assert(_cds_i2i_entry_code_buffers != NULL, "must already been initialized");
+  } else {
+    return NULL;
+  }
+
+  assert(_cds_i2i_entry_code_buffers_size == total_size, "must not change");
+  return _cds_i2i_entry_code_buffers;
+}
 
 // CDS code for dumping shared archive.
 
@@ -576,6 +593,8 @@
                                      &md_top, md_end,
                                      &mc_top, mc_end);
 
+  guarantee(md_top <= md_end, "Insufficient space for vtables.");
+
   // Reorder the system dictionary.  (Moving the symbols affects
   // how the hash table indices are calculated.)
   // Not doing this either.
@@ -668,6 +687,8 @@
   FileMapInfo* mapinfo = new FileMapInfo();
   mapinfo->populate_header(MetaspaceShared::max_alignment());
   mapinfo->set_misc_data_patching_start((char*)vtbl_list);
+  mapinfo->set_cds_i2i_entry_code_buffers(MetaspaceShared::cds_i2i_entry_code_buffers());
+  mapinfo->set_cds_i2i_entry_code_buffers_size(MetaspaceShared::cds_i2i_entry_code_buffers_size());
 
   for (int pass=1; pass<=2; pass++) {
     if (pass == 1) {
@@ -686,7 +707,7 @@
     mapinfo->write_region(MetaspaceShared::md, _md_vs.low(),
                           pointer_delta(md_top, _md_vs.low(), sizeof(char)),
                           SharedMiscDataSize,
-                          false, false);
+                          false, true);
     mapinfo->write_region(MetaspaceShared::mc, _mc_vs.low(),
                           pointer_delta(mc_top, _mc_vs.low(), sizeof(char)),
                           SharedMiscCodeSize,
@@ -980,6 +1001,11 @@
   return UseSharedSpaces && FileMapInfo::current_info()->is_in_shared_space(p);
 }
 
+// Return true if given address is in the misc data region
+bool MetaspaceShared::is_in_shared_region(const void* p, int idx) {
+  return UseSharedSpaces && FileMapInfo::current_info()->is_in_shared_region(p, idx);
+}
+
 bool MetaspaceShared::is_string_region(int idx) {
   return (idx >= MetaspaceShared::first_string &&
           idx < MetaspaceShared::first_string + MetaspaceShared::max_strings);
@@ -1053,6 +1079,8 @@
 
 void MetaspaceShared::initialize_shared_spaces() {
   FileMapInfo *mapinfo = FileMapInfo::current_info();
+  _cds_i2i_entry_code_buffers = mapinfo->cds_i2i_entry_code_buffers();
+  _cds_i2i_entry_code_buffers_size = mapinfo->cds_i2i_entry_code_buffers_size();
   char* buffer = mapinfo->misc_data_patching_start();
 
   // Skip over (reserve space for) a list of addresses of C++ vtables
--- a/hotspot/src/share/vm/memory/metaspaceShared.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/memory/metaspaceShared.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -50,17 +50,14 @@
 #define MIN_SHARED_READ_ONLY_SIZE       (NOT_LP64(8*M) LP64_ONLY(9*M))
 
 // the MIN_SHARED_MISC_DATA_SIZE and MIN_SHARED_MISC_CODE_SIZE estimates are based on
-// MetaspaceShared::generate_vtable_methods().
-// The minimum size only accounts for the vtable methods. Any size less than the
-// minimum required size would cause vm crash when allocating the vtable methods.
-#define SHARED_MISC_SIZE_FOR(size)      (DEFAULT_VTBL_VIRTUALS_COUNT*DEFAULT_VTBL_LIST_SIZE*size)
+// the sizes required for dumping the archive using the default classlist. The sizes
+// are multiplied by 1.5 for a safety margin.
 
 #define DEFAULT_SHARED_MISC_DATA_SIZE   (NOT_LP64(2*M) LP64_ONLY(4*M))
-#define MIN_SHARED_MISC_DATA_SIZE       (SHARED_MISC_SIZE_FOR(sizeof(void*)))
+#define MIN_SHARED_MISC_DATA_SIZE       (NOT_LP64(1*M) LP64_ONLY(1200*K))
 
 #define DEFAULT_SHARED_MISC_CODE_SIZE   (120*K)
-#define MIN_SHARED_MISC_CODE_SIZE       (SHARED_MISC_SIZE_FOR(sizeof(void*))+SHARED_MISC_SIZE_FOR(DEFAULT_VTBL_METHOD_SIZE)+DEFAULT_VTBL_COMMON_CODE_SIZE)
-
+#define MIN_SHARED_MISC_CODE_SIZE       (NOT_LP64(63*K) LP64_ONLY(69*K))
 #define DEFAULT_COMBINED_SIZE           (DEFAULT_SHARED_READ_WRITE_SIZE+DEFAULT_SHARED_READ_ONLY_SIZE+DEFAULT_SHARED_MISC_DATA_SIZE+DEFAULT_SHARED_MISC_CODE_SIZE)
 
 // the max size is the MAX size (ie. 0x7FFFFFFF) - the total size of
@@ -128,6 +125,8 @@
   static bool _check_classes_made_progress;
   static bool _has_error_classes;
   static bool _archive_loading_failed;
+  static address _cds_i2i_entry_code_buffers;
+  static size_t  _cds_i2i_entry_code_buffers_size;
 
   // Used only during dumping.
   static SharedMiscRegion _md;
@@ -185,6 +184,9 @@
   // Return true if given address is in the mapped shared space.
   static bool is_in_shared_space(const void* p) NOT_CDS_RETURN_(false);
 
+  // Return true if given address is in the shared region corresponding to the idx
+  static bool is_in_shared_region(const void* p, int idx) NOT_CDS_RETURN_(false);
+
   static bool is_string_region(int idx) NOT_CDS_RETURN_(false);
 
   static void generate_vtable_methods(void** vtbl_list,
@@ -218,6 +220,15 @@
   static char* misc_code_space_alloc(size_t num_bytes) {  return _mc.alloc(num_bytes); }
   static char* misc_data_space_alloc(size_t num_bytes) {  return _md.alloc(num_bytes); }
 
+  static address cds_i2i_entry_code_buffers(size_t total_size);
+
+  static address cds_i2i_entry_code_buffers() {
+    return _cds_i2i_entry_code_buffers;
+  }
+  static size_t cds_i2i_entry_code_buffers_size() {
+    return _cds_i2i_entry_code_buffers_size;
+  }
+
   static SharedMiscRegion* misc_code_region() {
     assert(DumpSharedSpaces, "used during dumping only");
     return &_mc;
--- a/hotspot/src/share/vm/memory/resourceArea.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/memory/resourceArea.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -26,7 +26,7 @@
 #define SHARE_VM_MEMORY_RESOURCEAREA_HPP
 
 #include "memory/allocation.hpp"
-#include "runtime/thread.inline.hpp"
+#include "runtime/thread.hpp"
 
 // The resource area holds temporary data structures in the VM.
 // The actual allocation areas are thread local. Typical usage:
--- a/hotspot/src/share/vm/memory/universe.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/memory/universe.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -747,8 +747,10 @@
 
     Universe::set_narrow_ptrs_base(Universe::narrow_oop_base());
 
-    if (PrintCompressedOopsMode || (PrintMiscellaneous && Verbose)) {
-      Universe::print_compressed_oops_mode(tty);
+    if (log_is_enabled(Info, gc, heap, coops)) {
+      ResourceMark rm;
+      outputStream* logst = Log(gc, heap, coops)::info_stream();
+      Universe::print_compressed_oops_mode(logst);
     }
 
     // Tell tests in which mode we run.
@@ -776,8 +778,8 @@
 }
 
 void Universe::print_compressed_oops_mode(outputStream* st) {
-  st->print("heap address: " PTR_FORMAT ", size: " SIZE_FORMAT " MB",
-              p2i(Universe::heap()->base()), Universe::heap()->reserved_region().byte_size()/M);
+  st->print("Heap address: " PTR_FORMAT ", size: " SIZE_FORMAT " MB",
+            p2i(Universe::heap()->base()), Universe::heap()->reserved_region().byte_size()/M);
 
   st->print(", Compressed Oops mode: %s", narrow_oop_mode_to_string(narrow_oop_mode()));
 
--- a/hotspot/src/share/vm/memory/virtualspace.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/memory/virtualspace.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -24,6 +24,8 @@
 
 #include "precompiled.hpp"
 #include "code/codeCacheExtensions.hpp"
+#include "logging/log.hpp"
+#include "memory/resourceArea.hpp"
 #include "memory/virtualspace.hpp"
 #include "oops/markOop.hpp"
 #include "oops/oop.inline.hpp"
@@ -78,10 +80,7 @@
     // Different reserve address may be acceptable in other cases
     // but for compressed oops heap should be at requested address.
     assert(UseCompressedOops, "currently requested address used only for compressed oops");
-    if (PrintCompressedOopsMode) {
-      tty->cr();
-      tty->print_cr("Reserved memory not at requested address: " PTR_FORMAT " vs " PTR_FORMAT, p2i(base), p2i(requested_address));
-    }
+    log_debug(gc, heap, coops)("Reserved memory not at requested address: " PTR_FORMAT " vs " PTR_FORMAT, p2i(base), p2i(requested_address));
     // OS ignored requested address. Try different address.
     if (special) {
       if (!os::release_memory_special(base, size)) {
@@ -143,10 +142,7 @@
       // failed; try to reserve regular memory below
       if (UseLargePages && (!FLAG_IS_DEFAULT(UseLargePages) ||
                             !FLAG_IS_DEFAULT(LargePageSizeInBytes))) {
-        if (PrintCompressedOopsMode) {
-          tty->cr();
-          tty->print_cr("Reserve regular memory without large pages.");
-        }
+        log_debug(gc, heap, coops)("Reserve regular memory without large pages");
       }
     }
   }
@@ -286,11 +282,10 @@
       if (!os::protect_memory(_base, _noaccess_prefix, os::MEM_PROT_NONE, _special)) {
         fatal("cannot protect protection page");
       }
-      if (PrintCompressedOopsMode) {
-        tty->cr();
-        tty->print_cr("Protected page at the reserved heap base: "
-                      PTR_FORMAT " / " INTX_FORMAT " bytes", p2i(_base), _noaccess_prefix);
-      }
+      log_debug(gc, heap, coops)("Protected page at the reserved heap base: "
+                                 PTR_FORMAT " / " INTX_FORMAT " bytes",
+                                 p2i(_base),
+                                 _noaccess_prefix);
       assert(Universe::narrow_oop_use_implicit_null_checks() == true, "not initialized?");
     } else {
       Universe::set_narrow_oop_use_implicit_null_checks(false);
@@ -321,10 +316,10 @@
   bool special = large && !os::can_commit_large_page_memory();
   char* base = NULL;
 
-  if (PrintCompressedOopsMode && Verbose) {
-    tty->print("Trying to allocate at address " PTR_FORMAT " heap of size " SIZE_FORMAT_HEX ".\n",
-               p2i(requested_address), size);
-  }
+  log_trace(gc, heap, coops)("Trying to allocate at address " PTR_FORMAT
+                             " heap of size " SIZE_FORMAT_HEX,
+                             p2i(requested_address),
+                             size);
 
   if (special) {
     base = os::reserve_memory_special(size, alignment, requested_address, false);
@@ -343,10 +338,7 @@
     // Failed; try to reserve regular memory below
     if (UseLargePages && (!FLAG_IS_DEFAULT(UseLargePages) ||
                           !FLAG_IS_DEFAULT(LargePageSizeInBytes))) {
-      if (PrintCompressedOopsMode) {
-        tty->cr();
-        tty->print_cr("Reserve regular memory without large pages.");
-      }
+      log_debug(gc, heap, coops)("Reserve regular memory without large pages");
     }
 
     // Optimistically assume that the OSes returns an aligned base pointer.
@@ -558,9 +550,7 @@
 
     // Last, desperate try without any placement.
     if (_base == NULL) {
-      if (PrintCompressedOopsMode && Verbose) {
-        tty->print("Trying to allocate at address NULL heap of size " SIZE_FORMAT_HEX ".\n", size + noaccess_prefix);
-      }
+      log_trace(gc, heap, coops)("Trying to allocate at address NULL heap of size " SIZE_FORMAT_HEX, size + noaccess_prefix);
       initialize(size + noaccess_prefix, alignment, large, NULL, false);
     }
   }
--- a/hotspot/src/share/vm/oops/constMethod.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/oops/constMethod.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -66,6 +66,7 @@
   set_max_locals(0);
   set_method_idnum(0);
   set_size_of_parameters(0);
+  set_result_type(T_VOID);
 }
 
 // Accessor that copies to metadata.
--- a/hotspot/src/share/vm/oops/constMethod.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/oops/constMethod.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -121,6 +121,7 @@
 };
 
 class KlassSizeStats;
+class AdapterHandlerEntry;
 
 // Class to collect the sizes of ConstMethod inline tables
 #define INLINE_TABLES_DO(do_element)            \
@@ -201,8 +202,15 @@
   // Raw stackmap data for the method
   Array<u1>*        _stackmap_data;
 
+  // Adapter blob (i2c/c2i) for this Method*. Set once when method is linked.
+  union {
+    AdapterHandlerEntry* _adapter;
+    AdapterHandlerEntry** _adapter_trampoline;
+  };
+
   int               _constMethod_size;
   u2                _flags;
+  u1                _result_type;                 // BasicType of result
 
   // Size of Java bytecodes allocated immediately after Method*.
   u2                _code_size;
@@ -276,6 +284,29 @@
   void copy_stackmap_data(ClassLoaderData* loader_data, u1* sd, int length, TRAPS);
   bool has_stackmap_table() const { return _stackmap_data != NULL; }
 
+  // adapter
+  void set_adapter_entry(AdapterHandlerEntry* adapter) {
+    assert(!is_shared(), "shared methods have fixed adapter_trampoline");
+    _adapter = adapter;
+  }
+  void set_adapter_trampoline(AdapterHandlerEntry** trampoline) {
+    assert(DumpSharedSpaces, "must be");
+    assert(*trampoline == NULL, "must be NULL during dump time, to be initialized at run time");
+    _adapter_trampoline = trampoline;
+  }
+  void update_adapter_trampoline(AdapterHandlerEntry* adapter) {
+    assert(is_shared(), "must be");
+    *_adapter_trampoline = adapter;
+    assert(this->adapter() == adapter, "must be");
+  }
+  AdapterHandlerEntry* adapter() {
+    if (is_shared()) {
+      return *_adapter_trampoline;
+    } else {
+      return _adapter;
+    }
+  }
+
   void init_fingerprint() {
     const uint64_t initval = UCONST64(0x8000000000000000);
     _fingerprint = initval;
@@ -464,6 +495,8 @@
   static ByteSize size_of_parameters_offset()
                             { return byte_offset_of(ConstMethod, _size_of_parameters); }
 
+  static ByteSize result_type_offset()
+                            { return byte_offset_of(ConstMethod, _result_type); }
 
   // Unique id for the method
   static const u2 MAX_IDNUM;
@@ -486,6 +519,8 @@
   int  size_of_parameters() const                { return _size_of_parameters; }
   void set_size_of_parameters(int size)          { _size_of_parameters = size; }
 
+  void set_result_type(BasicType rt)             { assert(rt < 16, "result type too large");
+                                                   _result_type = (u1)rt; }
   // Deallocation for RedefineClasses
   void deallocate_contents(ClassLoaderData* loader_data);
   bool is_klass() const { return false; }
--- a/hotspot/src/share/vm/oops/constantPool.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/oops/constantPool.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -283,8 +283,9 @@
   this_key->record_dependency(k(), CHECK_NULL); // Can throw OOM
 
   // logging for classresolve tag.
-  trace_class_resolution(this_cp, k);
-
+  if (log_is_enabled(Debug, classresolve)){
+    trace_class_resolution(this_cp, k);
+  }
   this_cp->klass_at_put(which, k());
   entry = this_cp->resolved_klass_at(which);
   assert(entry.is_resolved() && entry.get_klass()->is_klass(), "must be resolved at this point");
@@ -340,9 +341,7 @@
   int cache_index = decode_cpcache_index(which, true);
   if (!(cache_index >= 0 && cache_index < cpool->cache()->length())) {
     // FIXME: should be an assert
-    if (PrintMiscellaneous && (Verbose||WizardMode)) {
-      tty->print_cr("bad operand %d in:", which); cpool->print();
-    }
+    log_debug(classresolve)("bad operand %d in:", which); cpool->print();
     return NULL;
   }
   ConstantPoolCacheEntry* e = cpool->cache()->entry_at(cache_index);
@@ -396,7 +395,7 @@
   int i = which;
   if (!uncached && cache() != NULL) {
     if (ConstantPool::is_invokedynamic_index(which)) {
-      // Invokedynamic index is index into resolved_references
+      // Invokedynamic index is index into the constant pool cache
       int pool_index = invokedynamic_cp_cache_entry_at(which)->constant_pool_index();
       pool_index = invoke_dynamic_name_and_type_ref_index_at(pool_index);
       assert(tag_at(pool_index).is_name_and_type(), "");
@@ -672,10 +671,11 @@
       int callee_index             = this_cp->method_handle_klass_index_at(index);
       Symbol*  name =      this_cp->method_handle_name_ref_at(index);
       Symbol*  signature = this_cp->method_handle_signature_ref_at(index);
-      if (PrintMiscellaneous)
-        tty->print_cr("resolve JVM_CONSTANT_MethodHandle:%d [%d/%d/%d] %s.%s",
-                      ref_kind, index, this_cp->method_handle_index_at(index),
-                      callee_index, name->as_C_string(), signature->as_C_string());
+      { ResourceMark rm(THREAD);
+        log_debug(classresolve)("resolve JVM_CONSTANT_MethodHandle:%d [%d/%d/%d] %s.%s",
+                              ref_kind, index, this_cp->method_handle_index_at(index),
+                              callee_index, name->as_C_string(), signature->as_C_string());
+      }
       KlassHandle callee;
       { Klass* k = klass_at_impl(this_cp, callee_index, true, CHECK_NULL);
         callee = KlassHandle(THREAD, k);
@@ -694,10 +694,11 @@
   case JVM_CONSTANT_MethodType:
     {
       Symbol*  signature = this_cp->method_type_signature_at(index);
-      if (PrintMiscellaneous)
-        tty->print_cr("resolve JVM_CONSTANT_MethodType [%d/%d] %s",
-                      index, this_cp->method_type_index_at(index),
-                      signature->as_C_string());
+      { ResourceMark rm(THREAD);
+        log_debug(classresolve)("resolve JVM_CONSTANT_MethodType [%d/%d] %s",
+                              index, this_cp->method_type_index_at(index),
+                              signature->as_C_string());
+      }
       KlassHandle klass(THREAD, this_cp->pool_holder());
       Handle value = SystemDictionary::find_method_handle_type(signature, klass, THREAD);
       result_oop = value();
@@ -964,8 +965,8 @@
 
   case JVM_CONSTANT_MethodType:
   {
-    int k1 = method_type_index_at_error_ok(index1);
-    int k2 = cp2->method_type_index_at_error_ok(index2);
+    int k1 = method_type_index_at(index1);
+    int k2 = cp2->method_type_index_at(index2);
     bool match = compare_entry_to(k1, cp2, k2, CHECK_false);
     if (match) {
       return true;
@@ -974,11 +975,11 @@
 
   case JVM_CONSTANT_MethodHandle:
   {
-    int k1 = method_handle_ref_kind_at_error_ok(index1);
-    int k2 = cp2->method_handle_ref_kind_at_error_ok(index2);
+    int k1 = method_handle_ref_kind_at(index1);
+    int k2 = cp2->method_handle_ref_kind_at(index2);
     if (k1 == k2) {
-      int i1 = method_handle_index_at_error_ok(index1);
-      int i2 = cp2->method_handle_index_at_error_ok(index2);
+      int i1 = method_handle_index_at(index1);
+      int i2 = cp2->method_handle_index_at(index2);
       bool match = compare_entry_to(i1, cp2, i2, CHECK_false);
       if (match) {
         return true;
@@ -1310,15 +1311,15 @@
   case JVM_CONSTANT_MethodType:
   case JVM_CONSTANT_MethodTypeInError:
   {
-    jint k = from_cp->method_type_index_at_error_ok(from_i);
+    jint k = from_cp->method_type_index_at(from_i);
     to_cp->method_type_index_at_put(to_i, k);
   } break;
 
   case JVM_CONSTANT_MethodHandle:
   case JVM_CONSTANT_MethodHandleInError:
   {
-    int k1 = from_cp->method_handle_ref_kind_at_error_ok(from_i);
-    int k2 = from_cp->method_handle_index_at_error_ok(from_i);
+    int k1 = from_cp->method_handle_ref_kind_at(from_i);
+    int k2 = from_cp->method_handle_index_at(from_i);
     to_cp->method_handle_index_at_put(to_i, k1, k2);
   } break;
 
@@ -1754,8 +1755,8 @@
       case JVM_CONSTANT_MethodHandle:
       case JVM_CONSTANT_MethodHandleInError: {
         *bytes = JVM_CONSTANT_MethodHandle;
-        int kind = method_handle_ref_kind_at_error_ok(idx);
-        idx1 = method_handle_index_at_error_ok(idx);
+        int kind = method_handle_ref_kind_at(idx);
+        idx1 = method_handle_index_at(idx);
         *(bytes+1) = (unsigned char) kind;
         Bytes::put_Java_u2((address) (bytes+2), idx1);
         DBG(printf("JVM_CONSTANT_MethodHandle: %d %hd", kind, idx1));
@@ -1764,7 +1765,7 @@
       case JVM_CONSTANT_MethodType:
       case JVM_CONSTANT_MethodTypeInError: {
         *bytes = JVM_CONSTANT_MethodType;
-        idx1 = method_type_index_at_error_ok(idx);
+        idx1 = method_type_index_at(idx);
         Bytes::put_Java_u2((address) (bytes+1), idx1);
         DBG(printf("JVM_CONSTANT_MethodType: %hd", idx1));
         break;
@@ -1952,12 +1953,12 @@
       break;
     case JVM_CONSTANT_MethodHandle :
     case JVM_CONSTANT_MethodHandleInError :
-      st->print("ref_kind=%d", method_handle_ref_kind_at_error_ok(index));
-      st->print(" ref_index=%d", method_handle_index_at_error_ok(index));
+      st->print("ref_kind=%d", method_handle_ref_kind_at(index));
+      st->print(" ref_index=%d", method_handle_index_at(index));
       break;
     case JVM_CONSTANT_MethodType :
     case JVM_CONSTANT_MethodTypeInError :
-      st->print("signature_index=%d", method_type_index_at_error_ok(index));
+      st->print("signature_index=%d", method_type_index_at(index));
       break;
     case JVM_CONSTANT_InvokeDynamic :
       {
--- a/hotspot/src/share/vm/oops/constantPool.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/oops/constantPool.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -460,41 +460,21 @@
     return *int_at_addr(which);
   }
 
- private:
-  int method_handle_ref_kind_at(int which, bool error_ok) {
+  int method_handle_ref_kind_at(int which) {
     assert(tag_at(which).is_method_handle() ||
-           (error_ok && tag_at(which).is_method_handle_in_error()), "Corrupted constant pool");
+           tag_at(which).is_method_handle_in_error(), "Corrupted constant pool");
     return extract_low_short_from_int(*int_at_addr(which));  // mask out unwanted ref_index bits
   }
-  int method_handle_index_at(int which, bool error_ok) {
+  int method_handle_index_at(int which) {
     assert(tag_at(which).is_method_handle() ||
-           (error_ok && tag_at(which).is_method_handle_in_error()), "Corrupted constant pool");
+           tag_at(which).is_method_handle_in_error(), "Corrupted constant pool");
     return extract_high_short_from_int(*int_at_addr(which));  // shift out unwanted ref_kind bits
   }
-  int method_type_index_at(int which, bool error_ok) {
+  int method_type_index_at(int which) {
     assert(tag_at(which).is_method_type() ||
-           (error_ok && tag_at(which).is_method_type_in_error()), "Corrupted constant pool");
+           tag_at(which).is_method_type_in_error(), "Corrupted constant pool");
     return *int_at_addr(which);
   }
- public:
-  int method_handle_ref_kind_at(int which) {
-    return method_handle_ref_kind_at(which, false);
-  }
-  int method_handle_ref_kind_at_error_ok(int which) {
-    return method_handle_ref_kind_at(which, true);
-  }
-  int method_handle_index_at(int which) {
-    return method_handle_index_at(which, false);
-  }
-  int method_handle_index_at_error_ok(int which) {
-    return method_handle_index_at(which, true);
-  }
-  int method_type_index_at(int which) {
-    return method_type_index_at(which, false);
-  }
-  int method_type_index_at_error_ok(int which) {
-    return method_type_index_at(which, true);
-  }
 
   // Derived queries:
   Symbol* method_handle_name_ref_at(int which) {
--- a/hotspot/src/share/vm/oops/cpCache.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/oops/cpCache.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -77,18 +77,19 @@
 // f2 flag true if f2 contains an oop (e.g., virtual final method)
 // fv flag true if invokeinterface used for method in class Object
 //
-// The flags 31, 30, 29, 28 together build a 4 bit number 0 to 8 with the
+// The flags 31, 30, 29, 28 together build a 4 bit number 0 to 16 with the
 // following mapping to the TosState states:
 //
 // btos: 0
-// ctos: 1
-// stos: 2
-// itos: 3
-// ltos: 4
-// ftos: 5
-// dtos: 6
-// atos: 7
-// vtos: 8
+// ztos: 1
+// ctos: 2
+// stos: 3
+// itos: 4
+// ltos: 5
+// ftos: 6
+// dtos: 7
+// atos: 8
+// vtos: 9
 //
 // Entry specific: field entries:
 // _indices = get (b1 section) and put (b2 section) bytecodes, original constant pool index
@@ -352,14 +353,8 @@
   bool has_method_type() const                   { return (!is_f1_null()) && (_flags & (1 << has_method_type_shift))   != 0; }
   bool is_method_entry() const                   { return (_flags & (1 << is_field_entry_shift))    == 0; }
   bool is_field_entry() const                    { return (_flags & (1 << is_field_entry_shift))    != 0; }
-  bool is_byte() const                           { return flag_state() == btos; }
-  bool is_char() const                           { return flag_state() == ctos; }
-  bool is_short() const                          { return flag_state() == stos; }
-  bool is_int() const                            { return flag_state() == itos; }
   bool is_long() const                           { return flag_state() == ltos; }
-  bool is_float() const                          { return flag_state() == ftos; }
   bool is_double() const                         { return flag_state() == dtos; }
-  bool is_object() const                         { return flag_state() == atos; }
   TosState flag_state() const                    { assert((uint)number_of_states <= (uint)tos_state_mask+1, "");
                                                    return (TosState)((_flags >> tos_state_shift) & tos_state_mask); }
 
--- a/hotspot/src/share/vm/oops/klass.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/oops/klass.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -342,6 +342,21 @@
     assert(btvalue >= T_BOOLEAN && btvalue <= T_OBJECT, "sanity");
     return (BasicType) btvalue;
   }
+
+  // Want a pattern to quickly diff against layout header in register
+  // find something less clever!
+  static int layout_helper_boolean_diffbit() {
+    jint zlh = array_layout_helper(T_BOOLEAN);
+    jint blh = array_layout_helper(T_BYTE);
+    assert(zlh != blh, "array layout helpers must differ");
+    int diffbit = 1;
+    while ((diffbit & (zlh ^ blh)) == 0 && (diffbit & zlh) == 0) {
+      diffbit <<= 1;
+      assert(diffbit != 0, "make sure T_BOOLEAN has a different bit than T_BYTE");
+    }
+    return diffbit;
+  }
+
   static int layout_helper_log2_element_size(jint lh) {
     assert(lh < (jint)_lh_neutral_value, "must be array");
     int l2esz = (lh >> _lh_log2_element_size_shift) & _lh_log2_element_size_mask;
--- a/hotspot/src/share/vm/oops/method.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/oops/method.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -38,6 +38,7 @@
 #include "interpreter/oopMapCache.hpp"
 #include "memory/heapInspection.hpp"
 #include "memory/metadataFactory.hpp"
+#include "memory/metaspaceShared.hpp"
 #include "memory/oopFactory.hpp"
 #include "memory/resourceArea.hpp"
 #include "oops/constMethod.hpp"
@@ -83,9 +84,6 @@
   NoSafepointVerifier no_safepoint;
   set_constMethod(xconst);
   set_access_flags(access_flags);
-#ifdef CC_INTERP
-  set_result_index(T_VOID);
-#endif
   set_intrinsic_id(vmIntrinsics::_none);
   set_jfr_towrite(false);
   set_force_inline(false);
@@ -123,18 +121,18 @@
 }
 
 address Method::get_i2c_entry() {
-  assert(_adapter != NULL, "must have");
-  return _adapter->get_i2c_entry();
+  assert(adapter() != NULL, "must have");
+  return adapter()->get_i2c_entry();
 }
 
 address Method::get_c2i_entry() {
-  assert(_adapter != NULL, "must have");
-  return _adapter->get_c2i_entry();
+  assert(adapter() != NULL, "must have");
+  return adapter()->get_c2i_entry();
 }
 
 address Method::get_c2i_unverified_entry() {
-  assert(_adapter != NULL, "must have");
-  return _adapter->get_c2i_unverified_entry();
+  assert(adapter() != NULL, "must have");
+  return adapter()->get_c2i_unverified_entry();
 }
 
 char* Method::name_and_sig_as_C_string() const {
@@ -444,12 +442,6 @@
   set_size_of_parameters(asc.size() + (is_static() ? 0 : 1));
 }
 
-#ifdef CC_INTERP
-void Method::set_result_index(BasicType type)          {
-  _result_index = Interpreter::BasicType_as_index(type);
-}
-#endif
-
 BasicType Method::result_type() const {
   ResultTypeFinder rtf(signature());
   return rtf.type();
@@ -892,10 +884,10 @@
 
   // this may be NULL if c2i adapters have not been made yet
   // Only should happen at allocate time.
-  if (_adapter == NULL) {
+  if (adapter() == NULL) {
     _from_compiled_entry    = NULL;
   } else {
-    _from_compiled_entry    = _adapter->get_c2i_entry();
+    _from_compiled_entry    = adapter()->get_c2i_entry();
   }
   OrderAccess::storestore();
   _from_interpreted_entry = _i2i_entry;
@@ -903,47 +895,68 @@
   _code = NULL;
 }
 
+#if INCLUDE_CDS
 // Called by class data sharing to remove any entry points (which are not shared)
 void Method::unlink_method() {
   _code = NULL;
-  _i2i_entry = NULL;
-  _from_interpreted_entry = NULL;
+
+  assert(DumpSharedSpaces, "dump time only");
+  // Set the values to what they should be at run time. Note that
+  // this Method can no longer be executed during dump time.
+  _i2i_entry = Interpreter::entry_for_cds_method(this);
+  _from_interpreted_entry = _i2i_entry;
+
   if (is_native()) {
     *native_function_addr() = NULL;
     set_signature_handler(NULL);
   }
   NOT_PRODUCT(set_compiled_invocation_count(0);)
-  _adapter = NULL;
-  _from_compiled_entry = NULL;
+
+  CDSAdapterHandlerEntry* cds_adapter = (CDSAdapterHandlerEntry*)adapter();
+  constMethod()->set_adapter_trampoline(cds_adapter->get_adapter_trampoline());
+  _from_compiled_entry = cds_adapter->get_c2i_entry_trampoline();
+  assert(*((int*)_from_compiled_entry) == 0, "must be NULL during dump time, to be initialized at run time");
+
 
   // In case of DumpSharedSpaces, _method_data should always be NULL.
-  //
-  // During runtime (!DumpSharedSpaces), when we are cleaning a
-  // shared class that failed to load, this->link_method() may
-  // have already been called (before an exception happened), so
-  // this->_method_data may not be NULL.
-  assert(!DumpSharedSpaces || _method_data == NULL, "unexpected method data?");
+  assert(_method_data == NULL, "unexpected method data?");
 
   set_method_data(NULL);
   clear_method_counters();
 }
+#endif
 
 // Called when the method_holder is getting linked. Setup entrypoints so the method
 // is ready to be called from interpreter, compiler, and vtables.
 void Method::link_method(const methodHandle& h_method, TRAPS) {
   // If the code cache is full, we may reenter this function for the
   // leftover methods that weren't linked.
-  if (_i2i_entry != NULL) return;
+  if (is_shared()) {
+    if (adapter() != NULL) return;
+  } else {
+    if (_i2i_entry != NULL) return;
 
-  assert(_adapter == NULL, "init'd to NULL" );
+    assert(adapter() == NULL, "init'd to NULL" );
+  }
   assert( _code == NULL, "nothing compiled yet" );
 
   // Setup interpreter entrypoint
   assert(this == h_method(), "wrong h_method()" );
-  address entry = Interpreter::entry_for_method(h_method);
+  address entry;
+
+  if (this->is_shared()) {
+    entry = Interpreter::entry_for_cds_method(h_method);
+  } else {
+    entry = Interpreter::entry_for_method(h_method);
+  }
   assert(entry != NULL, "interpreter entry must be non-null");
-  // Sets both _i2i_entry and _from_interpreted_entry
-  set_interpreter_entry(entry);
+  if (is_shared()) {
+    assert(entry == _i2i_entry && entry == _from_interpreted_entry,
+           "should be correctly set during dump time");
+  } else {
+    // Sets both _i2i_entry and _from_interpreted_entry
+    set_interpreter_entry(entry);
+  }
 
   // Don't overwrite already registered native entries.
   if (is_native() && !has_native_function()) {
@@ -975,8 +988,13 @@
     THROW_MSG_NULL(vmSymbols::java_lang_VirtualMachineError(), "Out of space in CodeCache for adapters");
   }
 
-  mh->set_adapter_entry(adapter);
-  mh->_from_compiled_entry = adapter->get_c2i_entry();
+  if (mh->is_shared()) {
+    assert(mh->adapter() == adapter, "must be");
+    assert(mh->_from_compiled_entry != NULL, "must be"); // FIXME, the instructions also not NULL
+  } else {
+    mh->set_adapter_entry(adapter);
+    mh->_from_compiled_entry = adapter->get_c2i_entry();
+  }
   return adapter->get_c2i_entry();
 }
 
@@ -992,6 +1010,14 @@
   }
 }
 
+volatile address Method::from_compiled_entry_no_trampoline() const {
+  nmethod *code = (nmethod *)OrderAccess::load_ptr_acquire(&_code);
+  if (code) {
+    return code->verified_entry_point();
+  } else {
+    return adapter()->get_c2i_entry();
+  }
+}
 
 // The verified_code_entry() must be called when a invoke is resolved
 // on this method.
@@ -1185,10 +1211,8 @@
   m->set_signature_index(_imcp_invoke_signature);
   assert(MethodHandles::is_signature_polymorphic_name(m->name()), "");
   assert(m->signature() == signature, "");
-#ifdef CC_INTERP
   ResultTypeFinder rtf(signature);
-  m->set_result_index(rtf.type());
-#endif
+  m->constMethod()->set_result_type(rtf.type());
   m->compute_size_of_parameters(THREAD);
   m->init_intrinsic_id();
   assert(m->is_method_handle_intrinsic(), "");
--- a/hotspot/src/share/vm/oops/method.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/oops/method.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -69,9 +69,6 @@
   AccessFlags       _access_flags;               // Access flags
   int               _vtable_index;               // vtable index of this method (see VtableIndexFlag)
                                                  // note: can have vtables with >2**16 elements (because of inheritance)
-#ifdef CC_INTERP
-  int               _result_index;               // C++ interpreter needs for converting results to/from stack
-#endif
   u2                _intrinsic_id;               // vmSymbols::intrinsic_id (0 == _none)
 
   // Flags
@@ -93,8 +90,6 @@
 #endif
   // Entry point for calling both from and to the interpreter.
   address _i2i_entry;           // All-args-on-stack calling convention
-  // Adapter blob (i2c/c2i) for this Method*. Set once when method is linked.
-  AdapterHandlerEntry* _adapter;
   // Entry point for calling from compiled code, to compiled code if it exists
   // or else the interpreter.
   volatile address _from_compiled_entry;        // Cache of: _code ? _code->entry_point() : _adapter->c2i_entry()
@@ -137,6 +132,7 @@
 
   static address make_adapters(methodHandle mh, TRAPS);
   volatile address from_compiled_entry() const   { return (address)OrderAccess::load_ptr_acquire(&_from_compiled_entry); }
+  volatile address from_compiled_entry_no_trampoline() const;
   volatile address from_interpreted_entry() const{ return (address)OrderAccess::load_ptr_acquire(&_from_interpreted_entry); }
 
   // access flag
@@ -172,11 +168,6 @@
     return constMethod()->type_annotations();
   }
 
-#ifdef CC_INTERP
-  void set_result_index(BasicType type);
-  int  result_index()                            { return _result_index; }
-#endif
-
   // Helper routine: get klass name + "." + method name + signature as
   // C string, for the purpose of providing more useful NoSuchMethodErrors
   // and fatal error handling. The string is allocated in resource
@@ -435,15 +426,23 @@
   nmethod* volatile code() const                 { assert( check_code(), "" ); return (nmethod *)OrderAccess::load_ptr_acquire(&_code); }
   void clear_code();            // Clear out any compiled code
   static void set_code(methodHandle mh, nmethod* code);
-  void set_adapter_entry(AdapterHandlerEntry* adapter) {  _adapter = adapter; }
+  void set_adapter_entry(AdapterHandlerEntry* adapter) {
+    constMethod()->set_adapter_entry(adapter);
+  }
+  void update_adapter_trampoline(AdapterHandlerEntry* adapter) {
+    constMethod()->update_adapter_trampoline(adapter);
+  }
+
   address get_i2c_entry();
   address get_c2i_entry();
   address get_c2i_unverified_entry();
-  AdapterHandlerEntry* adapter() {  return _adapter; }
+  AdapterHandlerEntry* adapter() const {
+    return constMethod()->adapter();
+  }
   // setup entry points
   void link_method(const methodHandle& method, TRAPS);
-  // clear entry points. Used by sharing code
-  void unlink_method();
+  // clear entry points. Used by sharing code during dump time
+  void unlink_method() NOT_CDS_RETURN;
 
   // vtable index
   enum VtableIndexFlag {
@@ -469,7 +468,15 @@
   // interpreter entry
   address interpreter_entry() const              { return _i2i_entry; }
   // Only used when first initialize so we can set _i2i_entry and _from_interpreted_entry
-  void set_interpreter_entry(address entry)      { _i2i_entry = entry;  _from_interpreted_entry = entry; }
+  void set_interpreter_entry(address entry) {
+    assert(!is_shared(), "shared method's interpreter entry should not be changed at run time");
+    if (_i2i_entry != entry) {
+      _i2i_entry = entry;
+    }
+    if (_from_interpreted_entry != entry) {
+      _from_interpreted_entry = entry;
+    }
+  }
 
   // native function (used for native methods only)
   enum {
@@ -537,7 +544,6 @@
   void compute_size_of_parameters(Thread *thread); // word size of parameters (receiver if any + arguments)
   Symbol* klass_name() const;                    // returns the name of the method holder
   BasicType result_type() const;                 // type of the method result
-  int result_type_index() const;                 // type index of the method result
   bool is_returning_oop() const                  { BasicType r = result_type(); return (r == T_OBJECT || r == T_ARRAY); }
   bool is_returning_fp() const                   { BasicType r = result_type(); return (r == T_FLOAT || r == T_DOUBLE); }
 
@@ -638,9 +644,6 @@
   // interpreter support
   static ByteSize const_offset()                 { return byte_offset_of(Method, _constMethod       ); }
   static ByteSize access_flags_offset()          { return byte_offset_of(Method, _access_flags      ); }
-#ifdef CC_INTERP
-  static ByteSize result_index_offset()          { return byte_offset_of(Method, _result_index ); }
-#endif /* CC_INTERP */
   static ByteSize from_compiled_offset()         { return byte_offset_of(Method, _from_compiled_entry); }
   static ByteSize code_offset()                  { return byte_offset_of(Method, _code); }
   static ByteSize method_data_offset()           {
--- a/hotspot/src/share/vm/oops/methodData.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/oops/methodData.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -1729,6 +1729,7 @@
 }
 
 void MethodData::clean_method_data(BoolObjectClosure* is_alive) {
+  ResourceMark rm;
   for (ProfileData* data = first_data();
        is_valid(data);
        data = next_data(data)) {
@@ -1745,6 +1746,7 @@
 }
 
 void MethodData::clean_weak_method_links() {
+  ResourceMark rm;
   for (ProfileData* data = first_data();
        is_valid(data);
        data = next_data(data)) {
@@ -1758,6 +1760,7 @@
 
 #ifdef ASSERT
 void MethodData::verify_clean_weak_method_links() {
+  ResourceMark rm;
   for (ProfileData* data = first_data();
        is_valid(data);
        data = next_data(data)) {
--- a/hotspot/src/share/vm/oops/oop.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/oops/oop.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -30,7 +30,6 @@
 #include "memory/memRegion.hpp"
 #include "oops/metadata.hpp"
 #include "utilities/macros.hpp"
-#include "utilities/top.hpp"
 
 // oopDesc is the top baseclass for objects classes. The {name}Desc classes describe
 // the format of Java objects so the fields can be accessed from C++.
--- a/hotspot/src/share/vm/oops/oop.inline.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/oops/oop.inline.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -443,7 +443,7 @@
 void oopDesc::char_field_put(int offset, jchar contents)      { *char_field_addr(offset) = (jint) contents; }
 
 jboolean oopDesc::bool_field(int offset) const                { return (jboolean) *bool_field_addr(offset); }
-void oopDesc::bool_field_put(int offset, jboolean contents)   { *bool_field_addr(offset) = (jint) contents; }
+void oopDesc::bool_field_put(int offset, jboolean contents)   { *bool_field_addr(offset) = (((jint) contents) & 1); }
 
 jint oopDesc::int_field(int offset) const                     { return *int_field_addr(offset);        }
 void oopDesc::int_field_put(int offset, jint contents)        { *int_field_addr(offset) = contents;    }
@@ -483,7 +483,7 @@
 void oopDesc::release_char_field_put(int offset, jchar contents)      { OrderAccess::release_store(char_field_addr(offset), contents); }
 
 jboolean oopDesc::bool_field_acquire(int offset) const                { return OrderAccess::load_acquire(bool_field_addr(offset));     }
-void oopDesc::release_bool_field_put(int offset, jboolean contents)   { OrderAccess::release_store(bool_field_addr(offset), contents); }
+void oopDesc::release_bool_field_put(int offset, jboolean contents)   { OrderAccess::release_store(bool_field_addr(offset), (contents & 1)); }
 
 jint oopDesc::int_field_acquire(int offset) const                     { return OrderAccess::load_acquire(int_field_addr(offset));      }
 void oopDesc::release_int_field_put(int offset, jint contents)        { OrderAccess::release_store(int_field_addr(offset), contents);  }
--- a/hotspot/src/share/vm/oops/symbol.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/oops/symbol.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -25,9 +25,10 @@
 #ifndef SHARE_VM_OOPS_SYMBOL_HPP
 #define SHARE_VM_OOPS_SYMBOL_HPP
 
-#include "utilities/utf8.hpp"
 #include "memory/allocation.hpp"
 #include "runtime/atomic.hpp"
+#include "utilities/exceptions.hpp"
+#include "utilities/utf8.hpp"
 
 // A Symbol is a canonicalized string.
 // All Symbols reside in global SymbolTable and are reference counted.
--- a/hotspot/src/share/vm/oops/typeArrayOop.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/oops/typeArrayOop.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -96,7 +96,7 @@
   void byte_at_put(int which, jbyte contents)     { *byte_at_addr(which) = contents; }
 
   jboolean bool_at(int which) const               { return *bool_at_addr(which); }
-  void bool_at_put(int which, jboolean contents)  { *bool_at_addr(which) = contents; }
+  void bool_at_put(int which, jboolean contents)  { *bool_at_addr(which) = (((jint)contents) & 1); }
 
   jchar char_at(int which) const                  { return *char_at_addr(which); }
   void char_at_put(int which, jchar contents)     { *char_at_addr(which) = contents; }
--- a/hotspot/src/share/vm/opto/memnode.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/opto/memnode.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -2389,7 +2389,7 @@
          ctl != NULL, "raw memory operations should have control edge");
 
   switch (bt) {
-  case T_BOOLEAN:
+  case T_BOOLEAN: val = gvn.transform(new AndINode(val, gvn.intcon(0x1))); // Fall through to T_BYTE case
   case T_BYTE:    return new StoreBNode(ctl, mem, adr, adr_type, val, mo);
   case T_INT:     return new StoreINode(ctl, mem, adr, adr_type, val, mo);
   case T_CHAR:
--- a/hotspot/src/share/vm/opto/parse1.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/opto/parse1.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -730,6 +730,26 @@
 #endif
 }
 
+static Node* mask_int_value(Node* v, BasicType bt, PhaseGVN* gvn) {
+  switch (bt) {
+  case T_BYTE:
+    v = gvn->transform(new LShiftINode(v, gvn->intcon(24)));
+    v = gvn->transform(new RShiftINode(v, gvn->intcon(24)));
+    break;
+  case T_SHORT:
+    v = gvn->transform(new LShiftINode(v, gvn->intcon(16)));
+    v = gvn->transform(new RShiftINode(v, gvn->intcon(16)));
+    break;
+  case T_CHAR:
+    v = gvn->transform(new AndINode(v, gvn->intcon(0xFFFF)));
+    break;
+  case T_BOOLEAN:
+    v = gvn->transform(new AndINode(v, gvn->intcon(0x1)));
+    break;
+  }
+  return v;
+}
+
 //-------------------------------build_exits----------------------------------
 // Build normal and exceptional exit merge points.
 void Parse::build_exits() {
@@ -754,6 +774,16 @@
   // Add a return value to the exit state.  (Do not push it yet.)
   if (tf()->range()->cnt() > TypeFunc::Parms) {
     const Type* ret_type = tf()->range()->field_at(TypeFunc::Parms);
+    if (ret_type->isa_int()) {
+      BasicType ret_bt = method()->return_type()->basic_type();
+      if (ret_bt == T_BOOLEAN ||
+          ret_bt == T_CHAR ||
+          ret_bt == T_BYTE ||
+          ret_bt == T_SHORT) {
+        ret_type = TypeInt::INT;
+      }
+    }
+
     // Don't "bind" an unloaded return klass to the ret_phi. If the klass
     // becomes loaded during the subsequent parsing, the loaded and unloaded
     // types will not join when we transform and push in do_exits().
@@ -1014,6 +1044,10 @@
       }
       return;
     }
+    if (ret_type->isa_int()) {
+      BasicType ret_bt = method()->return_type()->basic_type();
+      ret_phi = mask_int_value(ret_phi, ret_bt, &_gvn);
+    }
     _exits.push_node(ret_type->basic_type(), ret_phi);
   }
 
--- a/hotspot/src/share/vm/opto/parse2.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/opto/parse2.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -64,11 +64,15 @@
 
 //--------------------------------array_store----------------------------------
 void Parse::array_store(BasicType elem_type) {
-  Node* adr = array_addressing(elem_type, 1);
+  const Type* elem = Type::TOP;
+  Node* adr = array_addressing(elem_type, 1, &elem);
   if (stopped())  return;     // guaranteed null or range check
   Node* val = pop();
   dec_sp(2);                  // Pop array and index
   const TypeAryPtr* adr_type = TypeAryPtr::get_array_body_type(elem_type);
+  if (elem == TypeInt::BOOL) {
+    elem_type = T_BOOLEAN;
+  }
   store_to_memory(control(), adr, val, elem_type, adr_type, StoreNode::release_if_reference(elem_type));
 }
 
--- a/hotspot/src/share/vm/opto/type.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/opto/type.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -1820,13 +1820,15 @@
       break;
     case T_OBJECT:
     case T_ARRAY:
+    case T_FLOAT:
+    case T_INT:
+      field_array[pos++] = get_const_type(type);
+      break;
     case T_BOOLEAN:
     case T_CHAR:
-    case T_FLOAT:
     case T_BYTE:
     case T_SHORT:
-    case T_INT:
-      field_array[pos++] = get_const_type(type);
+      field_array[pos++] = TypeInt::INT;
       break;
     default:
       ShouldNotReachHere();
--- a/hotspot/src/share/vm/precompiled/precompiled.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/precompiled/precompiled.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -242,7 +242,6 @@
 # include "utilities/ostream.hpp"
 # include "utilities/preserveException.hpp"
 # include "utilities/sizes.hpp"
-# include "utilities/top.hpp"
 # include "utilities/utf8.hpp"
 #ifdef COMPILER2
 # include "libadt/dict.hpp"
--- a/hotspot/src/share/vm/prims/jni.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/prims/jni.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -919,7 +919,14 @@
  protected:
   va_list _ap;
 
-  inline void get_bool()   { _arguments->push_int(va_arg(_ap, jint)); } // bool is coerced to int when using va_arg
+  inline void get_bool()   {
+    // Normalize boolean arguments from native code by converting 1-255 to JNI_TRUE and
+    // 0 to JNI_FALSE.  Boolean return values from native are normalized the same in
+    // TemplateInterpreterGenerator::generate_result_handler_for and
+    // SharedRuntime::generate_native_wrapper.
+    jboolean b = va_arg(_ap, jint);
+    _arguments->push_int((jint)(b == 0 ? JNI_FALSE : JNI_TRUE));
+  }
   inline void get_char()   { _arguments->push_int(va_arg(_ap, jint)); } // char is coerced to int when using va_arg
   inline void get_short()  { _arguments->push_int(va_arg(_ap, jint)); } // short is coerced to int when using va_arg
   inline void get_byte()   { _arguments->push_int(va_arg(_ap, jint)); } // byte is coerced to int when using va_arg
@@ -960,9 +967,17 @@
       while ( 1 ) {
         switch ( fingerprint & parameter_feature_mask ) {
           case bool_parm:
+            get_bool();
+            break;
           case char_parm:
+            get_char();
+            break;
           case short_parm:
+            get_short();
+            break;
           case byte_parm:
+            get_byte();
+            break;
           case int_parm:
             get_int();
             break;
@@ -996,7 +1011,14 @@
  protected:
   const jvalue *_ap;
 
-  inline void get_bool()   { _arguments->push_int((jint)(_ap++)->z); }
+  inline void get_bool()   {
+    // Normalize boolean arguments from native code by converting 1-255 to JNI_TRUE and
+    // 0 to JNI_FALSE.  Boolean return values from native are normalized the same in
+    // TemplateInterpreterGenerator::generate_result_handler_for and
+    // SharedRuntime::generate_native_wrapper.
+    jboolean b = (_ap++)->z;
+    _arguments->push_int((jint)(b == 0 ? JNI_FALSE : JNI_TRUE));
+  }
   inline void get_char()   { _arguments->push_int((jint)(_ap++)->c); }
   inline void get_short()  { _arguments->push_int((jint)(_ap++)->s); }
   inline void get_byte()   { _arguments->push_int((jint)(_ap++)->b); }
@@ -2188,6 +2210,7 @@
     field_value.unionType = value; \
     o = JvmtiExport::jni_SetField_probe_nh(thread, obj, o, k, fieldID, false, SigType, (jvalue *)&field_value); \
   } \
+  if (SigType == 'Z') { value = ((jboolean)value) & 1; } \
   o->Fieldname##_field_put(offset, value); \
   ReturnProbe; \
 JNI_END
@@ -2387,6 +2410,7 @@
     field_value.unionType = value; \
     JvmtiExport::jni_SetField_probe(thread, NULL, NULL, id->holder(), fieldID, true, SigType, (jvalue *)&field_value); \
   } \
+  if (SigType == 'Z') { value = ((jboolean)value) & 1; } \
   id->holder()->java_mirror()-> Fieldname##_field_put (id->offset(), value); \
   ReturnProbe;\
 JNI_END
--- a/hotspot/src/share/vm/prims/jvm.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/prims/jvm.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -79,7 +79,6 @@
 #include "utilities/events.hpp"
 #include "utilities/histogram.hpp"
 #include "utilities/macros.hpp"
-#include "utilities/top.hpp"
 #include "utilities/utf8.hpp"
 #if INCLUDE_CDS
 #include "classfile/sharedClassUtil.hpp"
@@ -534,7 +533,6 @@
 
 JVM_ENTRY(jobject, JVM_CallStackWalk(JNIEnv *env, jobject stackStream, jlong mode,
                                      jint skip_frames, jint frame_count, jint start_index,
-                                     jobjectArray classes,
                                      jobjectArray frames))
   JVMWrapper("JVM_CallStackWalk");
   JavaThread* jt = (JavaThread*) THREAD;
@@ -543,78 +541,51 @@
   }
 
   Handle stackStream_h(THREAD, JNIHandles::resolve_non_null(stackStream));
-  objArrayOop ca = objArrayOop(JNIHandles::resolve_non_null(classes));
-  objArrayHandle classes_array_h(THREAD, ca);
-
-  // frames array is null when only getting caller reference
-  objArrayOop fa = objArrayOop(JNIHandles::resolve(frames));
+
+  // frames array is a Class<?>[] array when only getting caller reference,
+  // and a StackFrameInfo[] array (or derivative) otherwise. It should never
+  // be null.
+  objArrayOop fa = objArrayOop(JNIHandles::resolve_non_null(frames));
   objArrayHandle frames_array_h(THREAD, fa);
 
   int limit = start_index + frame_count;
-  if (classes_array_h->length() < limit) {
+  if (frames_array_h->length() < limit) {
     THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(), "not enough space in buffers", NULL);
   }
 
   Handle result = StackWalk::walk(stackStream_h, mode, skip_frames, frame_count,
-                                  start_index, classes_array_h,
-                                  frames_array_h, CHECK_NULL);
+                                  start_index, frames_array_h, CHECK_NULL);
   return JNIHandles::make_local(env, result());
 JVM_END
 
 
 JVM_ENTRY(jint, JVM_MoreStackWalk(JNIEnv *env, jobject stackStream, jlong mode, jlong anchor,
                                   jint frame_count, jint start_index,
-                                  jobjectArray classes,
                                   jobjectArray frames))
   JVMWrapper("JVM_MoreStackWalk");
   JavaThread* jt = (JavaThread*) THREAD;
-  objArrayOop ca = objArrayOop(JNIHandles::resolve_non_null(classes));
-  objArrayHandle classes_array_h(THREAD, ca);
-
-  // frames array is null when only getting caller reference
-  objArrayOop fa = objArrayOop(JNIHandles::resolve(frames));
+
+  // frames array is a Class<?>[] array when only getting caller reference,
+  // and a StackFrameInfo[] array (or derivative) otherwise. It should never
+  // be null.
+  objArrayOop fa = objArrayOop(JNIHandles::resolve_non_null(frames));
   objArrayHandle frames_array_h(THREAD, fa);
 
   int limit = start_index+frame_count;
-  if (classes_array_h->length() < limit) {
+  if (frames_array_h->length() < limit) {
     THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "not enough space in buffers");
   }
 
   Handle stackStream_h(THREAD, JNIHandles::resolve_non_null(stackStream));
   return StackWalk::moreFrames(stackStream_h, mode, anchor, frame_count,
-                               start_index, classes_array_h,
-                               frames_array_h, THREAD);
+                               start_index, frames_array_h, THREAD);
 JVM_END
 
-JVM_ENTRY(void, JVM_FillStackFrames(JNIEnv *env, jclass stackStream,
-                                    jint start_index,
-                                    jobjectArray frames,
-                                    jint from_index, jint to_index))
-  JVMWrapper("JVM_FillStackFrames");
-  if (TraceStackWalk) {
-    tty->print("JVM_FillStackFrames() start_index=%d from_index=%d to_index=%d\n",
-               start_index, from_index, to_index);
-  }
-
-  JavaThread* jt = (JavaThread*) THREAD;
-
-  objArrayOop fa = objArrayOop(JNIHandles::resolve_non_null(frames));
-  objArrayHandle frames_array_h(THREAD, fa);
-
-  if (frames_array_h->length() < to_index) {
-    THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "array length not matched");
-  }
-
-  for (int i = from_index; i < to_index; i++) {
-    Handle stackFrame(THREAD, frames_array_h->obj_at(i));
-    java_lang_StackFrameInfo::fill_methodInfo(stackFrame, CHECK);
-  }
-JVM_END
-
-JVM_ENTRY(void, JVM_SetMethodInfo(JNIEnv *env, jobject frame))
-  JVMWrapper("JVM_SetMethodInfo");
-  Handle stackFrame(THREAD, JNIHandles::resolve(frame));
-  java_lang_StackFrameInfo::fill_methodInfo(stackFrame, THREAD);
+JVM_ENTRY(void, JVM_ToStackTraceElement(JNIEnv *env, jobject frame, jobject stack))
+  JVMWrapper("JVM_ToStackTraceElement");
+  Handle stack_frame_info(THREAD, JNIHandles::resolve_non_null(frame));
+  Handle stack_trace_element(THREAD, JNIHandles::resolve_non_null(stack));
+  java_lang_StackFrameInfo::to_stack_trace_element(stack_frame_info, stack_trace_element, THREAD);
 JVM_END
 
 // java.lang.Object ///////////////////////////////////////////////
@@ -1818,9 +1789,6 @@
   // Ensure class is linked
   k->link_class(CHECK_NULL);
 
-  // 4496456 We need to filter out java.lang.Throwable.backtrace
-  bool skip_backtrace = false;
-
   // Allocate result
   int num_fields;
 
@@ -1831,11 +1799,6 @@
     }
   } else {
     num_fields = k->java_fields_count();
-
-    if (k() == SystemDictionary::Throwable_klass()) {
-      num_fields--;
-      skip_backtrace = true;
-    }
   }
 
   objArrayOop r = oopFactory::new_objArray(SystemDictionary::reflect_Field_klass(), num_fields, CHECK_NULL);
@@ -1844,12 +1807,6 @@
   int out_idx = 0;
   fieldDescriptor fd;
   for (JavaFieldStream fs(k); !fs.done(); fs.next()) {
-    if (skip_backtrace) {
-      // 4496456 skip java.lang.Throwable.backtrace
-      int offset = fs.offset();
-      if (offset == java_lang_Throwable::get_backtrace_offset()) continue;
-    }
-
     if (!publicOnly || fs.access_flags().is_public()) {
       fd.reinitialize(k(), fs.index());
       oop field = Reflection::new_field(&fd, CHECK_NULL);
--- a/hotspot/src/share/vm/prims/jvm.h	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/prims/jvm.h	Wed Jul 05 21:37:42 2017 +0200
@@ -209,7 +209,6 @@
  */
 enum {
   JVM_STACKWALK_FILL_CLASS_REFS_ONLY       = 0x2,
-  JVM_STACKWALK_FILTER_FILL_IN_STACK_TRACE = 0x10,
   JVM_STACKWALK_SHOW_HIDDEN_FRAMES         = 0x20,
   JVM_STACKWALK_FILL_LIVE_STACK_FRAMES     = 0x100
 };
@@ -217,23 +216,15 @@
 JNIEXPORT jobject JNICALL
 JVM_CallStackWalk(JNIEnv *env, jobject stackStream, jlong mode,
                   jint skip_frames, jint frame_count, jint start_index,
-                  jobjectArray classes,
                   jobjectArray frames);
 
 JNIEXPORT jint JNICALL
 JVM_MoreStackWalk(JNIEnv *env, jobject stackStream, jlong mode, jlong anchor,
                   jint frame_count, jint start_index,
-                  jobjectArray classes,
                   jobjectArray frames);
 
 JNIEXPORT void JNICALL
-JVM_FillStackFrames(JNIEnv* env, jclass cls,
-                    jint start_index,
-                    jobjectArray frames,
-                    jint from_index, jint toIndex);
-
-JNIEXPORT void JNICALL
-JVM_SetMethodInfo(JNIEnv* env, jobject frame);
+JVM_ToStackTraceElement(JNIEnv* env, jobject frame, jobject stackElement);
 
 /*
  * java.lang.Thread
--- a/hotspot/src/share/vm/prims/jvmtiEnvBase.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/prims/jvmtiEnvBase.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -1354,7 +1354,7 @@
   ResultTypeFinder rtf(signature);
   TosState fr_tos = as_TosState(rtf.type());
   if (fr_tos != tos) {
-    if (tos != itos || (fr_tos != btos && fr_tos != ctos && fr_tos != stos)) {
+    if (tos != itos || (fr_tos != btos && fr_tos != ztos && fr_tos != ctos && fr_tos != stos)) {
       return JVMTI_ERROR_TYPE_MISMATCH;
     }
   }
--- a/hotspot/src/share/vm/prims/jvmtiExport.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/prims/jvmtiExport.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -1702,7 +1702,7 @@
   address location, KlassHandle field_klass, Handle object, jfieldID field,
   char sig_type, jvalue *value) {
 
-  if (sig_type == 'I' || sig_type == 'Z' || sig_type == 'C' || sig_type == 'S') {
+  if (sig_type == 'I' || sig_type == 'Z' || sig_type == 'B' || sig_type == 'C' || sig_type == 'S') {
     // 'I' instructions are used for byte, char, short and int.
     // determine which it really is, and convert
     fieldDescriptor fd;
@@ -2260,7 +2260,7 @@
     if (env->is_enabled(JVMTI_EVENT_VM_OBJECT_ALLOC)) {
       EVT_TRACE(JVMTI_EVENT_VM_OBJECT_ALLOC, ("JVMTI [%s] Evt vmobject alloc sent %s",
                                          JvmtiTrace::safe_get_thread_name(thread),
-                                         object==NULL? "NULL" : java_lang_Class::as_Klass(object)->external_name()));
+                                         object==NULL? "NULL" : object->klass()->external_name()));
 
       JvmtiVMObjectAllocEventMark jem(thread, h());
       JvmtiJavaThreadEventTransition jet(thread);
--- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -1443,8 +1443,9 @@
     return JVMTI_ERROR_INTERNAL;
   }
 
-  // Update the version number of the constant pool
+  // Update the version number of the constant pools (may keep scratch_cp)
   merge_cp->increment_and_save_version(old_cp->version());
+  scratch_cp->increment_and_save_version(old_cp->version());
 
   ResourceMark rm(THREAD);
   _index_map_count = 0;
@@ -3911,6 +3912,11 @@
     method->set_constants(scratch_class->constants());
   }
 
+  // NOTE: this doesn't work because you can redefine the same class in two
+  // threads, each getting their own constant pool data appended to the
+  // original constant pool.  In order for the new methods to work when they
+  // become old methods, they need to keep their updated copy of the constant pool.
+
   {
     // walk all previous versions of the klass
     InstanceKlass *ik = (InstanceKlass *)the_class();
--- a/hotspot/src/share/vm/prims/nativeLookup.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/prims/nativeLookup.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -25,8 +25,8 @@
 #ifndef SHARE_VM_PRIMS_NATIVELOOKUP_HPP
 #define SHARE_VM_PRIMS_NATIVELOOKUP_HPP
 
+#include "memory/allocation.hpp"
 #include "runtime/handles.hpp"
-#include "utilities/top.hpp"
 
 // NativeLookup provides an interface for finding DLL entry points for
 // Java native functions.
--- a/hotspot/src/share/vm/prims/stackwalk.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/prims/stackwalk.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -37,22 +37,22 @@
 #include "utilities/globalDefinitions.hpp"
 
 // setup and cleanup actions
-void StackWalkAnchor::setup_magic_on_entry(objArrayHandle classes_array) {
-  classes_array->obj_at_put(magic_pos, _thread->threadObj());
+void StackWalkAnchor::setup_magic_on_entry(objArrayHandle frames_array) {
+  frames_array->obj_at_put(magic_pos, _thread->threadObj());
   _anchor = address_value();
-  assert(check_magic(classes_array), "invalid magic");
+  assert(check_magic(frames_array), "invalid magic");
 }
 
-bool StackWalkAnchor::check_magic(objArrayHandle classes_array) {
-  oop   m1 = classes_array->obj_at(magic_pos);
+bool StackWalkAnchor::check_magic(objArrayHandle frames_array) {
+  oop   m1 = frames_array->obj_at(magic_pos);
   jlong m2 = _anchor;
   if (m1 == _thread->threadObj() && m2 == address_value())  return true;
   return false;
 }
 
-bool StackWalkAnchor::cleanup_magic_on_exit(objArrayHandle classes_array) {
-  bool ok = check_magic(classes_array);
-  classes_array->obj_at_put(magic_pos, NULL);
+bool StackWalkAnchor::cleanup_magic_on_exit(objArrayHandle frames_array) {
+  bool ok = check_magic(frames_array);
+  frames_array->obj_at_put(magic_pos, NULL);
   _anchor = 0L;
   return ok;
 }
@@ -62,18 +62,18 @@
 // Parameters:
 //  thread         Current Java thread.
 //  magic          Magic value used for each stack walking
-//  classes_array  User-supplied buffers.  The 0th element is reserved
+//  frames_array   User-supplied buffers.  The 0th element is reserved
 //                 to this StackWalkAnchor to use
 //
 StackWalkAnchor* StackWalkAnchor::from_current(JavaThread* thread, jlong magic,
-                                               objArrayHandle classes_array)
+                                               objArrayHandle frames_array)
 {
   assert(thread != NULL && thread->is_Java_thread(), "");
-  oop m1 = classes_array->obj_at(magic_pos);
+  oop m1 = frames_array->obj_at(magic_pos);
   if (m1 != thread->threadObj())      return NULL;
   if (magic == 0L)                    return NULL;
   StackWalkAnchor* anchor = (StackWalkAnchor*) (intptr_t) magic;
-  if (!anchor->is_valid_in(thread, classes_array))   return NULL;
+  if (!anchor->is_valid_in(thread, frames_array))   return NULL;
   return anchor;
 }
 
@@ -88,24 +88,24 @@
 //   vfst           vFrameStream.
 //   max_nframes    Maximum number of frames to be filled.
 //   start_index    Start index to the user-supplied buffers.
-//   classes_array  Buffer to store classes in, starting at start_index.
-//   frames_array   Buffer to store StackFrame in, starting at start_index.
-//                  NULL if not used.
+//   frames_array   Buffer to store Class or StackFrame in, starting at start_index.
+//                  frames array is a Class<?>[] array when only getting caller
+//                  reference, and a StackFrameInfo[] array (or derivative)
+//                  otherwise. It should never be null.
 //   end_index      End index to the user-supplied buffers with unpacked frames.
 //
 // Returns the number of frames whose information was transferred into the buffers.
 //
 int StackWalk::fill_in_frames(jlong mode, vframeStream& vfst,
                               int max_nframes, int start_index,
-                              objArrayHandle  classes_array,
                               objArrayHandle  frames_array,
                               int& end_index, TRAPS) {
   if (TraceStackWalk) {
     tty->print_cr("fill_in_frames limit=%d start=%d frames length=%d",
-                  max_nframes, start_index, classes_array->length());
+                  max_nframes, start_index, frames_array->length());
   }
   assert(max_nframes > 0, "invalid max_nframes");
-  assert(start_index + max_nframes <= classes_array->length(), "oob");
+  assert(start_index + max_nframes <= frames_array->length(), "oob");
 
   int frames_decoded = 0;
   for (; !vfst.at_end(); vfst.next()) {
@@ -129,14 +129,18 @@
       tty->print_cr(" bci=%d", bci);
     }
 
-    classes_array->obj_at_put(index, method->method_holder()->java_mirror());
     // fill in StackFrameInfo and initialize MemberName
     if (live_frame_info(mode)) {
+      assert (use_frames_array(mode), "Bad mode for get live frame");
       Handle stackFrame(frames_array->obj_at(index));
       fill_live_stackframe(stackFrame, method, bci, vfst.java_frame(), CHECK_0);
     } else if (need_method_info(mode)) {
+      assert (use_frames_array(mode), "Bad mode for get stack frame");
       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");
+      frames_array->obj_at_put(index, method->method_holder()->java_mirror());
     }
     if (++frames_decoded >= max_nframes)  break;
   }
@@ -279,15 +283,15 @@
 //   skip_frames    Number of frames to be skipped.
 //   frame_count    Number of frames to be traversed.
 //   start_index    Start index to the user-supplied buffers.
-//   classes_array  Buffer to store classes in, starting at start_index.
 //   frames_array   Buffer to store StackFrame in, starting at start_index.
-//                  NULL if not used.
+//                  frames array is a Class<?>[] array when only getting caller
+//                  reference, and a StackFrameInfo[] array (or derivative)
+//                  otherwise. It should never be null.
 //
 // Returns Object returned from AbstractStackWalker::doStackWalk call.
 //
 oop StackWalk::walk(Handle stackStream, jlong mode,
                     int skip_frames, int frame_count, int start_index,
-                    objArrayHandle classes_array,
                     objArrayHandle frames_array,
                     TRAPS) {
   JavaThread* jt = (JavaThread*)THREAD;
@@ -296,10 +300,8 @@
                   mode, skip_frames, frame_count);
   }
 
-  if (need_method_info(mode)) {
-    if (frames_array.is_null()) {
-      THROW_MSG_(vmSymbols::java_lang_NullPointerException(), "frames_array is NULL", NULL);
-    }
+  if (frames_array.is_null()) {
+    THROW_MSG_(vmSymbols::java_lang_NullPointerException(), "frames_array is NULL", NULL);
   }
 
   Klass* stackWalker_klass = SystemDictionary::StackWalker_klass();
@@ -313,48 +315,17 @@
   vframeStream& vfst = anchor.vframe_stream();
 
   {
-    // Skip all methods from AbstractStackWalker and StackWalk (enclosing method)
-    if (!fill_in_stacktrace(mode)) {
-      while (!vfst.at_end()) {
-        InstanceKlass* ik = vfst.method()->method_holder();
-        if (ik != stackWalker_klass &&
-              ik != abstractStackWalker_klass && ik->super() != abstractStackWalker_klass)  {
-          break;
-        }
-
-        if (TraceStackWalk) {
-          tty->print("  skip "); vfst.method()->print_short_name(); tty->print("\n");
-        }
-        vfst.next();
+    while (!vfst.at_end()) {
+      InstanceKlass* ik = vfst.method()->method_holder();
+      if (ik != stackWalker_klass &&
+            ik != abstractStackWalker_klass && ik->super() != abstractStackWalker_klass)  {
+        break;
       }
-    }
 
-    // For exceptions, skip Throwable::fillInStackTrace and <init> methods
-    // of the exception class and superclasses
-    if (fill_in_stacktrace(mode)) {
-      bool skip_to_fillInStackTrace = false;
-      bool skip_throwableInit_check = false;
-      while (!vfst.at_end() && !skip_throwableInit_check) {
-        InstanceKlass* ik = vfst.method()->method_holder();
-        Method* method = vfst.method();
-        if (!skip_to_fillInStackTrace) {
-          if (ik == SystemDictionary::Throwable_klass() &&
-              method->name() == vmSymbols::fillInStackTrace_name()) {
-              // this frame will be skipped
-              skip_to_fillInStackTrace = true;
-          }
-        } else if (!(ik->is_subclass_of(SystemDictionary::Throwable_klass()) &&
-                     method->name() == vmSymbols::object_initializer_name())) {
-            // there are none or we've seen them all - either way stop checking
-            skip_throwableInit_check = true;
-            break;
-        }
-
-        if (TraceStackWalk) {
-          tty->print("stack walk: skip "); vfst.method()->print_short_name(); tty->print("\n");
-        }
-        vfst.next();
+      if (TraceStackWalk) {
+        tty->print("  skip "); vfst.method()->print_short_name(); tty->print("\n");
       }
+      vfst.next();
     }
 
     // stack frame has been traversed individually and resume stack walk
@@ -372,7 +343,7 @@
   int end_index = start_index;
   int numFrames = 0;
   if (!vfst.at_end()) {
-    numFrames = fill_in_frames(mode, vfst, frame_count, start_index, classes_array,
+    numFrames = fill_in_frames(mode, vfst, frame_count, start_index,
                                frames_array, end_index, CHECK_NULL);
     if (numFrames < 1) {
       THROW_MSG_(vmSymbols::java_lang_InternalError(), "stack walk: decode failed", NULL);
@@ -392,12 +363,12 @@
   args.push_int(end_index);
 
   // Link the thread and vframe stream into the callee-visible object
-  anchor.setup_magic_on_entry(classes_array);
+  anchor.setup_magic_on_entry(frames_array);
 
   JavaCalls::call(&result, m_doStackWalk, &args, THREAD);
 
   // Do this before anything else happens, to disable any lingering stream objects
-  bool ok = anchor.cleanup_magic_on_exit(classes_array);
+  bool ok = anchor.cleanup_magic_on_exit(frames_array);
 
   // Throw pending exception if we must
   (void) (CHECK_NULL);
@@ -419,31 +390,28 @@
 //   magic          Must be valid value to continue the stack walk
 //   frame_count    Number of frames to be decoded.
 //   start_index    Start index to the user-supplied buffers.
-//   classes_array  Buffer to store classes in, starting at start_index.
 //   frames_array   Buffer to store StackFrame in, starting at start_index.
-//                  NULL if not used.
 //
 // Returns the end index of frame filled in the buffer.
 //
 jint StackWalk::moreFrames(Handle stackStream, jlong mode, jlong magic,
                            int frame_count, int start_index,
-                           objArrayHandle classes_array,
                            objArrayHandle frames_array,
                            TRAPS)
 {
   JavaThread* jt = (JavaThread*)THREAD;
-  StackWalkAnchor* existing_anchor = StackWalkAnchor::from_current(jt, magic, classes_array);
+  StackWalkAnchor* existing_anchor = StackWalkAnchor::from_current(jt, magic, frames_array);
   if (existing_anchor == NULL) {
     THROW_MSG_(vmSymbols::java_lang_InternalError(), "doStackWalk: corrupted buffers", 0L);
   }
 
-  if ((need_method_info(mode) || live_frame_info(mode)) && frames_array.is_null()) {
+  if (frames_array.is_null()) {
     THROW_MSG_(vmSymbols::java_lang_NullPointerException(), "frames_array is NULL", 0L);
   }
 
   if (TraceStackWalk) {
     tty->print_cr("StackWalk::moreFrames frame_count %d existing_anchor " PTR_FORMAT " start %d frames %d",
-                  frame_count, p2i(existing_anchor), start_index, classes_array->length());
+                  frame_count, p2i(existing_anchor), start_index, frames_array->length());
   }
   int end_index = start_index;
   if (frame_count <= 0) {
@@ -451,14 +419,14 @@
   }
 
   int count = frame_count + start_index;
-  assert (classes_array->length() >= count, "not enough space in buffers");
+  assert (frames_array->length() >= count, "not enough space in buffers");
 
   StackWalkAnchor& anchor = (*existing_anchor);
   vframeStream& vfst = anchor.vframe_stream();
   if (!vfst.at_end()) {
     vfst.next();  // this was the last frame decoded in the previous batch
     if (!vfst.at_end()) {
-      int n = fill_in_frames(mode, vfst, frame_count, start_index, classes_array,
+      int n = fill_in_frames(mode, vfst, frame_count, start_index,
                              frames_array, end_index, CHECK_0);
       if (n < 1) {
         THROW_MSG_(vmSymbols::java_lang_InternalError(), "doStackWalk: later decode failed", 0L);
--- a/hotspot/src/share/vm/prims/stackwalk.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/prims/stackwalk.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -45,12 +45,12 @@
   vframeStream&   vframe_stream()         { return _vfst; }
   JavaThread*     thread()                { return _thread; }
 
-  void setup_magic_on_entry(objArrayHandle classes_array);
-  bool check_magic(objArrayHandle classes_array);
-  bool cleanup_magic_on_exit(objArrayHandle classes_array);
+  void setup_magic_on_entry(objArrayHandle frames_array);
+  bool check_magic(objArrayHandle frames_array);
+  bool cleanup_magic_on_exit(objArrayHandle frames_array);
 
-  bool is_valid_in(Thread* thread, objArrayHandle classes_array) {
-    return (_thread == thread && check_magic(classes_array));
+  bool is_valid_in(Thread* thread, objArrayHandle frames_array) {
+    return (_thread == thread && check_magic(frames_array));
   }
 
   jlong address_value() {
@@ -64,7 +64,6 @@
 private:
   static int fill_in_frames(jlong mode, vframeStream& vfst,
                             int max_nframes, int start_index,
-                            objArrayHandle classes_array,
                             objArrayHandle frames_array,
                             int& end_index, TRAPS);
 
@@ -82,20 +81,18 @@
   static inline bool live_frame_info(int mode) {
     return (mode & JVM_STACKWALK_FILL_LIVE_STACK_FRAMES) != 0;
   }
-  static inline bool fill_in_stacktrace(int mode) {
-    return (mode & JVM_STACKWALK_FILTER_FILL_IN_STACK_TRACE) != 0;
-  }
 
 public:
+  static inline bool use_frames_array(int mode) {
+    return (mode & JVM_STACKWALK_FILL_CLASS_REFS_ONLY) == 0;
+  }
   static oop walk(Handle stackStream, jlong mode,
                   int skip_frames, int frame_count, int start_index,
-                  objArrayHandle classes_array,
                   objArrayHandle frames_array,
                   TRAPS);
 
   static jint moreFrames(Handle stackStream, jlong mode, jlong magic,
                          int frame_count, int start_index,
-                         objArrayHandle classes_array,
                          objArrayHandle frames_array,
                          TRAPS);
 };
--- a/hotspot/src/share/vm/prims/unsafe.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/prims/unsafe.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -133,13 +133,22 @@
 
 ///// Data in the Java heap.
 
+#define truncate_jboolean(x) ((x) & 1)
+#define truncate_jbyte(x) (x)
+#define truncate_jshort(x) (x)
+#define truncate_jchar(x) (x)
+#define truncate_jint(x) (x)
+#define truncate_jlong(x) (x)
+#define truncate_jfloat(x) (x)
+#define truncate_jdouble(x) (x)
+
 #define GET_FIELD(obj, offset, type_name, v) \
   oop p = JNIHandles::resolve(obj); \
   type_name v = *(type_name*)index_oop_from_field_offset_long(p, offset)
 
 #define SET_FIELD(obj, offset, type_name, x) \
   oop p = JNIHandles::resolve(obj); \
-  *(type_name*)index_oop_from_field_offset_long(p, offset) = x
+  *(type_name*)index_oop_from_field_offset_long(p, offset) = truncate_##type_name(x)
 
 #define GET_FIELD_VOLATILE(obj, offset, type_name, v) \
   oop p = JNIHandles::resolve(obj); \
@@ -150,7 +159,7 @@
 
 #define SET_FIELD_VOLATILE(obj, offset, type_name, x) \
   oop p = JNIHandles::resolve(obj); \
-  OrderAccess::release_store_fence((volatile type_name*)index_oop_from_field_offset_long(p, offset), x);
+  OrderAccess::release_store_fence((volatile type_name*)index_oop_from_field_offset_long(p, offset), truncate_##type_name(x));
 
 
 // Get/SetObject must be special-cased, since it works with handles.
--- a/hotspot/src/share/vm/runtime/arguments.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/runtime/arguments.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -407,7 +407,9 @@
   { NULL, NULL}
 };
 
+// NOTE: A compatibility request will be necessary for each alias to be removed.
 static AliasedLoggingFlag const aliased_logging_flags[] = {
+  { "PrintCompressedOopsMode",   LogLevel::Info,  true,  LOG_TAGS(gc, heap, coops) },
   { "TraceBiasedLocking",        LogLevel::Info,  true,  LOG_TAGS(biasedlocking) },
   { "TraceClassLoading",         LogLevel::Info,  true,  LOG_TAGS(classload) },
   { "TraceClassLoadingPreorder", LogLevel::Debug, true,  LOG_TAGS(classload, preorder) },
@@ -696,7 +698,7 @@
   assert(total_len > 0, "empty sysclasspath not allowed");
 
   // Copy the _items to a single string.
-  char* cp = NEW_C_HEAP_ARRAY(char, total_len, mtInternal);
+  char* cp = NEW_C_HEAP_ARRAY(char, total_len, mtArguments);
   char* cp_tmp = cp;
   for (i = 0; i < _bcp_nitems; ++i) {
     if (_items[i] != NULL) {
@@ -717,7 +719,7 @@
   assert(str != NULL, "just checking");
   if (path == NULL) {
     size_t len = strlen(str) + 1;
-    cp = NEW_C_HEAP_ARRAY(char, len, mtInternal);
+    cp = NEW_C_HEAP_ARRAY(char, len, mtArguments);
     memcpy(cp, str, len);                       // copy the trailing null
   } else {
     const char separator = *os::path_separator();
@@ -726,7 +728,7 @@
     size_t len = old_len + str_len + 2;
 
     if (prepend) {
-      cp = NEW_C_HEAP_ARRAY(char, len, mtInternal);
+      cp = NEW_C_HEAP_ARRAY(char, len, mtArguments);
       char* cp_tmp = cp;
       memcpy(cp_tmp, str, str_len);
       cp_tmp += str_len;
@@ -734,7 +736,7 @@
       memcpy(++cp_tmp, path, old_len + 1);      // copy the trailing null
       FREE_C_HEAP_ARRAY(char, path);
     } else {
-      cp = REALLOC_C_HEAP_ARRAY(char, path, len, mtInternal);
+      cp = REALLOC_C_HEAP_ARRAY(char, path, len, mtArguments);
       char* cp_tmp = cp + old_len;
       *cp_tmp = separator;
       memcpy(++cp_tmp, str, str_len + 1);       // copy the trailing null
@@ -756,7 +758,7 @@
 
   /* Scan the directory for jars/zips, appending them to path. */
   struct dirent *entry;
-  char *dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(directory), mtInternal);
+  char *dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(directory), mtArguments);
   while ((entry = os::readdir(dir, (dirent *) dbuf)) != NULL) {
     const char* name = entry->d_name;
     const char* ext = name + strlen(name) - 4;
@@ -764,7 +766,7 @@
       (os::file_name_strcmp(ext, ".jar") == 0 ||
        os::file_name_strcmp(ext, ".zip") == 0);
     if (isJarOrZip) {
-      char* jarpath = NEW_C_HEAP_ARRAY(char, directory_len + 2 + strlen(name), mtInternal);
+      char* jarpath = NEW_C_HEAP_ARRAY(char, directory_len + 2 + strlen(name), mtArguments);
       sprintf(jarpath, "%s%s%s", directory, dir_sep, name);
       path = add_to_path(path, jarpath, false);
       FREE_C_HEAP_ARRAY(char, jarpath);
@@ -941,7 +943,7 @@
   } else if (new_len == 0) {
     value = old_value;
   } else {
-    char* buf = NEW_C_HEAP_ARRAY(char, old_len + 1 + new_len + 1, mtInternal);
+    char* buf = NEW_C_HEAP_ARRAY(char, old_len + 1 + new_len + 1, mtArguments);
     // each new setting adds another LINE to the switch:
     sprintf(buf, "%s\n%s", old_value, new_value);
     value = buf;
@@ -1132,9 +1134,9 @@
 
   // expand the array and add arg to the last element
   if (*bldarray == NULL) {
-    *bldarray = NEW_C_HEAP_ARRAY(char*, new_count, mtInternal);
+    *bldarray = NEW_C_HEAP_ARRAY(char*, new_count, mtArguments);
   } else {
-    *bldarray = REALLOC_C_HEAP_ARRAY(char*, *bldarray, new_count, mtInternal);
+    *bldarray = REALLOC_C_HEAP_ARRAY(char*, *bldarray, new_count, mtArguments);
   }
   (*bldarray)[*count] = os::strdup_check_oom(arg);
   *count = new_count;
@@ -1398,7 +1400,7 @@
     // property have a value, thus extract it and save to the
     // allocated string
     size_t key_len = eq - prop;
-    char* tmp_key = AllocateHeap(key_len + 1, mtInternal);
+    char* tmp_key = AllocateHeap(key_len + 1, mtArguments);
 
     strncpy(tmp_key, prop, key_len);
     tmp_key[key_len] = '\0';
@@ -1420,7 +1422,7 @@
   } else {
     if (strcmp(key, "sun.java.command") == 0) {
       char *old_java_command = _java_command;
-      _java_command = os::strdup_check_oom(value, mtInternal);
+      _java_command = os::strdup_check_oom(value, mtArguments);
       if (old_java_command != NULL) {
         os::free(old_java_command);
       }
@@ -1428,7 +1430,7 @@
       const char* old_java_vendor_url_bug = _java_vendor_url_bug;
       // save it in _java_vendor_url_bug, so JVM fatal error handler can access
       // its value without going through the property list or making a Java call.
-      _java_vendor_url_bug = os::strdup_check_oom(value, mtInternal);
+      _java_vendor_url_bug = os::strdup_check_oom(value, mtArguments);
       if (old_java_vendor_url_bug != DEFAULT_VENDOR_URL_BUG) {
         assert(old_java_vendor_url_bug != NULL, "_java_vendor_url_bug is NULL");
         os::free((void *)old_java_vendor_url_bug);
@@ -1456,7 +1458,7 @@
   if (old_value != NULL) {
     buf_len += strlen(old_value) + 1;
   }
-  char* new_value = AllocateHeap(buf_len, mtInternal);
+  char* new_value = AllocateHeap(buf_len, mtArguments);
   if (new_value == NULL) {
     return false;
   }
@@ -2093,8 +2095,8 @@
   }
 
 #if INCLUDE_ALL_GCS
-  if (G1ConcRefinementThreads == 0) {
-    FLAG_SET_DEFAULT(G1ConcRefinementThreads, ParallelGCThreads);
+  if (FLAG_IS_DEFAULT(G1ConcRefinementThreads)) {
+    FLAG_SET_ERGO(uint, G1ConcRefinementThreads, ParallelGCThreads);
   }
 #endif
 
@@ -2184,15 +2186,11 @@
       if (!FLAG_IS_DEFAULT(HeapBaseMinAddress)) {
         if (HeapBaseMinAddress < DefaultHeapBaseMinAddress) {
           // matches compressed oops printing flags
-          if (PrintCompressedOopsMode || (PrintMiscellaneous && Verbose)) {
-            jio_fprintf(defaultStream::error_stream(),
-                        "HeapBaseMinAddress must be at least " SIZE_FORMAT
-                        " (" SIZE_FORMAT "G) which is greater than value given "
-                        SIZE_FORMAT "\n",
-                        DefaultHeapBaseMinAddress,
-                        DefaultHeapBaseMinAddress/G,
-                        HeapBaseMinAddress);
-          }
+          log_debug(gc, heap, coops)("HeapBaseMinAddress must be at least " SIZE_FORMAT
+                                     " (" SIZE_FORMAT "G) which is greater than value given " SIZE_FORMAT,
+                                     DefaultHeapBaseMinAddress,
+                                     DefaultHeapBaseMinAddress/G,
+                                     HeapBaseMinAddress);
           FLAG_SET_ERGO(size_t, HeapBaseMinAddress, DefaultHeapBaseMinAddress);
         }
       }
@@ -2854,13 +2852,13 @@
       if (tail != NULL) {
         const char* pos = strchr(tail, ':');
         size_t len = (pos == NULL) ? strlen(tail) : pos - tail;
-        char* name = (char*)memcpy(NEW_C_HEAP_ARRAY(char, len + 1, mtInternal), tail, len);
+        char* name = (char*)memcpy(NEW_C_HEAP_ARRAY(char, len + 1, mtArguments), tail, len);
         name[len] = '\0';
 
         char *options = NULL;
         if(pos != NULL) {
           size_t len2 = strlen(pos+1) + 1; // options start after ':'.  Final zero must be copied.
-          options = (char*)memcpy(NEW_C_HEAP_ARRAY(char, len2, mtInternal), pos+1, len2);
+          options = (char*)memcpy(NEW_C_HEAP_ARRAY(char, len2, mtArguments), pos+1, len2);
         }
 #if !INCLUDE_JVMTI
         if (strcmp(name, "jdwp") == 0) {
@@ -2877,12 +2875,12 @@
       if(tail != NULL) {
         const char* pos = strchr(tail, '=');
         size_t len = (pos == NULL) ? strlen(tail) : pos - tail;
-        char* name = strncpy(NEW_C_HEAP_ARRAY(char, len + 1, mtInternal), tail, len);
+        char* name = strncpy(NEW_C_HEAP_ARRAY(char, len + 1, mtArguments), tail, len);
         name[len] = '\0';
 
         char *options = NULL;
         if(pos != NULL) {
-          options = os::strdup_check_oom(pos + 1, mtInternal);
+          options = os::strdup_check_oom(pos + 1, mtArguments);
         }
 #if !INCLUDE_JVMTI
         if (valid_jdwp_agent(name, is_absolute_path)) {
@@ -2901,7 +2899,7 @@
       return JNI_ERR;
 #else
       if (tail != NULL) {
-        char *options = strcpy(NEW_C_HEAP_ARRAY(char, strlen(tail) + 1, mtInternal), tail);
+        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. Also -addmods ALL-SYSTEM because
         // the java agent is in the unmamed module of the application class loader
@@ -3203,7 +3201,7 @@
             size_t len = strlen(patch_dirs[x]);
             if (len != 0) { // Ignore empty strings.
               len += 11; // file_sep + "java.base" + null terminator.
-              char* dir = NEW_C_HEAP_ARRAY(char, len, mtInternal);
+              char* dir = NEW_C_HEAP_ARRAY(char, len, mtArguments);
               jio_snprintf(dir, len, "%s%cjava.base", patch_dirs[x], file_sep);
 
               // See if Xpatch module path exists.
@@ -3509,7 +3507,7 @@
       src ++;
     }
 
-    char* copy = os::strdup_check_oom(src, mtInternal);
+    char* copy = os::strdup_check_oom(src, mtArguments);
 
     // trim all trailing empty paths
     for (char* tail = copy + strlen(copy) - 1; tail >= copy && *tail == separator; tail--) {
@@ -3533,7 +3531,7 @@
   if (dir == NULL) return false;
 
   struct dirent *entry;
-  char *dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(directory), mtInternal);
+  char *dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(directory), mtArguments);
   bool hasJarFile = false;
   while (!hasJarFile && (entry = os::readdir(dir, (dirent *) dbuf)) != NULL) {
     const char* name = entry->d_name;
@@ -3559,7 +3557,7 @@
       }
       path = end;
     } else {
-      char* dirpath = NEW_C_HEAP_ARRAY(char, tmp_end - path + 1, mtInternal);
+      char* dirpath = NEW_C_HEAP_ARRAY(char, tmp_end - path + 1, mtArguments);
       memcpy(dirpath, path, tmp_end - path);
       dirpath[tmp_end - path] = '\0';
       if (has_jar_files(dirpath)) {
@@ -3731,7 +3729,7 @@
   jint set_args(GrowableArray<JavaVMOption>* options) {
     _is_set = true;
     JavaVMOption* options_arr = NEW_C_HEAP_ARRAY_RETURN_NULL(
-        JavaVMOption, options->length(), mtInternal);
+        JavaVMOption, options->length(), mtArguments);
     if (options_arr == NULL) {
       return JNI_ENOMEM;
     }
@@ -3786,7 +3784,7 @@
     assert(vm_options_file_pos != -1, "vm_options_file_pos should be set");
 
     int length = args->nOptions + args_to_insert->nOptions - 1;
-    GrowableArray<JavaVMOption> *options = new (ResourceObj::C_HEAP, mtInternal)
+    GrowableArray<JavaVMOption> *options = new (ResourceObj::C_HEAP, mtArguments)
               GrowableArray<JavaVMOption>(length, true);    // Construct new option array
     for (int i = 0; i < args->nOptions; i++) {
       if (i == vm_options_file_pos) {
@@ -3863,7 +3861,7 @@
   // '+ 1' for NULL termination even with max bytes
   size_t bytes_alloc = stbuf.st_size + 1;
 
-  char *buf = NEW_C_HEAP_ARRAY_RETURN_NULL(char, bytes_alloc, mtInternal);
+  char *buf = NEW_C_HEAP_ARRAY_RETURN_NULL(char, bytes_alloc, mtArguments);
   if (NULL == buf) {
     jio_fprintf(defaultStream::error_stream(),
                 "Could not allocate read buffer for options file parse\n");
@@ -3900,7 +3898,7 @@
 }
 
 jint Arguments::parse_options_buffer(const char* name, char* buffer, const size_t buf_len, ScopedVMInitArgs* vm_args) {
-  GrowableArray<JavaVMOption> *options = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<JavaVMOption>(2, true);    // Construct option array
+  GrowableArray<JavaVMOption> *options = new (ResourceObj::C_HEAP, mtArguments) GrowableArray<JavaVMOption>(2, true);    // Construct option array
 
   // some pointers to help with parsing
   char *buffer_end = buffer + buf_len;
@@ -4004,13 +4002,13 @@
     size_t jvm_path_len = strlen(jvm_path);
     size_t file_sep_len = strlen(os::file_separator());
     const size_t len = jvm_path_len + file_sep_len + 20;
-    shared_archive_path = NEW_C_HEAP_ARRAY(char, len, mtInternal);
+    shared_archive_path = NEW_C_HEAP_ARRAY(char, len, mtArguments);
     if (shared_archive_path != NULL) {
       jio_snprintf(shared_archive_path, len, "%s%sclasses.jsa",
         jvm_path, os::file_separator());
     }
   } else {
-    shared_archive_path = os::strdup_check_oom(SharedArchiveFile, mtInternal);
+    shared_archive_path = os::strdup_check_oom(SharedArchiveFile, mtArguments);
   }
   return shared_archive_path;
 }
--- a/hotspot/src/share/vm/runtime/arguments.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/runtime/arguments.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -31,7 +31,6 @@
 #include "runtime/os.hpp"
 #include "runtime/perfData.hpp"
 #include "utilities/debug.hpp"
-#include "utilities/top.hpp"
 
 // Arguments parses the command line and recognizes options
 
@@ -48,7 +47,7 @@
 // PathString is used as the underlying value container for a
 // SystemProperty and for the string that represents the system
 // boot class path, Arguments::_system_boot_class_path.
-class PathString : public CHeapObj<mtInternal> {
+class PathString : public CHeapObj<mtArguments> {
  protected:
   char*           _value;
  public:
@@ -58,7 +57,7 @@
     if (_value != NULL) {
       FreeHeap(_value);
     }
-    _value = AllocateHeap(strlen(value)+1, mtInternal);
+    _value = AllocateHeap(strlen(value)+1, mtArguments);
     assert(_value != NULL, "Unable to allocate space for new path value");
     if (_value != NULL) {
       strcpy(_value, value);
@@ -77,7 +76,7 @@
       if (_value != NULL) {
         len += strlen(_value);
       }
-      sp = AllocateHeap(len+2, mtInternal);
+      sp = AllocateHeap(len+2, mtArguments);
       assert(sp != NULL, "Unable to allocate space for new append path value");
       if (sp != NULL) {
         if (_value != NULL) {
@@ -98,7 +97,7 @@
     if (value == NULL) {
       _value = NULL;
     } else {
-      _value = AllocateHeap(strlen(value)+1, mtInternal);
+      _value = AllocateHeap(strlen(value)+1, mtArguments);
       strcpy(_value, value);
     }
   }
@@ -144,7 +143,7 @@
     if (key == NULL) {
       _key = NULL;
     } else {
-      _key = AllocateHeap(strlen(key)+1, mtInternal);
+      _key = AllocateHeap(strlen(key)+1, mtArguments);
       strcpy(_key, key);
     }
     _next = NULL;
@@ -155,7 +154,7 @@
 
 
 // For use by -agentlib, -agentpath and -Xrun
-class AgentLibrary : public CHeapObj<mtInternal> {
+class AgentLibrary : public CHeapObj<mtArguments> {
   friend class AgentLibraryList;
 public:
   // Is this library valid or not. Don't rely on os_lib == NULL as statically
@@ -190,12 +189,12 @@
 
   // Constructor
   AgentLibrary(const char* name, const char* options, bool is_absolute_path, void* os_lib) {
-    _name = AllocateHeap(strlen(name)+1, mtInternal);
+    _name = AllocateHeap(strlen(name)+1, mtArguments);
     strcpy(_name, name);
     if (options == NULL) {
       _options = NULL;
     } else {
-      _options = AllocateHeap(strlen(options)+1, mtInternal);
+      _options = AllocateHeap(strlen(options)+1, mtArguments);
       strcpy(_options, options);
     }
     _is_absolute_path = is_absolute_path;
--- a/hotspot/src/share/vm/runtime/basicLock.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/runtime/basicLock.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -27,7 +27,6 @@
 
 #include "oops/markOop.hpp"
 #include "runtime/handles.hpp"
-#include "utilities/top.hpp"
 
 class BasicLock VALUE_OBJ_CLASS_SPEC {
   friend class VMStructs;
--- a/hotspot/src/share/vm/runtime/commandLineFlagConstraintList.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/runtime/commandLineFlagConstraintList.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -226,7 +226,7 @@
 
 // Check the ranges of all flags that have them or print them out and exit if requested
 void CommandLineFlagConstraintList::init(void) {
-  _constraints = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<CommandLineFlagConstraint*>(INITIAL_CONSTRAINTS_SIZE, true);
+  _constraints = new (ResourceObj::C_HEAP, mtArguments) GrowableArray<CommandLineFlagConstraint*>(INITIAL_CONSTRAINTS_SIZE, true);
 
   emit_constraint_no(NULL RUNTIME_FLAGS(EMIT_CONSTRAINT_DEVELOPER_FLAG,
                                         EMIT_CONSTRAINT_PD_DEVELOPER_FLAG,
--- a/hotspot/src/share/vm/runtime/commandLineFlagConstraintList.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/runtime/commandLineFlagConstraintList.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -48,7 +48,7 @@
 typedef Flag::Error (*CommandLineFlagConstraintFunc_size_t)(size_t value, bool verbose);
 typedef Flag::Error (*CommandLineFlagConstraintFunc_double)(double value, bool verbose);
 
-class CommandLineFlagConstraint : public CHeapObj<mtInternal> {
+class CommandLineFlagConstraint : public CHeapObj<mtArguments> {
 public:
   // During VM initialization, constraint validation will be done order of ConstraintType.
   enum ConstraintType {
--- a/hotspot/src/share/vm/runtime/commandLineFlagConstraintsGC.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/runtime/commandLineFlagConstraintsGC.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -457,6 +457,51 @@
   }
 }
 
+static Flag::Error CMSReservedAreaConstraintFunc(const char* name, size_t value, bool verbose) {
+#if INCLUDE_ALL_GCS
+  if (UseConcMarkSweepGC) {
+    ConcurrentMarkSweepGeneration* cms = (ConcurrentMarkSweepGeneration*)GenCollectedHeap::heap()->old_gen();
+    const size_t ergo_max = cms->cmsSpace()->max_flag_size_for_task_size();
+    if (value > ergo_max) {
+      CommandLineError::print(verbose,
+                              "%s (" SIZE_FORMAT ") must be "
+                              "less than or equal to ergonomic maximum (" SIZE_FORMAT ") "
+                              "which is based on the maximum size of the old generation of the Java heap\n",
+                              name, value, ergo_max);
+      return Flag::VIOLATES_CONSTRAINT;
+    }
+  }
+#endif
+
+  return Flag::SUCCESS;
+}
+
+Flag::Error CMSRescanMultipleConstraintFunc(size_t value, bool verbose) {
+  Flag::Error status = CMSReservedAreaConstraintFunc("CMSRescanMultiple", value, verbose);
+
+#if INCLUDE_ALL_GCS
+  if (status == Flag::SUCCESS && UseConcMarkSweepGC) {
+    // CMSParRemarkTask::do_dirty_card_rescan_tasks requires CompactibleFreeListSpace::rescan_task_size()
+    // to be aligned to CardTableModRefBS::card_size * BitsPerWord.
+    // Note that rescan_task_size() will be aligned if CMSRescanMultiple is a multiple of 'HeapWordSize'
+    // because rescan_task_size() is CardTableModRefBS::card_size / HeapWordSize * BitsPerWord.
+    if (value % HeapWordSize != 0) {
+      CommandLineError::print(verbose,
+                              "CMSRescanMultiple (" SIZE_FORMAT ") must be "
+                              "a multiple of " SIZE_FORMAT "\n",
+                              value, HeapWordSize);
+      status = Flag::VIOLATES_CONSTRAINT;
+    }
+  }
+#endif
+
+  return status;
+}
+
+Flag::Error CMSConcMarkMultipleConstraintFunc(size_t value, bool verbose) {
+  return CMSReservedAreaConstraintFunc("CMSConcMarkMultiple", value, verbose);
+}
+
 Flag::Error CMSPrecleanDenominatorConstraintFunc(uintx value, bool verbose) {
 #if INCLUDE_ALL_GCS
   if (UseConcMarkSweepGC && (value <= CMSPrecleanNumerator)) {
--- a/hotspot/src/share/vm/runtime/commandLineFlagConstraintsGC.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/runtime/commandLineFlagConstraintsGC.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -60,6 +60,8 @@
 Flag::Error CMSOldPLABMinConstraintFunc(size_t value, bool verbose);
 Flag::Error CMSOldPLABMaxConstraintFunc(size_t value, bool verbose);
 Flag::Error MarkStackSizeConstraintFunc(size_t value, bool verbose);
+Flag::Error CMSRescanMultipleConstraintFunc(size_t value, bool verbose);
+Flag::Error CMSConcMarkMultipleConstraintFunc(size_t value, bool verbose);
 Flag::Error CMSPrecleanDenominatorConstraintFunc(uintx value, bool verbose);
 Flag::Error CMSPrecleanNumeratorConstraintFunc(uintx value, bool verbose);
 Flag::Error CMSSamplingGrainConstraintFunc(uintx value, bool verbose);
--- a/hotspot/src/share/vm/runtime/commandLineFlagRangeList.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/runtime/commandLineFlagRangeList.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -292,7 +292,7 @@
 // Check the ranges of all flags that have them
 void CommandLineFlagRangeList::init(void) {
 
-  _ranges = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<CommandLineFlagRange*>(INITIAL_RANGES_SIZE, true);
+  _ranges = new (ResourceObj::C_HEAP, mtArguments) GrowableArray<CommandLineFlagRange*>(INITIAL_RANGES_SIZE, true);
 
   emit_range_no(NULL RUNTIME_FLAGS(EMIT_RANGE_DEVELOPER_FLAG,
                                    EMIT_RANGE_PD_DEVELOPER_FLAG,
--- a/hotspot/src/share/vm/runtime/commandLineFlagRangeList.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/runtime/commandLineFlagRangeList.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -44,7 +44,7 @@
   static void print(bool verbose, const char* msg, ...);
 };
 
-class CommandLineFlagRange : public CHeapObj<mtInternal> {
+class CommandLineFlagRange : public CHeapObj<mtArguments> {
 private:
   const char* _name;
 public:
--- a/hotspot/src/share/vm/runtime/deoptimization.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/runtime/deoptimization.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -896,13 +896,25 @@
       break;
     }
 
-    case T_SHORT: case T_CHAR: // 2 bytes
+    case T_SHORT:
       assert(value->type() == T_INT, "Agreement.");
       val = value->get_int();
       obj->short_at_put(index, (jshort)*((jint*)&val));
       break;
 
-    case T_BOOLEAN: case T_BYTE: // 1 byte
+    case T_CHAR:
+      assert(value->type() == T_INT, "Agreement.");
+      val = value->get_int();
+      obj->char_at_put(index, (jchar)*((jint*)&val));
+      break;
+
+    case T_BYTE:
+      assert(value->type() == T_INT, "Agreement.");
+      val = value->get_int();
+      obj->byte_at_put(index, (jbyte)*((jint*)&val));
+      break;
+
+    case T_BOOLEAN:
       assert(value->type() == T_INT, "Agreement.");
       val = value->get_int();
       obj->bool_at_put(index, (jboolean)*((jint*)&val));
@@ -1017,13 +1029,25 @@
         break;
       }
 
-      case T_SHORT: case T_CHAR: // 2 bytes
+      case T_SHORT:
         assert(value->type() == T_INT, "Agreement.");
         val = value->get_int();
         obj->short_field_put(offset, (jshort)*((jint*)&val));
         break;
 
-      case T_BOOLEAN: case T_BYTE: // 1 byte
+      case T_CHAR:
+        assert(value->type() == T_INT, "Agreement.");
+        val = value->get_int();
+        obj->char_field_put(offset, (jchar)*((jint*)&val));
+        break;
+
+      case T_BYTE:
+        assert(value->type() == T_INT, "Agreement.");
+        val = value->get_int();
+        obj->byte_field_put(offset, (jbyte)*((jint*)&val));
+        break;
+
+      case T_BOOLEAN:
         assert(value->type() == T_INT, "Agreement.");
         val = value->get_int();
         obj->bool_field_put(offset, (jboolean)*((jint*)&val));
--- a/hotspot/src/share/vm/runtime/frame.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/runtime/frame.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -29,7 +29,6 @@
 #include "runtime/basicLock.hpp"
 #include "runtime/monitorChunk.hpp"
 #include "runtime/registerMap.hpp"
-#include "utilities/top.hpp"
 #ifdef TARGET_ARCH_zero
 # include "stack_zero.hpp"
 #endif
--- a/hotspot/src/share/vm/runtime/globals.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/runtime/globals.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -35,7 +35,6 @@
 #include "trace/tracing.hpp"
 #include "utilities/macros.hpp"
 #include "utilities/ostream.hpp"
-#include "utilities/top.hpp"
 #if INCLUDE_ALL_GCS
 #include "gc/g1/g1_globals.hpp"
 #endif // INCLUDE_ALL_GCS
@@ -1293,7 +1292,7 @@
   const size_t length = Flag::numFlags - 1;
 
   // Sort
-  Flag** array = NEW_C_HEAP_ARRAY(Flag*, length, mtInternal);
+  Flag** array = NEW_C_HEAP_ARRAY(Flag*, length, mtArguments);
   for (size_t i = 0; i < length; i++) {
     array[i] = &flagTable[i];
   }
@@ -1327,7 +1326,7 @@
   const size_t length = Flag::numFlags - 1;
 
   // Sort
-  Flag** array = NEW_C_HEAP_ARRAY(Flag*, length, mtInternal);
+  Flag** array = NEW_C_HEAP_ARRAY(Flag*, length, mtArguments);
   for (size_t i = 0; i < length; i++) {
     array[i] = &flagTable[i];
   }
--- a/hotspot/src/share/vm/runtime/globals.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/runtime/globals.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -641,9 +641,6 @@
           "region.")                                                        \
           range(1, max_uintx)                                               \
                                                                             \
-  diagnostic(bool, PrintCompressedOopsMode, false,                          \
-          "Print compressed oops base address and encoding mode")           \
-                                                                            \
   lp64_product(intx, ObjectAlignmentInBytes, 8,                             \
           "Default object alignment in bytes, 8 is minimum")                \
           range(8, 256)                                                     \
@@ -688,9 +685,6 @@
           "Use large page memory in metaspace. "                            \
           "Only used if UseLargePages is enabled.")                         \
                                                                             \
-  develop(bool, TracePageSizes, false,                                      \
-          "Trace page size selection and usage")                            \
-                                                                            \
   product(bool, UseNUMA, false,                                             \
           "Use NUMA if available")                                          \
                                                                             \
@@ -1809,13 +1803,17 @@
           "enough work per iteration")                                      \
           range(0, max_intx)                                                \
                                                                             \
+  /* 4096 = CardTableModRefBS::card_size_in_words * BitsPerWord */          \
   product(size_t, CMSRescanMultiple, 32,                                    \
           "Size (in cards) of CMS parallel rescan task")                    \
-          range(1, max_uintx)                                               \
-                                                                            \
+          range(1, SIZE_MAX / 4096)                                         \
+          constraint(CMSRescanMultipleConstraintFunc,AfterMemoryInit)       \
+                                                                            \
+  /* 4096 = CardTableModRefBS::card_size_in_words * BitsPerWord */          \
   product(size_t, CMSConcMarkMultiple, 32,                                  \
           "Size (in cards) of CMS concurrent MT marking task")              \
-          range(1, max_uintx)                                               \
+          range(1, SIZE_MAX / 4096)                                         \
+          constraint(CMSConcMarkMultipleConstraintFunc,AfterMemoryInit)     \
                                                                             \
   product(bool, CMSAbortSemantics, false,                                   \
           "Whether abort-on-overflow semantics is implemented")             \
@@ -2954,9 +2952,6 @@
   develop(bool, TraceStackWalk, false,                                      \
           "Trace stack walking")                                            \
                                                                             \
-  product(bool, MemberNameInStackFrame, true,                               \
-          "Use MemberName in StackFrame")                                   \
-                                                                            \
   /* notice: the max range value here is max_jint, not max_intx  */         \
   /* because of overflow issue                                   */         \
   NOT_EMBEDDED(diagnostic(intx, GuaranteedSafepointInterval, 1000,          \
--- a/hotspot/src/share/vm/runtime/globals_extension.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/runtime/globals_extension.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -27,7 +27,19 @@
 
 #include "runtime/globals.hpp"
 #include "utilities/macros.hpp"
-#include "utilities/top.hpp"
+#include "utilities/macros.hpp"
+#if INCLUDE_ALL_GCS
+#include "gc/g1/g1_globals.hpp"
+#endif
+#if INCLUDE_JVMCI
+#include "jvmci/jvmci_globals.hpp"
+#endif
+#ifdef COMPILER1
+#include "c1/c1_globals.hpp"
+#endif
+#ifdef COMPILER2
+#include "opto/c2_globals.hpp"
+#endif
 
 // Construct enum of Flag_<cmdline-arg> constants.
 
--- a/hotspot/src/share/vm/runtime/init.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/runtime/init.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -25,7 +25,7 @@
 #ifndef SHARE_VM_RUNTIME_INIT_HPP
 #define SHARE_VM_RUNTIME_INIT_HPP
 
-#include "utilities/top.hpp"
+#include "utilities/globalDefinitions.hpp"
 
 // init_globals replaces C++ global objects so we can use the standard linker
 // to link Delta (which is at least twice as fast as using the GNU C++ linker).
--- a/hotspot/src/share/vm/runtime/interfaceSupport.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/runtime/interfaceSupport.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -35,7 +35,6 @@
 #include "runtime/vmThread.hpp"
 #include "utilities/globalDefinitions.hpp"
 #include "utilities/preserveException.hpp"
-#include "utilities/top.hpp"
 
 // Wrapper for all entry points to the virtual machine.
 // The HandleMarkCleaner is a faster version of HandleMark.
--- a/hotspot/src/share/vm/runtime/javaCalls.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/runtime/javaCalls.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -29,7 +29,7 @@
 #include "oops/method.hpp"
 #include "runtime/handles.hpp"
 #include "runtime/javaFrameAnchor.hpp"
-#include "runtime/thread.inline.hpp"
+#include "runtime/thread.hpp"
 #include "runtime/vmThread.hpp"
 #ifdef TARGET_ARCH_x86
 # include "jniTypes_x86.hpp"
--- a/hotspot/src/share/vm/runtime/jniHandles.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/runtime/jniHandles.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -25,8 +25,8 @@
 #ifndef SHARE_VM_RUNTIME_JNIHANDLES_HPP
 #define SHARE_VM_RUNTIME_JNIHANDLES_HPP
 
+#include "memory/allocation.hpp"
 #include "runtime/handles.hpp"
-#include "utilities/top.hpp"
 
 class JNIHandleBlock;
 
--- a/hotspot/src/share/vm/runtime/os.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/runtime/os.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -33,6 +33,7 @@
 #include "gc/shared/vmGCOperations.hpp"
 #include "interpreter/interpreter.hpp"
 #include "logging/log.hpp"
+#include "logging/logStream.inline.hpp"
 #include "memory/allocation.inline.hpp"
 #ifdef ASSERT
 #include "memory/guardedMemory.hpp"
@@ -1494,31 +1495,63 @@
   return errno_to_string(e, true);
 }
 
-#ifndef PRODUCT
-void os::trace_page_sizes(const char* str, const size_t* page_sizes, int count)
-{
-  if (TracePageSizes) {
-    tty->print("%s: ", str);
+void os::trace_page_sizes(const char* str, const size_t* page_sizes, int count) {
+  LogTarget(Info, pagesize) log;
+  if (log.is_enabled()) {
+    LogStreamCHeap out(log);
+
+    out.print("%s: ", str);
     for (int i = 0; i < count; ++i) {
-      tty->print(" " SIZE_FORMAT, page_sizes[i]);
+      out.print(" " SIZE_FORMAT, page_sizes[i]);
     }
-    tty->cr();
+    out.cr();
   }
 }
 
-void os::trace_page_sizes(const char* str, const size_t region_min_size,
-                          const size_t region_max_size, const size_t page_size,
-                          const char* base, const size_t size)
-{
-  if (TracePageSizes) {
-    tty->print_cr("%s:  min=" SIZE_FORMAT " max=" SIZE_FORMAT
-                  " pg_sz=" SIZE_FORMAT " base=" PTR_FORMAT
-                  " size=" SIZE_FORMAT,
-                  str, region_min_size, region_max_size,
-                  page_size, p2i(base), size);
-  }
+#define trace_page_size_params(size) byte_size_in_exact_unit(size), exact_unit_for_byte_size(size)
+
+void os::trace_page_sizes(const char* str,
+                          const size_t region_min_size,
+                          const size_t region_max_size,
+                          const size_t page_size,
+                          const char* base,
+                          const size_t size) {
+
+  log_info(pagesize)("%s: "
+                     " min=" SIZE_FORMAT "%s"
+                     " max=" SIZE_FORMAT "%s"
+                     " base=" PTR_FORMAT
+                     " page_size=" SIZE_FORMAT "%s"
+                     " size=" SIZE_FORMAT "%s",
+                     str,
+                     trace_page_size_params(region_min_size),
+                     trace_page_size_params(region_max_size),
+                     p2i(base),
+                     trace_page_size_params(page_size),
+                     trace_page_size_params(size));
 }
-#endif  // #ifndef PRODUCT
+
+void os::trace_page_sizes_for_requested_size(const char* str,
+                                             const size_t requested_size,
+                                             const size_t page_size,
+                                             const size_t alignment,
+                                             const char* base,
+                                             const size_t size) {
+
+  log_info(pagesize)("%s:"
+                     " req_size=" SIZE_FORMAT "%s"
+                     " base=" PTR_FORMAT
+                     " page_size=" SIZE_FORMAT "%s"
+                     " alignment=" SIZE_FORMAT "%s"
+                     " size=" SIZE_FORMAT "%s",
+                     str,
+                     trace_page_size_params(requested_size),
+                     p2i(base),
+                     trace_page_size_params(page_size),
+                     trace_page_size_params(alignment),
+                     trace_page_size_params(size));
+}
+
 
 // This is the working definition of a server class machine:
 // >= 2 physical CPU's and >=2GB of memory, with some fuzz
--- a/hotspot/src/share/vm/runtime/os.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/runtime/os.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -28,7 +28,6 @@
 #include "jvmtifiles/jvmti.h"
 #include "runtime/extendedPC.hpp"
 #include "runtime/handles.hpp"
-#include "utilities/top.hpp"
 #ifdef TARGET_OS_FAMILY_linux
 # include "jvm_linux.h"
 # include <setjmp.h>
@@ -286,18 +285,24 @@
     return _page_sizes[0];
   }
 
-  // Methods for tracing page sizes returned by the above method; enabled by
-  // TracePageSizes.  The region_{min,max}_size parameters should be the values
+  // Methods for tracing page sizes returned by the above method.
+  // The region_{min,max}_size parameters should be the values
   // passed to page_size_for_region() and page_size should be the result of that
   // call.  The (optional) base and size parameters should come from the
   // ReservedSpace base() and size() methods.
-  static void trace_page_sizes(const char* str, const size_t* page_sizes,
-                               int count) PRODUCT_RETURN;
-  static void trace_page_sizes(const char* str, const size_t region_min_size,
+  static void trace_page_sizes(const char* str, const size_t* page_sizes, int count);
+  static void trace_page_sizes(const char* str,
+                               const size_t region_min_size,
                                const size_t region_max_size,
                                const size_t page_size,
-                               const char* base = NULL,
-                               const size_t size = 0) PRODUCT_RETURN;
+                               const char* base,
+                               const size_t size);
+  static void trace_page_sizes_for_requested_size(const char* str,
+                                                  const size_t requested_size,
+                                                  const size_t page_size,
+                                                  const size_t alignment,
+                                                  const char* base,
+                                                  const size_t size);
 
   static int    vm_allocation_granularity();
   static char*  reserve_memory(size_t bytes, char* addr = 0,
@@ -515,6 +520,9 @@
   static int ftruncate(int fd, jlong length);
   static int fsync(int fd);
   static int available(int fd, jlong *bytes);
+  static int fileno(FILE* fp);
+
+  static int compare_file_modified_times(const char* file1, const char* file2);
 
   //File i/o operations
 
--- a/hotspot/src/share/vm/runtime/osThread.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/runtime/osThread.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -29,7 +29,6 @@
 #include "runtime/handles.hpp"
 #include "runtime/javaFrameAnchor.hpp"
 #include "runtime/objectMonitor.hpp"
-#include "utilities/top.hpp"
 
 // The OSThread class holds OS-specific thread information.  It is equivalent
 // to the sys_thread_t structure of the classic JVM implementation.
--- a/hotspot/src/share/vm/runtime/reflection.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/runtime/reflection.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -1025,7 +1025,7 @@
 static void narrow(jvalue* value, BasicType narrow_type, TRAPS) {
   switch (narrow_type) {
   case T_BOOLEAN:
-    value->z = (jboolean)value->i;
+    value->z = (jboolean) (value->i & 1);
     return;
   case T_BYTE:
     value->b = (jbyte)value->i;
--- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -38,6 +38,7 @@
 #include "interpreter/interpreter.hpp"
 #include "interpreter/interpreterRuntime.hpp"
 #include "logging/log.hpp"
+#include "memory/metaspaceShared.hpp"
 #include "memory/resourceArea.hpp"
 #include "memory/universe.inline.hpp"
 #include "oops/klass.hpp"
@@ -1788,7 +1789,7 @@
 IRT_LEAF(void, SharedRuntime::fixup_callers_callsite(Method* method, address caller_pc))
   Method* moop(method);
 
-  address entry_point = moop->from_compiled_entry();
+  address entry_point = moop->from_compiled_entry_no_trampoline();
 
   // It's possible that deoptimization can occur at a call site which hasn't
   // been resolved yet, in which case this function will be called from
@@ -2351,12 +2352,15 @@
 
  public:
   AdapterHandlerTable()
-    : BasicHashtable<mtCode>(293, sizeof(AdapterHandlerEntry)) { }
+    : BasicHashtable<mtCode>(293, (DumpSharedSpaces ? sizeof(CDSAdapterHandlerEntry) : sizeof(AdapterHandlerEntry))) { }
 
   // Create a new entry suitable for insertion in the table
   AdapterHandlerEntry* new_entry(AdapterFingerPrint* fingerprint, address i2c_entry, address c2i_entry, address c2i_unverified_entry) {
     AdapterHandlerEntry* entry = (AdapterHandlerEntry*)BasicHashtable<mtCode>::new_entry(fingerprint->compute_hash());
     entry->init(fingerprint, i2c_entry, c2i_entry, c2i_unverified_entry);
+    if (DumpSharedSpaces) {
+      ((CDSAdapterHandlerEntry*)entry)->init();
+    }
     return entry;
   }
 
@@ -2519,6 +2523,28 @@
 }
 
 AdapterHandlerEntry* AdapterHandlerLibrary::get_adapter(const methodHandle& method) {
+  AdapterHandlerEntry* entry = get_adapter0(method);
+  if (method->is_shared()) {
+    MutexLocker mu(AdapterHandlerLibrary_lock);
+    if (method->adapter() == NULL) {
+      method->update_adapter_trampoline(entry);
+    }
+    address trampoline = method->from_compiled_entry();
+    if (*(int*)trampoline == 0) {
+      CodeBuffer buffer(trampoline, (int)SharedRuntime::trampoline_size());
+      MacroAssembler _masm(&buffer);
+      SharedRuntime::generate_trampoline(&_masm, entry->get_c2i_entry());
+
+      if (PrintInterpreter) {
+        Disassembler::decode(buffer.insts_begin(), buffer.insts_end());
+      }
+    }
+  }
+
+  return entry;
+}
+
+AdapterHandlerEntry* AdapterHandlerLibrary::get_adapter0(const methodHandle& method) {
   // Use customized signature handler.  Need to lock around updates to
   // the AdapterHandlerTable (it is not safe for concurrent readers
   // and a single writer: this could be fixed if it becomes a
@@ -2535,7 +2561,9 @@
     // make sure data structure is initialized
     initialize();
 
-    if (CodeCacheExtensions::skip_compiler_support()) {
+    // during dump time, always generate adapters, even if the
+    // compiler has been turned off.
+    if (!DumpSharedSpaces && CodeCacheExtensions::skip_compiler_support()) {
       // adapters are useless and should not be used, including the
       // abstract_method_handler. However, some callers check that
       // an adapter was installed.
@@ -3017,6 +3045,17 @@
 
 }
 
+#if INCLUDE_CDS
+
+void CDSAdapterHandlerEntry::init() {
+  assert(DumpSharedSpaces, "used during dump time only");
+  _c2i_entry_trampoline = (address)MetaspaceShared::misc_data_space_alloc(SharedRuntime::trampoline_size());
+  _adapter_trampoline = (AdapterHandlerEntry**)MetaspaceShared::misc_data_space_alloc(sizeof(AdapterHandlerEntry*));
+};
+
+#endif // INCLUDE_CDS
+
+
 #ifndef PRODUCT
 
 void AdapterHandlerLibrary::print_statistics() {
--- a/hotspot/src/share/vm/runtime/sharedRuntime.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -398,6 +398,10 @@
   static void convert_ints_to_longints(int i2l_argcnt, int& in_args_count,
                                        BasicType*& in_sig_bt, VMRegPair*& in_regs);
 
+  static size_t trampoline_size();
+
+  static void generate_trampoline(MacroAssembler *masm, address destination);
+
   // Generate I2C and C2I adapters. These adapters are simple argument marshalling
   // blobs. Unlike adapters in the tiger and earlier releases the code in these
   // blobs does not create a new frame and are therefore virtually invisible
@@ -680,6 +684,17 @@
   void print_adapter_on(outputStream* st) const;
 };
 
+class CDSAdapterHandlerEntry: public AdapterHandlerEntry {
+  address               _c2i_entry_trampoline;   // allocated from shared spaces "MC" region
+  AdapterHandlerEntry** _adapter_trampoline;     // allocated from shared spaces "MD" region
+
+public:
+  address get_c2i_entry_trampoline()             const { return _c2i_entry_trampoline; }
+  AdapterHandlerEntry** get_adapter_trampoline() const { return _adapter_trampoline; }
+  void init() NOT_CDS_RETURN;
+};
+
+
 class AdapterHandlerLibrary: public AllStatic {
  private:
   static BufferBlob* _buffer; // the temporary code buffer in CodeCache
@@ -687,6 +702,7 @@
   static AdapterHandlerEntry* _abstract_method_handler;
   static BufferBlob* buffer_blob();
   static void initialize();
+  static AdapterHandlerEntry* get_adapter0(const methodHandle& method);
 
  public:
 
--- a/hotspot/src/share/vm/runtime/signature.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/runtime/signature.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -27,7 +27,6 @@
 
 #include "memory/allocation.hpp"
 #include "oops/method.hpp"
-#include "utilities/top.hpp"
 
 // SignatureIterators iterate over a Java signature (or parts of it).
 // (Syntax according to: "The Java Virtual Machine Specification" by
--- a/hotspot/src/share/vm/runtime/stackValue.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/runtime/stackValue.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -27,7 +27,6 @@
 
 #include "code/location.hpp"
 #include "runtime/handles.hpp"
-#include "utilities/top.hpp"
 
 class StackValue : public ResourceObj {
  private:
--- a/hotspot/src/share/vm/runtime/stubRoutines.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/runtime/stubRoutines.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -30,7 +30,6 @@
 #include "runtime/frame.hpp"
 #include "runtime/mutexLocker.hpp"
 #include "runtime/stubCodeGenerator.hpp"
-#include "utilities/top.hpp"
 
 // StubRoutines provides entry points to assembly routines used by
 // compiled code and the run-time system. Platform-specific entry
--- a/hotspot/src/share/vm/runtime/synchronizer.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/runtime/synchronizer.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -29,8 +29,6 @@
 #include "runtime/basicLock.hpp"
 #include "runtime/handles.hpp"
 #include "runtime/perfData.hpp"
-#include "utilities/top.hpp"
-
 
 class ObjectMonitor;
 
--- a/hotspot/src/share/vm/runtime/task.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/runtime/task.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -25,7 +25,8 @@
 #ifndef SHARE_VM_RUNTIME_TASK_HPP
 #define SHARE_VM_RUNTIME_TASK_HPP
 
-#include "utilities/top.hpp"
+#include "memory/allocation.hpp"
+#include "runtime/timer.hpp"
 
 // A PeriodicTask has the sole purpose of executing its task
 // function with regular intervals.
--- a/hotspot/src/share/vm/runtime/thread.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/runtime/thread.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -818,13 +818,17 @@
 // Thread::print_on_error() is called by fatal error handler. Don't use
 // any lock or allocate memory.
 void Thread::print_on_error(outputStream* st, char* buf, int buflen) const {
-  if (is_VM_thread())                 st->print("VMThread");
-  else if (is_Compiler_thread())      st->print("CompilerThread");
-  else if (is_Java_thread())          st->print("JavaThread");
-  else if (is_GC_task_thread())       st->print("GCTaskThread");
-  else if (is_Watcher_thread())       st->print("WatcherThread");
-  else if (is_ConcurrentGC_thread())  st->print("ConcurrentGCThread");
-  else                                st->print("Thread");
+  assert(!(is_Compiler_thread() || is_Java_thread()), "Can't call name() here if it allocates");
+
+  if (is_VM_thread())                 { st->print("VMThread"); }
+  else if (is_GC_task_thread())       { st->print("GCTaskThread"); }
+  else if (is_Watcher_thread())       { st->print("WatcherThread"); }
+  else if (is_ConcurrentGC_thread())  { st->print("ConcurrentGCThread"); }
+  else                                { st->print("Thread"); }
+
+  if (is_Named_thread()) {
+    st->print(" \"%s\"", name());
+  }
 
   st->print(" [stack: " PTR_FORMAT "," PTR_FORMAT "]",
             p2i(stack_end()), p2i(stack_base()));
@@ -4498,6 +4502,36 @@
   st->flush();
 }
 
+void Threads::print_on_error(Thread* this_thread, outputStream* st, Thread* current, char* buf,
+                             int buflen, bool* found_current) {
+  if (this_thread != NULL) {
+    bool is_current = (current == this_thread);
+    *found_current = *found_current || is_current;
+    st->print("%s", is_current ? "=>" : "  ");
+
+    st->print(PTR_FORMAT, p2i(this_thread));
+    st->print(" ");
+    this_thread->print_on_error(st, buf, buflen);
+    st->cr();
+  }
+}
+
+class PrintOnErrorClosure : public ThreadClosure {
+  outputStream* _st;
+  Thread* _current;
+  char* _buf;
+  int _buflen;
+  bool* _found_current;
+ public:
+  PrintOnErrorClosure(outputStream* st, Thread* current, char* buf,
+                      int buflen, bool* found_current) :
+   _st(st), _current(current), _buf(buf), _buflen(buflen), _found_current(found_current) {}
+
+  virtual void do_thread(Thread* thread) {
+    Threads::print_on_error(thread, _st, _current, _buf, _buflen, _found_current);
+  }
+};
+
 // Threads::print_on_error() is called by fatal error handler. It's possible
 // that VM is not at safepoint and/or current thread is inside signal handler.
 // Don't print stack trace, as the stack may not be walkable. Don't allocate
@@ -4507,40 +4541,17 @@
   bool found_current = false;
   st->print_cr("Java Threads: ( => current thread )");
   ALL_JAVA_THREADS(thread) {
-    bool is_current = (current == thread);
-    found_current = found_current || is_current;
-
-    st->print("%s", is_current ? "=>" : "  ");
-
-    st->print(PTR_FORMAT, p2i(thread));
-    st->print(" ");
-    thread->print_on_error(st, buf, buflen);
-    st->cr();
+    print_on_error(thread, st, current, buf, buflen, &found_current);
   }
   st->cr();
 
   st->print_cr("Other Threads:");
-  if (VMThread::vm_thread()) {
-    bool is_current = (current == VMThread::vm_thread());
-    found_current = found_current || is_current;
-    st->print("%s", current == VMThread::vm_thread() ? "=>" : "  ");
-
-    st->print(PTR_FORMAT, p2i(VMThread::vm_thread()));
-    st->print(" ");
-    VMThread::vm_thread()->print_on_error(st, buf, buflen);
-    st->cr();
-  }
-  WatcherThread* wt = WatcherThread::watcher_thread();
-  if (wt != NULL) {
-    bool is_current = (current == wt);
-    found_current = found_current || is_current;
-    st->print("%s", is_current ? "=>" : "  ");
-
-    st->print(PTR_FORMAT, p2i(wt));
-    st->print(" ");
-    wt->print_on_error(st, buf, buflen);
-    st->cr();
-  }
+  print_on_error(VMThread::vm_thread(), st, current, buf, buflen, &found_current);
+  print_on_error(WatcherThread::watcher_thread(), st, current, buf, buflen, &found_current);
+
+  PrintOnErrorClosure print_closure(st, current, buf, buflen, &found_current);
+  Universe::heap()->gc_threads_do(&print_closure);
+
   if (!found_current) {
     st->cr();
     st->print("=>" PTR_FORMAT " (exited) ", p2i(current));
--- a/hotspot/src/share/vm/runtime/thread.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/runtime/thread.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -46,7 +46,6 @@
 #include "trace/traceMacros.hpp"
 #include "utilities/exceptions.hpp"
 #include "utilities/macros.hpp"
-#include "utilities/top.hpp"
 #if INCLUDE_ALL_GCS
 #include "gc/g1/dirtyCardQueue.hpp"
 #include "gc/g1/satbMarkQueue.hpp"
@@ -2157,6 +2156,8 @@
     print_on(tty, print_stacks, internal_format, false /* no concurrent lock printed */);
   }
   static void print_on_error(outputStream* st, Thread* current, char* buf, int buflen);
+  static void print_on_error(Thread* this_thread, outputStream* st, Thread* current, char* buf,
+                             int buflen, bool* found_current);
   static void print_threads_compiling(outputStream* st, char* buf, int buflen);
 
   // Get Java threads that are waiting to enter a monitor. If doLock
--- a/hotspot/src/share/vm/runtime/threadLocalStorage.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/runtime/threadLocalStorage.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -25,7 +25,7 @@
 #ifndef SHARE_VM_RUNTIME_THREADLOCALSTORAGE_HPP
 #define SHARE_VM_RUNTIME_THREADLOCALSTORAGE_HPP
 
-#include "utilities/top.hpp"
+#include "memory/allocation.hpp"
 
 // forward-decl as we can't have an include cycle
 class Thread;
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -400,7 +400,6 @@
   nonproduct_nonstatic_field(Method,           _compiled_invocation_count,                    int)                                   \
   volatile_nonstatic_field(Method,             _code,                                         nmethod*)                              \
   nonstatic_field(Method,                      _i2i_entry,                                    address)                               \
-  nonstatic_field(Method,                      _adapter,                                      AdapterHandlerEntry*)                  \
   volatile_nonstatic_field(Method,             _from_compiled_entry,                          address)                               \
   volatile_nonstatic_field(Method,             _from_interpreted_entry,                       address)                               \
   volatile_nonstatic_field(ConstMethod,        _fingerprint,                                  uint64_t)                              \
--- a/hotspot/src/share/vm/runtime/vmThread.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/runtime/vmThread.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -26,7 +26,7 @@
 #define SHARE_VM_RUNTIME_VMTHREAD_HPP
 
 #include "runtime/perfData.hpp"
-#include "runtime/thread.inline.hpp"
+#include "runtime/thread.hpp"
 #include "runtime/vm_operations.hpp"
 
 //
--- a/hotspot/src/share/vm/runtime/vm_operations.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/runtime/vm_operations.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -29,7 +29,6 @@
 #include "memory/allocation.hpp"
 #include "oops/oop.hpp"
 #include "runtime/thread.hpp"
-#include "utilities/top.hpp"
 #include "code/codeCache.hpp"
 
 // The following classes are used for operations
--- a/hotspot/src/share/vm/runtime/vm_version.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/runtime/vm_version.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -24,6 +24,7 @@
 
 #include "precompiled.hpp"
 #include "code/codeCacheExtensions.hpp"
+#include "logging/log.hpp"
 #include "memory/universe.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/arguments.hpp"
@@ -274,12 +275,12 @@
 void VM_Version_init() {
   VM_Version::initialize();
 
-#ifndef PRODUCT
-  if (PrintMiscellaneous && Verbose) {
-    char buf[512];
-    os::print_cpu_info(tty, buf, sizeof(buf));
+  if (log_is_enabled(Info, os, cpu)) {
+    char buf[1024];
+    ResourceMark rm;
+    outputStream* log = Log(os, cpu)::info_stream();
+    os::print_cpu_info(log, buf, sizeof(buf));
   }
-#endif
 }
 
 unsigned int Abstract_VM_Version::nof_parallel_worker_threads(
--- a/hotspot/src/share/vm/services/nmtCommon.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/services/nmtCommon.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -41,6 +41,7 @@
   "Test",
   "Tracing",
   "Logging",
+  "Arguments",
   "Unknown"
 };
 
--- a/hotspot/src/share/vm/utilities/accessFlags.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/utilities/accessFlags.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -25,8 +25,9 @@
 #ifndef SHARE_VM_UTILITIES_ACCESSFLAGS_HPP
 #define SHARE_VM_UTILITIES_ACCESSFLAGS_HPP
 
+#include "memory/allocation.hpp"
 #include "prims/jvm.h"
-#include "utilities/top.hpp"
+#include "utilities/macros.hpp"
 
 // AccessFlags is an abstraction over Java access flags.
 
--- a/hotspot/src/share/vm/utilities/bitMap.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/utilities/bitMap.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -68,6 +68,10 @@
   }
 }
 
+void BitMap::pretouch() {
+  os::pretouch_memory(word_addr(0), word_addr(size()));
+}
+
 void BitMap::set_range_within_word(idx_t beg, idx_t end) {
   // With a valid range (beg <= end), this test ensures that end != 0, as
   // required by inverted_bit_mask_for_range.  Also avoids an unnecessary write.
--- a/hotspot/src/share/vm/utilities/bitMap.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/utilities/bitMap.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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,7 +26,6 @@
 #define SHARE_VM_UTILITIES_BITMAP_HPP
 
 #include "memory/allocation.hpp"
-#include "utilities/top.hpp"
 
 // Forward decl;
 class BitMapClosure;
@@ -135,10 +134,18 @@
   // use the same value for "in_resource_area".)
   void resize(idx_t size_in_bits, bool in_resource_area = true);
 
+  // Pretouch the entire range of memory this BitMap covers.
+  void pretouch();
+
   // Accessing
   idx_t size() const                    { return _size; }
+  idx_t size_in_bytes() const           { return size_in_words() * BytesPerWord; }
   idx_t size_in_words() const           {
-    return word_index(size() + BitsPerWord - 1);
+    return calc_size_in_words(size());
+  }
+
+  static idx_t calc_size_in_words(size_t size_in_bits) {
+    return word_index(size_in_bits + BitsPerWord - 1);
   }
 
   bool at(idx_t index) const {
--- a/hotspot/src/share/vm/utilities/constantTag.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/utilities/constantTag.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -24,6 +24,7 @@
 
 #include "precompiled.hpp"
 #include "utilities/constantTag.hpp"
+#include "utilities/ostream.hpp"
 
 #ifndef PRODUCT
 
--- a/hotspot/src/share/vm/utilities/constantTag.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/utilities/constantTag.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -25,8 +25,8 @@
 #ifndef SHARE_VM_UTILITIES_CONSTANTTAG_HPP
 #define SHARE_VM_UTILITIES_CONSTANTTAG_HPP
 
+#include "memory/allocation.hpp"
 #include "prims/jvm.h"
-#include "utilities/top.hpp"
 
 // constant tags in Java .class files
 
--- a/hotspot/src/share/vm/utilities/debug.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/utilities/debug.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -52,7 +52,6 @@
 #include "utilities/defaultStream.hpp"
 #include "utilities/events.hpp"
 #include "utilities/macros.hpp"
-#include "utilities/top.hpp"
 #include "utilities/vmError.hpp"
 
 #if INCLUDE_TRACE
--- a/hotspot/src/share/vm/utilities/events.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/utilities/events.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -28,7 +28,6 @@
 #include "memory/allocation.hpp"
 #include "runtime/mutexLocker.hpp"
 #include "runtime/thread.hpp"
-#include "utilities/top.hpp"
 #include "utilities/vmError.hpp"
 
 // Events and EventMark provide interfaces to log events taking place in the vm.
--- a/hotspot/src/share/vm/utilities/exceptions.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/utilities/exceptions.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -47,7 +47,6 @@
 
 
 // Forward declarations to be independent of the include structure.
-// This allows us to have exceptions.hpp included in top.hpp.
 
 class Thread;
 class Handle;
--- a/hotspot/src/share/vm/utilities/globalDefinitions.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/utilities/globalDefinitions.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -25,7 +25,6 @@
 #include "precompiled.hpp"
 #include "runtime/os.hpp"
 #include "utilities/globalDefinitions.hpp"
-#include "utilities/top.hpp"
 
 // Basic error support
 
@@ -374,39 +373,89 @@
 
 #ifndef PRODUCT
 // For unit testing only
-class GlobalDefinitions {
+class TestGlobalDefinitions {
+private:
+
+  static void test_clamp_address_in_page() {
+    intptr_t page_sizes[] = { os::vm_page_size(), 4096, 8192, 65536, 2*1024*1024 };
+    const int num_page_sizes = sizeof(page_sizes) / sizeof(page_sizes[0]);
+
+    for (int i = 0; i < num_page_sizes; i++) {
+      intptr_t page_size = page_sizes[i];
+
+      address a_page = (address)(10*page_size);
+
+      // Check that address within page is returned as is
+      assert(clamp_address_in_page(a_page, a_page, page_size) == a_page, "incorrect");
+      assert(clamp_address_in_page(a_page + 128, a_page, page_size) == a_page + 128, "incorrect");
+      assert(clamp_address_in_page(a_page + page_size - 1, a_page, page_size) == a_page + page_size - 1, "incorrect");
+
+      // Check that address above page returns start of next page
+      assert(clamp_address_in_page(a_page + page_size, a_page, page_size) == a_page + page_size, "incorrect");
+      assert(clamp_address_in_page(a_page + page_size + 1, a_page, page_size) == a_page + page_size, "incorrect");
+      assert(clamp_address_in_page(a_page + page_size*5 + 1, a_page, page_size) == a_page + page_size, "incorrect");
+
+      // Check that address below page returns start of page
+      assert(clamp_address_in_page(a_page - 1, a_page, page_size) == a_page, "incorrect");
+      assert(clamp_address_in_page(a_page - 2*page_size - 1, a_page, page_size) == a_page, "incorrect");
+      assert(clamp_address_in_page(a_page - 5*page_size - 1, a_page, page_size) == a_page, "incorrect");
+    }
+  }
+
+  static void test_exact_unit_for_byte_size() {
+    assert(strcmp(exact_unit_for_byte_size(0),     "B") == 0, "incorrect");
+    assert(strcmp(exact_unit_for_byte_size(1),     "B") == 0, "incorrect");
+    assert(strcmp(exact_unit_for_byte_size(K - 1), "B") == 0, "incorrect");
+    assert(strcmp(exact_unit_for_byte_size(K),     "K") == 0, "incorrect");
+    assert(strcmp(exact_unit_for_byte_size(K + 1), "B") == 0, "incorrect");
+    assert(strcmp(exact_unit_for_byte_size(M - 1), "B") == 0, "incorrect");
+    assert(strcmp(exact_unit_for_byte_size(M),     "M") == 0, "incorrect");
+    assert(strcmp(exact_unit_for_byte_size(M + 1), "B") == 0, "incorrect");
+    assert(strcmp(exact_unit_for_byte_size(M + K), "K") == 0, "incorrect");
+#ifdef LP64
+    assert(strcmp(exact_unit_for_byte_size(G - 1),     "B") == 0, "incorrect");
+    assert(strcmp(exact_unit_for_byte_size(G),         "G") == 0, "incorrect");
+    assert(strcmp(exact_unit_for_byte_size(G + 1),     "B") == 0, "incorrect");
+    assert(strcmp(exact_unit_for_byte_size(G + K),     "K") == 0, "incorrect");
+    assert(strcmp(exact_unit_for_byte_size(G + M),     "M") == 0, "incorrect");
+    assert(strcmp(exact_unit_for_byte_size(G + M + K), "K") == 0, "incorrect");
+#endif
+  }
+
+  static void test_byte_size_in_exact_unit() {
+    assert(byte_size_in_exact_unit(0)     == 0,     "incorrect");
+    assert(byte_size_in_exact_unit(1)     == 1,     "incorrect");
+    assert(byte_size_in_exact_unit(K - 1) == K - 1, "incorrect");
+    assert(byte_size_in_exact_unit(K)     == 1,     "incorrect");
+    assert(byte_size_in_exact_unit(K + 1) == K + 1, "incorrect");
+    assert(byte_size_in_exact_unit(M - 1) == M - 1, "incorrect");
+    assert(byte_size_in_exact_unit(M)     == 1,     "incorrect");
+    assert(byte_size_in_exact_unit(M + 1) == M + 1, "incorrect");
+    assert(byte_size_in_exact_unit(M + K) == K + 1, "incorrect");
+#ifdef LP64
+    assert(byte_size_in_exact_unit(G - 1)     == G - 1,     "incorrect");
+    assert(byte_size_in_exact_unit(G)         == 1,         "incorrect");
+    assert(byte_size_in_exact_unit(G + 1)     == G + 1,     "incorrect");
+    assert(byte_size_in_exact_unit(G + K)     == M + 1,     "incorrect");
+    assert(byte_size_in_exact_unit(G + M)     == K + 1,     "incorrect");
+    assert(byte_size_in_exact_unit(G + M + K) == M + K + 1, "incorrect");
+#endif
+  }
+
+  static void test_exact_units() {
+    test_exact_unit_for_byte_size();
+    test_byte_size_in_exact_unit();
+  }
+
 public:
-  static void test_globals();
+  static void test() {
+    test_clamp_address_in_page();
+    test_exact_units();
+  }
 };
 
-void GlobalDefinitions::test_globals() {
-  intptr_t page_sizes[] = { os::vm_page_size(), 4096, 8192, 65536, 2*1024*1024 };
-  const int num_page_sizes = sizeof(page_sizes) / sizeof(page_sizes[0]);
-
-  for (int i = 0; i < num_page_sizes; i++) {
-    intptr_t page_size = page_sizes[i];
-
-    address a_page = (address)(10*page_size);
-
-    // Check that address within page is returned as is
-    assert(clamp_address_in_page(a_page, a_page, page_size) == a_page, "incorrect");
-    assert(clamp_address_in_page(a_page + 128, a_page, page_size) == a_page + 128, "incorrect");
-    assert(clamp_address_in_page(a_page + page_size - 1, a_page, page_size) == a_page + page_size - 1, "incorrect");
-
-    // Check that address above page returns start of next page
-    assert(clamp_address_in_page(a_page + page_size, a_page, page_size) == a_page + page_size, "incorrect");
-    assert(clamp_address_in_page(a_page + page_size + 1, a_page, page_size) == a_page + page_size, "incorrect");
-    assert(clamp_address_in_page(a_page + page_size*5 + 1, a_page, page_size) == a_page + page_size, "incorrect");
-
-    // Check that address below page returns start of page
-    assert(clamp_address_in_page(a_page - 1, a_page, page_size) == a_page, "incorrect");
-    assert(clamp_address_in_page(a_page - 2*page_size - 1, a_page, page_size) == a_page, "incorrect");
-    assert(clamp_address_in_page(a_page - 5*page_size - 1, a_page, page_size) == a_page, "incorrect");
-  }
-}
-
-void GlobalDefinitions_test() {
-  GlobalDefinitions::test_globals();
+void TestGlobalDefinitions_test() {
+  TestGlobalDefinitions::test();
 }
 
 #endif // PRODUCT
--- a/hotspot/src/share/vm/utilities/globalDefinitions.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/utilities/globalDefinitions.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -199,9 +199,6 @@
 const size_t G                  = M*K;
 const size_t HWperKB            = K / sizeof(HeapWord);
 
-const jint min_jint = (jint)1 << (sizeof(jint)*BitsPerByte-1); // 0x80000000 == smallest jint
-const jint max_jint = (juint)min_jint - 1;                     // 0x7FFFFFFF == largest jint
-
 // Constants for converting from a base unit to milli-base units.  For
 // example from seconds to milliseconds and microseconds
 
@@ -243,6 +240,36 @@
   }
 }
 
+inline const char* exact_unit_for_byte_size(size_t s) {
+#ifdef _LP64
+  if (s >= G && (s % G) == 0) {
+    return "G";
+  }
+#endif
+  if (s >= M && (s % M) == 0) {
+    return "M";
+  }
+  if (s >= K && (s % K) == 0) {
+    return "K";
+  }
+  return "B";
+}
+
+inline size_t byte_size_in_exact_unit(size_t s) {
+#ifdef _LP64
+  if (s >= G && (s % G) == 0) {
+    return s / G;
+  }
+#endif
+  if (s >= M && (s % M) == 0) {
+    return s / M;
+  }
+  if (s >= K && (s % K) == 0) {
+    return s / K;
+  }
+  return s;
+}
+
 //----------------------------------------------------------------------------------------------------
 // VM type definitions
 
@@ -328,7 +355,7 @@
 // so far from the middle of the road that it is likely to be problematic in
 // many C++ compilers.
 //
-#define CAST_TO_FN_PTR(func_type, value) ((func_type)(castable_address(value)))
+#define CAST_TO_FN_PTR(func_type, value) (reinterpret_cast<func_type>(value))
 #define CAST_FROM_FN_PTR(new_type, func_ptr) ((new_type)((address_word)(func_ptr)))
 
 // Unsigned byte types for os and stream.hpp
@@ -351,6 +378,14 @@
 typedef jint   s4;
 typedef jlong  s8;
 
+const jbyte min_jbyte = -(1 << 7);       // smallest jbyte
+const jbyte max_jbyte = (1 << 7) - 1;    // largest jbyte
+const jshort min_jshort = -(1 << 15);    // smallest jshort
+const jshort max_jshort = (1 << 15) - 1; // largest jshort
+
+const jint min_jint = (jint)1 << (sizeof(jint)*BitsPerByte-1); // 0x80000000 == smallest jint
+const jint max_jint = (juint)min_jint - 1;                     // 0x7FFFFFFF == largest jint
+
 //----------------------------------------------------------------------------------------------------
 // JVM spec restrictions
 
@@ -816,14 +851,15 @@
 
 enum TosState {         // describes the tos cache contents
   btos = 0,             // byte, bool tos cached
-  ctos = 1,             // char tos cached
-  stos = 2,             // short tos cached
-  itos = 3,             // int tos cached
-  ltos = 4,             // long tos cached
-  ftos = 5,             // float tos cached
-  dtos = 6,             // double tos cached
-  atos = 7,             // object cached
-  vtos = 8,             // tos not cached
+  ztos = 1,             // byte, bool tos cached
+  ctos = 2,             // char tos cached
+  stos = 3,             // short tos cached
+  itos = 4,             // int tos cached
+  ltos = 5,             // long tos cached
+  ftos = 6,             // float tos cached
+  dtos = 7,             // double tos cached
+  atos = 8,             // object cached
+  vtos = 9,             // tos not cached
   number_of_states,
   ilgl                  // illegal state: should not occur
 };
@@ -832,7 +868,7 @@
 inline TosState as_TosState(BasicType type) {
   switch (type) {
     case T_BYTE   : return btos;
-    case T_BOOLEAN: return btos; // FIXME: Add ztos
+    case T_BOOLEAN: return ztos;
     case T_CHAR   : return ctos;
     case T_SHORT  : return stos;
     case T_INT    : return itos;
@@ -848,8 +884,8 @@
 
 inline BasicType as_BasicType(TosState state) {
   switch (state) {
-    //case ztos: return T_BOOLEAN;//FIXME
     case btos : return T_BYTE;
+    case ztos : return T_BOOLEAN;
     case ctos : return T_CHAR;
     case stos : return T_SHORT;
     case itos : return T_INT;
--- a/hotspot/src/share/vm/utilities/growableArray.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/utilities/growableArray.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -29,7 +29,6 @@
 #include "memory/allocation.inline.hpp"
 #include "utilities/debug.hpp"
 #include "utilities/globalDefinitions.hpp"
-#include "utilities/top.hpp"
 
 // A growable array.
 
--- a/hotspot/src/share/vm/utilities/internalVMTests.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/utilities/internalVMTests.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -50,7 +50,7 @@
   run_unit_test(TestMetaspaceAux_test);
   run_unit_test(TestMetachunk_test);
   run_unit_test(TestVirtualSpaceNode_test);
-  run_unit_test(GlobalDefinitions_test);
+  run_unit_test(TestGlobalDefinitions_test);
   run_unit_test(GCTimer_test);
   run_unit_test(arrayOopDesc_test);
   run_unit_test(CollectedHeap_test);
@@ -67,6 +67,7 @@
   run_unit_test(Test_linked_list);
   run_unit_test(TestChunkedList_test);
   run_unit_test(JSON_test);
+  run_unit_test(Test_log_tag_combinations_limit);
   run_unit_test(Test_logtarget);
   run_unit_test(Test_logstream);
   run_unit_test(Test_loghandle);
@@ -77,6 +78,9 @@
   run_unit_test(Test_log_prefix);
   run_unit_test(Test_log_big);
   run_unit_test(Test_logtagset_duplicates);
+  run_unit_test(Test_log_file_startup_rotation);
+  run_unit_test(Test_log_file_startup_truncation);
+  run_unit_test(Test_invalid_log_file);
   run_unit_test(DirectivesParser_test);
   run_unit_test(Test_TempNewSymbol);
 #if INCLUDE_VM_STRUCTS
--- a/hotspot/src/share/vm/utilities/ostream.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/utilities/ostream.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -31,7 +31,6 @@
 #include "utilities/defaultStream.hpp"
 #include "utilities/macros.hpp"
 #include "utilities/ostream.hpp"
-#include "utilities/top.hpp"
 #include "utilities/xmlstream.hpp"
 
 extern "C" void jio_print(const char* s); // Declarationtion of jvm method
--- a/hotspot/src/share/vm/utilities/pair.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/utilities/pair.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -26,7 +26,6 @@
 #define SHARE_VM_UTILITIES_PAIR_HPP
 
 #include "memory/allocation.hpp"
-#include "utilities/top.hpp"
 
 template<typename T, typename V,  typename ALLOC_BASE = ResourceObj>
 class Pair : public ALLOC_BASE {
--- a/hotspot/src/share/vm/utilities/preserveException.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/utilities/preserveException.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -26,7 +26,7 @@
 #define SHARE_VM_UTILITIES_PRESERVEEXCEPTION_HPP
 
 #include "runtime/handles.hpp"
-#include "runtime/thread.inline.hpp"
+#include "runtime/thread.hpp"
 
 // This file provides more support for exception handling; see also exceptions.hpp
 class PreserveExceptionMark {
--- a/hotspot/src/share/vm/utilities/resourceHash.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/utilities/resourceHash.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -26,7 +26,6 @@
 #define SHARE_VM_UTILITIES_RESOURCEHASH_HPP
 
 #include "memory/allocation.hpp"
-#include "utilities/top.hpp"
 
 template<typename K> struct ResourceHashtableFns {
     typedef unsigned (*hash_fn)(K const&);
--- a/hotspot/src/share/vm/utilities/top.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * 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 SHARE_VM_UTILITIES_TOP_HPP
-#define SHARE_VM_UTILITIES_TOP_HPP
-
-#include "oops/oopsHierarchy.hpp"
-#include "runtime/globals.hpp"
-#include "utilities/debug.hpp"
-#include "utilities/exceptions.hpp"
-#include "utilities/globalDefinitions.hpp"
-#include "utilities/macros.hpp"
-#include "utilities/ostream.hpp"
-#include "utilities/sizes.hpp"
-#if INCLUDE_ALL_GCS
-#include "gc/g1/g1_globals.hpp"
-#endif // INCLUDE_ALL_GCS
-#ifdef COMPILER1
-#include "c1/c1_globals.hpp"
-#endif
-#ifdef COMPILER2
-#include "opto/c2_globals.hpp"
-#endif
-#if INCLUDE_JVMCI
-#include "jvmci/jvmci_globals.hpp"
-#endif
-
-// THIS FILE IS INTESIONALLY LEFT EMPTY
-// IT IS USED TO MINIMIZE THE NUMBER OF DEPENDENCIES IN includeDB
-
-#endif // SHARE_VM_UTILITIES_TOP_HPP
--- a/hotspot/src/share/vm/utilities/utf8.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/utilities/utf8.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -26,7 +26,6 @@
 #define SHARE_VM_UTILITIES_UTF8_HPP
 
 #include "memory/allocation.hpp"
-#include "utilities/top.hpp"
 
 // Low-level interface for UTF8 strings
 
--- a/hotspot/src/share/vm/utilities/vmError.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/src/share/vm/utilities/vmError.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -43,7 +43,6 @@
 #include "utilities/defaultStream.hpp"
 #include "utilities/errorReporter.hpp"
 #include "utilities/events.hpp"
-#include "utilities/top.hpp"
 #include "utilities/vmError.hpp"
 
 // List of environment variables that should be reported in error log file.
--- a/hotspot/test/TEST.ROOT	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/test/TEST.ROOT	Wed Jul 05 21:37:42 2017 +0200
@@ -30,6 +30,10 @@
 keys=cte_test jcmd nmt regression gc stress
 
 groups=TEST.groups [closed/TEST.groups]
+
+# Source files for classes that will be used at the beginning of each test suite run, 
+# to determine additional characteristics of the system for use with the @requires tag. 
+requires.extraPropDefns = ../../test/jtreg-ext/requires/VMProps.java
 requires.properties=sun.arch.data.model
 
 # Tests using jtreg 4.2 b01 features
--- a/hotspot/test/TEST.groups	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/test/TEST.groups	Wed Jul 05 21:37:42 2017 +0200
@@ -338,6 +338,7 @@
   sanity/ExecuteInternalVMTests.java \
   gc/ \
   -gc/g1/ \
+  -gc/stress \
   -gc/survivorAlignment/TestPromotionFromSurvivorToTenuredAfterMinorGC.java \
   -gc/cms/TestMBeanCMS.java \
   -gc/metaspace/CompressedClassSpaceSizeInJmapHeap.java
@@ -346,7 +347,7 @@
   sanity/ExecuteInternalVMTests.java
 
 hotspot_fast_gc_gcold = \
-  stress/gc/TestGCOld.java
+  gc/stress/TestGCOld.java
 
 hotspot_fast_runtime = \
   runtime/ \
@@ -387,7 +388,8 @@
   :hotspot_fast_compiler_2 \
   :hotspot_fast_compiler_3 \
   :hotspot_fast_compiler_closed \
-  :hotspot_fast_gc \
+  :hotspot_fast_gc_1 \
+  :hotspot_fast_gc_2 \
   :hotspot_fast_gc_closed \
   :hotspot_fast_gc_gcold \
   :hotspot_fast_runtime \
--- a/hotspot/test/gc/TestHumongousReferenceObject.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/test/gc/TestHumongousReferenceObject.java	Wed Jul 05 21:37:42 2017 +0200
@@ -27,26 +27,26 @@
  * @test
  * @summary Test that verifies that iteration over large, plain Java objects, that potentially cross region boundaries on G1, with references in them works.
  * @requires vm.gc == "null"
- * @bug 8151499
+ * @bug 8151499 8153734
  * @modules java.base/jdk.internal.vm.annotation
- * @run main/othervm -XX:+EnableContended -XX:-RestrictContended -Xmx1g -XX:+UseParallelGC -XX:ContendedPaddingWidth=8192 TestHumongousReferenceObject
- * @run main/othervm -XX:+EnableContended -XX:-RestrictContended -Xmx1g -XX:+UseG1GC -XX:G1HeapRegionSize=1M -XX:ContendedPaddingWidth=8192 TestHumongousReferenceObject
- * @run main/othervm -XX:+EnableContended -XX:-RestrictContended -Xmx1g -XX:+UseG1GC -XX:G1HeapRegionSize=2M -XX:ContendedPaddingWidth=8192 TestHumongousReferenceObject
- * @run main/othervm -XX:+EnableContended -XX:-RestrictContended -Xmx1g -XX:+UseG1GC -XX:G1HeapRegionSize=4M -XX:ContendedPaddingWidth=8192 TestHumongousReferenceObject
- * @run main/othervm -XX:+EnableContended -XX:-RestrictContended -Xmx1g -XX:+UseG1GC -XX:G1HeapRegionSize=8M -XX:ContendedPaddingWidth=8192 TestHumongousReferenceObject
+ * @run main/othervm -XX:+EnableContended -XX:-RestrictContended -Xmx128m -XX:+UseParallelGC -XX:ContendedPaddingWidth=8192 TestHumongousReferenceObject
+ * @run main/othervm -XX:+EnableContended -XX:-RestrictContended -Xmx128m -XX:+UseG1GC -XX:G1HeapRegionSize=1M -XX:ContendedPaddingWidth=8192 TestHumongousReferenceObject
+ * @run main/othervm -XX:+EnableContended -XX:-RestrictContended -Xmx128m -XX:+UseG1GC -XX:G1HeapRegionSize=2M -XX:ContendedPaddingWidth=8192 TestHumongousReferenceObject
+ * @run main/othervm -XX:+EnableContended -XX:-RestrictContended -Xmx128m -XX:+UseG1GC -XX:G1HeapRegionSize=4M -XX:ContendedPaddingWidth=8192 TestHumongousReferenceObject
+ * @run main/othervm -XX:+EnableContended -XX:-RestrictContended -Xmx128m -XX:+UseG1GC -XX:G1HeapRegionSize=8M -XX:ContendedPaddingWidth=8192 TestHumongousReferenceObject
  */
 public class TestHumongousReferenceObject {
 
     /*
       Due to 300 fields with 8K @Contended padding around each field, it takes 2.4M bytes per instance.
       With small G1 regions, it is bound to cross regions. G1 should properly (card) mark the object nevertheless.
-      With 1G heap, it is enough to allocate ~400 of these objects to provoke at least one GC.
+      With 128M heap, it is enough to allocate ~100 of these objects to provoke at least one GC.
      */
 
     static volatile Object instance;
 
     public static void main(String[] args) {
-        for (int c = 0; c < 400; c++) {
+        for (int c = 0; c < 100; c++) {
             instance = new TestHumongousReferenceObject();
         }
     }
--- a/hotspot/test/gc/arguments/TestG1ConcRefinementThreads.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/test/gc/arguments/TestG1ConcRefinementThreads.java	Wed Jul 05 21:37:42 2017 +0200
@@ -38,7 +38,7 @@
 
 public class TestG1ConcRefinementThreads {
 
-  static final int AUTO_SELECT_THREADS_COUNT = 0;
+  static final int AUTO_SELECT_THREADS_COUNT = -1;
   static final int PASSED_THREADS_COUNT = 11;
 
   public static void main(String args[]) throws Exception {
@@ -49,8 +49,8 @@
 
     // zero setting case
     runG1ConcRefinementThreadsTest(
-        new String[]{"-XX:G1ConcRefinementThreads=0"}, // automatically selected
-        AUTO_SELECT_THREADS_COUNT /* set to zero */);
+        new String[]{"-XX:G1ConcRefinementThreads=0"},
+        0);
 
     // non-zero sestting case
     runG1ConcRefinementThreadsTest(
@@ -77,7 +77,7 @@
   private static void checkG1ConcRefinementThreadsConsistency(String output, int expectedValue) {
     int actualValue = getIntValue("G1ConcRefinementThreads", output);
 
-    if (expectedValue == 0) {
+    if (expectedValue == AUTO_SELECT_THREADS_COUNT) {
       // If expectedValue is automatically selected, set it same as ParallelGCThreads.
       expectedValue = getIntValue("ParallelGCThreads", output);
     }
--- a/hotspot/test/gc/arguments/TestMaxMinHeapFreeRatioFlags.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/test/gc/arguments/TestMaxMinHeapFreeRatioFlags.java	Wed Jul 05 21:37:42 2017 +0200
@@ -168,6 +168,11 @@
             long maxHeapSize = getMax();
             int gcTries = (shrinkHeapInSteps ? GC_TRIES : 1);
 
+            // Initial checks. This also links up everything in these helper methods,
+            // in case it brings more garbage.
+            forceGC(gcTries);
+            verifyRatio(minRatio, maxRatio);
+
             // commit 0.5 of total heap size to have enough space
             // to both shink and expand
             while (getCommitted() < maxHeapSize / 2) {
@@ -215,7 +220,6 @@
             if (previouslyCommitted <= getCommitted()) {
                 throw new RuntimeException("Heap was not shrinked.");
             }
-
         }
 
         public static void forceGC(int gcTries) {
--- a/hotspot/test/gc/g1/Test2GbHeap.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/test/gc/g1/Test2GbHeap.java	Wed Jul 05 21:37:42 2017 +0200
@@ -25,6 +25,9 @@
  * @test Test2GbHeap
  * @bug 8031686
  * @summary Regression test to ensure we can start G1 with 2gb heap.
+ * Skip test on 32 bit Windows: it typically does not support the many and large virtual memory reservations needed.
+ * @requires (vm.gc == "G1" | vm.gc == "null")
+ * @requires !((sun.arch.data.model == "32") & (os.family == "windows"))
  * @key gc
  * @key regression
  * @library /testlibrary
@@ -48,17 +51,6 @@
     ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(testArguments.toArray(new String[0]));
 
     OutputAnalyzer output = new OutputAnalyzer(pb.start());
-
-    // Avoid failing test for setups not supported.
-    if (output.getOutput().contains("Could not reserve enough space for 2097152KB object heap")) {
-      // Will fail on machines with too little memory (and Windows 32-bit VM), ignore such failures.
-      output.shouldHaveExitValue(1);
-    } else if (output.getOutput().contains("-XX:+UseG1GC not supported in this VM")) {
-      // G1 is not supported on embedded, ignore such failures.
-      output.shouldHaveExitValue(1);
-    } else {
-      // Normally everything should be fine.
-      output.shouldHaveExitValue(0);
-    }
+    output.shouldHaveExitValue(0);
   }
 }
--- a/hotspot/test/gc/g1/TestLargePageUseForAuxMemory.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/test/gc/g1/TestLargePageUseForAuxMemory.java	Wed Jul 05 21:37:42 2017 +0200
@@ -36,6 +36,8 @@
  */
 
 import java.lang.Math;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 
 import jdk.test.lib.*;
 import jdk.test.lib.Asserts;
@@ -47,14 +49,29 @@
     static long smallPageSize;
     static long allocGranularity;
 
+    static void checkSize(OutputAnalyzer output, long expectedSize, String pattern) {
+        String pageSizeStr = output.firstMatch(pattern, 1);
+
+        if (pageSizeStr == null) {
+            output.reportDiagnosticSummary();
+            throw new RuntimeException("Match from '" + pattern + "' got 'null' expected: " + expectedSize);
+        }
+
+        long size = parseMemoryString(pageSizeStr);
+        if (size != expectedSize) {
+            output.reportDiagnosticSummary();
+            throw new RuntimeException("Match from '" + pattern + "' got " + size + " expected: " + expectedSize);
+        }
+    }
+
     static void checkSmallTables(OutputAnalyzer output, long expectedPageSize) throws Exception {
-        output.shouldContain("G1 'Block offset table': pg_sz=" + expectedPageSize);
-        output.shouldContain("G1 'Card counts table': pg_sz=" + expectedPageSize);
+        checkSize(output, expectedPageSize, "Block Offset Table: .*page_size=([^ ]+)");
+        checkSize(output, expectedPageSize, "Card Counts Table: .*page_size=([^ ]+)");
     }
 
     static void checkBitmaps(OutputAnalyzer output, long expectedPageSize) throws Exception {
-        output.shouldContain("G1 'Prev Bitmap': pg_sz=" + expectedPageSize);
-        output.shouldContain("G1 'Next Bitmap': pg_sz=" + expectedPageSize);
+        checkSize(output, expectedPageSize, "Prev Bitmap: .*page_size=([^ ]+)");
+        checkSize(output, expectedPageSize, "Next Bitmap: .*page_size=([^ ]+)");
     }
 
     static void testVM(String what, long heapsize, boolean cardsShouldUseLargePages, boolean bitmapShouldUseLargePages) throws Exception {
@@ -66,7 +83,7 @@
                                                    "-XX:G1HeapRegionSize=" + HEAP_REGION_SIZE,
                                                    "-Xms" + heapsize,
                                                    "-Xmx" + heapsize,
-                                                   "-XX:+TracePageSizes",
+                                                   "-Xlog:pagesize",
                                                    "-XX:+UseLargePages",
                                                    "-XX:+IgnoreUnrecognizedVMOptions",  // there is no ObjectAlignmentInBytes in 32 bit builds
                                                    "-XX:ObjectAlignmentInBytes=8",
@@ -82,7 +99,7 @@
                                                    "-XX:G1HeapRegionSize=" + HEAP_REGION_SIZE,
                                                    "-Xms" + heapsize,
                                                    "-Xmx" + heapsize,
-                                                   "-XX:+TracePageSizes",
+                                                   "-Xlog:pagesize",
                                                    "-XX:-UseLargePages",
                                                    "-XX:+IgnoreUnrecognizedVMOptions",  // there is no ObjectAlignmentInBytes in 32 bit builds
                                                    "-XX:ObjectAlignmentInBytes=8",
@@ -108,11 +125,6 @@
     }
 
     public static void main(String[] args) throws Exception {
-        if (!Platform.isDebugBuild()) {
-            System.out.println("Skip tests on non-debug builds because the required option TracePageSizes is a debug-only option.");
-            return;
-        }
-
         // Size that a single card covers.
         final int cardSize = 512;
         WhiteBox wb = WhiteBox.getWhiteBox();
@@ -159,4 +171,24 @@
         testVM("case5: only bitmap uses large pages (extra slack)", heapSizeForBitmapUsingLargePages + heapSizeDiffForBitmap, false, true);
         testVM("case6: nothing uses large pages (barely not)", heapSizeForBitmapUsingLargePages - heapSizeDiffForBitmap, false, false);
     }
+
+    public static long parseMemoryString(String value) {
+        long multiplier = 1;
+
+        if (value.endsWith("B")) {
+            multiplier = 1;
+        } else if (value.endsWith("K")) {
+            multiplier = 1024;
+        } else if (value.endsWith("M")) {
+            multiplier = 1024 * 1024;
+        } else if (value.endsWith("G")) {
+            multiplier = 1024 * 1024 * 1024;
+        } else {
+            throw new IllegalArgumentException("Expected memory string '" + value + "'to end with either of: B, K, M, G");
+        }
+
+        long longValue = Long.parseUnsignedLong(value.substring(0, value.length() - 1));
+
+        return longValue * multiplier;
+    }
 }
--- a/hotspot/test/gc/g1/humongousObjects/TestHumongousThreshold.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/test/gc/g1/humongousObjects/TestHumongousThreshold.java	Wed Jul 05 21:37:42 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
@@ -70,7 +70,7 @@
     private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
     private static final int REGION_SIZE = WHITE_BOX.g1RegionSize();
     private static final int MAX_CONTINUOUS_SIZE_CHECK = 129;
-    private static final int NON_HUMONGOUS_DIVIDER = 10;
+    private static final int NON_HUMONGOUS_STEPS = 10;
 
     /**
      * The method allocates byte[] with specified size and checks that:
@@ -84,7 +84,7 @@
      * @return allocated byte array
      */
 
-    private static byte[] allocateAndCheck(int arraySize, boolean expectedHumongous) {
+    private static void allocateAndCheck(int arraySize, boolean expectedHumongous) {
         byte[] storage = new byte[arraySize];
         long objectSize = WHITE_BOX.getObjectSize(storage);
         boolean shouldBeHumongous = objectSize > (REGION_SIZE / 2);
@@ -98,7 +98,6 @@
                 "Object should be allocated as " + (shouldBeHumongous ? "humongous"
                         : "non-humongous") + " but it wasn't; Allocation size = " + arraySize + "; Object size = "
                         + objectSize + "; region size = " + REGION_SIZE);
-        return storage;
     }
 
     public static void main(String[] args) {
@@ -108,7 +107,7 @@
         int maxByteArrayNonHumongousSize = (REGION_SIZE / 2) - byteArrayMemoryOverhead;
 
         // Increment for non-humongous testing
-        int nonHumongousStep = maxByteArrayNonHumongousSize / NON_HUMONGOUS_DIVIDER;
+        int nonHumongousStep = maxByteArrayNonHumongousSize / NON_HUMONGOUS_STEPS;
 
         // Maximum byte[] that takes one region
         int maxByteArrayOneRegionSize = REGION_SIZE - byteArrayMemoryOverhead;
@@ -131,10 +130,10 @@
             allocateAndCheck(i, false);
         }
 
-        // Testing allocations with byte[] with length from 0 to nonHumongousStep * NON_HUMONGOUS_DIVIDER
+        // Testing allocations with byte[] with length from 0 to nonHumongousStep * NON_HUMONGOUS_STEPS
         System.out.format("Testing allocations with byte[] with length from 0 to %d with step %d%n",
-                nonHumongousStep * NON_HUMONGOUS_DIVIDER, nonHumongousStep);
-        for (int i = 0; i < NON_HUMONGOUS_DIVIDER; ++i) {
+                nonHumongousStep * NON_HUMONGOUS_STEPS, nonHumongousStep);
+        for (int i = 0; i < NON_HUMONGOUS_STEPS; ++i) {
             allocateAndCheck(i * nonHumongousStep, false);
         }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/g1/plab/TestPLABEvacuationFailure.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,203 @@
+/*
+ * 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 TestPLABEvacuationFailure
+ * @bug 8148376
+ * @summary Checks PLAB statistics on evacuation failure
+ * @requires vm.gc=="G1" | vm.gc=="null"
+ * @library /testlibrary /
+ * @modules java.management
+ * @build gc.g1.plab.lib.LogParser
+ *        gc.g1.plab.lib.AppPLABEvacuationFailure
+ * @run main gc.g1.plab.TestPLABEvacuationFailure
+ */
+package gc.g1.plab;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+import jdk.test.lib.OutputAnalyzer;
+import jdk.test.lib.ProcessTools;
+import jdk.test.lib.Utils;
+
+import gc.g1.plab.lib.LogParser;
+import gc.g1.plab.lib.AppPLABEvacuationFailure;
+import gc.g1.plab.lib.PlabInfo;
+
+/**
+ * The test runs the AppPLABEvacuationFailure application to provoke a number of
+ * Evacuation Failures, parses GC log and analyzes PLAB statistics. The test checks
+ * that both fields 'failure_waste' and 'failure_used' for Evacuation Failure statistic
+ * are non zero, and zero for other statistics.
+ */
+public class TestPLABEvacuationFailure {
+
+    /* PLAB statistics fields which are checked.
+     * Test expects to find 0 in this fields in survivor statistics.
+     * Expects to find 0 in old statistics for GC when evacuation failure
+     * did not happen. And expects to find not 0 in old statistics in case when
+     * GC causes to evacuation failure.
+     */
+    private static final List<String> FAILURE_STAT_FIELDS = new ArrayList<>(Arrays.asList(
+            "failure used",
+            "failure wasted"));
+
+    private static final String[] COMMON_OPTIONS = {
+        "-Xlog:gc=debug,gc+plab=debug,gc+phases=trace",
+        "-XX:+UseG1GC",
+        "-XX:InitiatingHeapOccupancyPercent=100",
+        "-XX:-G1UseAdaptiveIHOP",
+        "-XX:G1HeapRegionSize=1m"};
+
+    private static final Pattern GC_ID_PATTERN = Pattern.compile("GC\\((\\d+)\\)");
+    private static List<Long> evacuationFailureIDs;
+    private static LogParser logParser;
+    private static String appPlabEvacFailureOutput;
+
+    public static void main(String[] args) throws Throwable {
+        // ParallelGCBufferWastePct, PLAB Size, ParallelGCBufferWastePct, MaxHeapSize, is plab fixed.
+        runTest(10, 1024, 3, 16, true);
+        runTest(15, 2048, 4, 256, true);
+        runTest(20, 65536, 7, 128, false);
+        runTest(25, 1024, 3, 16, true);
+        runTest(30, 16384, 7, 256, false);
+        runTest(10, 65536, 4, 32, false);
+    }
+
+    private static void runTest(int wastePct, int plabSize, int parGCThreads, int heapSize, boolean plabIsFixed) throws Throwable {
+        System.out.println("Test case details:");
+        System.out.println("  Heap size : " + heapSize + "M");
+        System.out.println("  Initial PLAB size : " + plabSize);
+        System.out.println("  Parallel GC buffer waste pct : " + wastePct);
+        System.out.println("  Parallel GC threads : " + parGCThreads);
+        System.out.println("  PLAB size is fixed: " + (plabIsFixed ? "yes" : "no"));
+        // Set up test GC and PLAB options
+        List<String> testOptions = new ArrayList<>();
+        Collections.addAll(testOptions, COMMON_OPTIONS);
+        Collections.addAll(testOptions, Utils.getTestJavaOpts());
+        Collections.addAll(testOptions,
+                "-XX:ParallelGCThreads=" + parGCThreads,
+                "-XX:ParallelGCBufferWastePct=" + wastePct,
+                "-XX:OldPLABSize=" + plabSize,
+                "-XX:YoungPLABSize=" + plabSize,
+                "-XX:" + (plabIsFixed ? "-" : "+") + "ResizePLAB",
+                "-XX:MaxHeapSize=" + heapSize + "m");
+        testOptions.add(AppPLABEvacuationFailure.class.getName());
+        OutputAnalyzer out = ProcessTools.executeTestJvm(testOptions.toArray(new String[testOptions.size()]));
+
+        appPlabEvacFailureOutput = out.getOutput();
+        if (out.getExitValue() != 0) {
+            System.out.println(appPlabEvacFailureOutput);
+            throw new RuntimeException("Expect exit code 0.");
+        }
+        // Get list of GC ID on evacuation failure
+        evacuationFailureIDs = getGcIdPlabEvacFailures(out);
+        logParser = new LogParser(appPlabEvacFailureOutput);
+        checkResults();
+    }
+
+    private static void checkResults() {
+
+        if (evacuationFailureIDs.isEmpty()) {
+            System.out.println(appPlabEvacFailureOutput);
+            throw new RuntimeException("AppPLABEvacuationFailure did not reach Evacuation Failure.");
+        }
+
+        Map<Long, PlabInfo> valuesToCheck = getNonEvacFailureSurvivorStats();
+        checkValuesIsZero(valuesToCheck, "Expect that SURVIVOR PLAB failure statistics should be 0 when no evacuation failure");
+
+        valuesToCheck = getNonEvacFailureOldStats();
+        checkValuesIsZero(valuesToCheck, "Expect that OLD PLAB failure statistics should be 0 when no evacuation failure");
+
+        valuesToCheck = getEvacFailureSurvivorStats();
+        checkValuesIsZero(valuesToCheck, "Expect that failure statistics should be 0 in SURVIVOR PLAB statistics at evacuation failure");
+
+        valuesToCheck = getEvacFailureOldStats();
+        checkValuesIsNotZero(valuesToCheck, "Expect that failure statistics should not be 0 in OLD PLAB statistics at evacuation failure");
+    }
+
+    /**
+     * Checks logItems for non-zero values. Throws RuntimeException if found.
+     *
+     * @param logItems
+     * @param errorMessage
+     */
+    private static void checkValuesIsZero(Map<Long, PlabInfo> logItems, String errorMessage) {
+        checkValues(logItems, errorMessage, true);
+    }
+
+    /**
+     * Checks logItems for zero values. Throws RuntimeException if found.
+     *
+     * @param logItems
+     * @param errorMessage
+     */
+    private static void checkValuesIsNotZero(Map<Long, PlabInfo> logItems, String errorMessage) {
+        checkValues(logItems, errorMessage, false);
+    }
+
+    private static void checkValues(Map<Long, PlabInfo> logItems, String errorMessage, boolean expectZero) {
+        logItems.entrySet()
+                .forEach(item -> item.getValue()
+                        .values()
+                        .forEach(items -> {
+                            if (expectZero != (items == 0)) {
+                                System.out.println(appPlabEvacFailureOutput);
+                                throw new RuntimeException(errorMessage);
+                            }
+                        })
+                );
+    }
+
+    /**
+     * For tracking PLAB statistics for specified PLAB type - survivor and old
+     */
+    private static Map<Long, PlabInfo> getNonEvacFailureSurvivorStats() {
+        return logParser.getExcludedSpecifiedStats(evacuationFailureIDs, LogParser.ReportType.SURVIVOR_STATS, FAILURE_STAT_FIELDS);
+    }
+
+    private static Map<Long, PlabInfo> getNonEvacFailureOldStats() {
+        return logParser.getExcludedSpecifiedStats(evacuationFailureIDs, LogParser.ReportType.OLD_STATS, FAILURE_STAT_FIELDS);
+    }
+
+    private static Map<Long, PlabInfo> getEvacFailureSurvivorStats() {
+        return logParser.getSpecifiedStats(evacuationFailureIDs, LogParser.ReportType.SURVIVOR_STATS, FAILURE_STAT_FIELDS);
+    }
+
+    private static Map<Long, PlabInfo> getEvacFailureOldStats() {
+        return logParser.getSpecifiedStats(evacuationFailureIDs, LogParser.ReportType.OLD_STATS, FAILURE_STAT_FIELDS);
+    }
+
+    private static List<Long> getGcIdPlabEvacFailures(OutputAnalyzer out) {
+        return out.asLines().stream()
+                .filter(line -> line.contains("Evacuation Failure"))
+                .map(line -> LogParser.getGcIdFromLine(line, GC_ID_PATTERN))
+                .collect(Collectors.toList());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/g1/plab/lib/AppPLABEvacuationFailure.java	Wed Jul 05 21:37:42 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.
+ */
+package gc.g1.plab.lib;
+
+import java.util.ArrayList;
+
+/**
+ * Application that provokes Evacuation Failure
+ */
+public class AppPLABEvacuationFailure {
+
+    public static final int CHUNK = 10000;
+    public static ArrayList<Object> arr = new ArrayList<>();
+
+    public static void main(String[] args) {
+        System.gc();
+        // First attempt.
+        try {
+            while (true) {
+                arr.add(new byte[CHUNK]);
+            }
+        } catch (OutOfMemoryError oome) {
+            arr.clear();
+        }
+        // Second attempt.
+        try {
+            while (true) {
+                arr.add(new byte[CHUNK]);
+            }
+        } catch (OutOfMemoryError oome) {
+            arr.clear();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/stress/TestGCOld.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,417 @@
+/*
+* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* This code is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License version 2 only, as
+* published by the Free Software Foundation.
+*
+* This code is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+* version 2 for more details (a copy is included in the LICENSE file that
+* accompanied this code).
+*
+* You should have received a copy of the GNU General Public License version
+* 2 along with this work; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+*
+* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+* or visit www.oracle.com if you need additional information or have any
+* questions.
+*/
+
+/*
+ * @test TestGCOld
+ * @key gc
+ * @key stress
+ * @requires vm.gc=="null"
+ * @summary Stress the GC by trying to make old objects more likely to be garbage than young objects.
+ * @run main/othervm -Xmx384M -XX:+UseSerialGC TestGCOld 50 1 20 10 10000
+ * @run main/othervm -Xmx384M -XX:+UseParallelGC TestGCOld 50 1 20 10 10000
+ * @run main/othervm -Xmx384M -XX:+UseParallelGC -XX:-UseParallelOldGC TestGCOld 50 1 20 10 10000
+ * @run main/othervm -Xmx384M -XX:+UseConcMarkSweepGC TestGCOld 50 1 20 10 10000
+ * @run main/othervm -Xmx384M -XX:+UseG1GC TestGCOld 50 1 20 10 10000
+ */
+
+import java.text.*;
+import java.util.Random;
+
+class TreeNode {
+    public TreeNode left, right;
+    public int val;                // will always be the height of the tree
+}
+
+
+/* Args:
+   live-data-size: in megabytes (approximate, will be rounded down).
+   work: units of mutator non-allocation work per byte allocated,
+     (in unspecified units.  This will affect the promotion rate
+      printed at the end of the run: more mutator work per step implies
+      fewer steps per second implies fewer bytes promoted per second.)
+   short/long ratio: ratio of short-lived bytes allocated to long-lived
+      bytes allocated.
+   pointer mutation rate: number of pointer mutations per step.
+   steps: number of steps to do.
+*/
+
+public class TestGCOld {
+
+  // Command-line parameters.
+
+  private static int size, workUnits, promoteRate, ptrMutRate, steps;
+
+  // Constants.
+
+  private static final int MEG = 1000000;
+  private static final int INSIGNIFICANT = 999; // this many bytes don't matter
+  private static final int BYTES_PER_WORD = 4;
+  private static final int BYTES_PER_NODE = 20; // bytes per TreeNode
+  private static final int WORDS_DEAD = 100;    // size of young garbage object
+
+  private final static int treeHeight = 14;
+  private final static long treeSize = heightToBytes(treeHeight);
+
+  private static final String msg1
+    = "Usage: java TestGCOld <size> <work> <ratio> <mutation> <steps>";
+  private static final String msg2
+    = "  where <size> is the live storage in megabytes";
+  private static final String msg3
+    = "        <work> is the mutator work per step (arbitrary units)";
+  private static final String msg4
+    = "        <ratio> is the ratio of short-lived to long-lived allocation";
+  private static final String msg5
+    = "        <mutation> is the mutations per step";
+  private static final String msg6
+    = "        <steps> is the number of steps";
+
+  // Counters (and global variables that discourage optimization)
+
+  private static long youngBytes = 0;    // total young bytes allocated
+  private static long nodes = 0;         // total tree nodes allocated
+  private static long actuallyMut = 0;   // pointer mutations in old trees
+  private static long mutatorSum = 0;    // checksum to discourage optimization
+  public static int[] aexport;           // exported array to discourage opt
+
+  // Global variables.
+
+  private static TreeNode[] trees;
+  private static int where = 0;               // roving index into trees
+  private static Random rnd = new Random();
+
+  // Returns the height of the given tree.
+
+  private static int height (TreeNode t) {
+    if (t == null) {
+      return 0;
+    }
+    else {
+      return 1 + Math.max (height (t.left), height (t.right));
+    }
+  }
+
+  // Returns the length of the shortest path in the given tree.
+
+  private static int shortestPath (TreeNode t) {
+    if (t == null) {
+      return 0;
+    }
+    else {
+      return 1 + Math.min (shortestPath (t.left), shortestPath (t.right));
+    }
+  }
+
+  // Returns the number of nodes in a balanced tree of the given height.
+
+  private static long heightToNodes (int h) {
+    if (h == 0) {
+      return 0;
+    }
+    else {
+      long n = 1;
+      while (h > 1) {
+        n = n + n;
+        h = h - 1;
+      }
+      return n + n - 1;
+    }
+  }
+
+  // Returns the number of bytes in a balanced tree of the given height.
+
+  private static long heightToBytes (int h) {
+    return BYTES_PER_NODE * heightToNodes (h);
+  }
+
+  // Returns the height of the largest balanced tree
+  // that has no more than the given number of nodes.
+
+  private static int nodesToHeight (long nodes) {
+    int h = 1;
+    long n = 1;
+    while (n + n - 1 <= nodes) {
+      n = n + n;
+      h = h + 1;
+    }
+    return h - 1;
+  }
+
+  // Returns the height of the largest balanced tree
+  // that occupies no more than the given number of bytes.
+
+  private static int bytesToHeight (long bytes) {
+    return nodesToHeight (bytes / BYTES_PER_NODE);
+  }
+
+  // Returns a newly allocated balanced binary tree of height h.
+
+  private static TreeNode makeTree(int h) {
+    if (h == 0) return null;
+    else {
+      TreeNode res = new TreeNode();
+      nodes++;
+      res.left = makeTree(h-1);
+      res.right = makeTree(h-1);
+      res.val = h;
+      return res;
+    }
+  }
+
+  // Allocates approximately size megabytes of trees and stores
+  // them into a global array.
+
+  private static void init() {
+    int ntrees = (int) ((size * MEG) / treeSize);
+    trees = new TreeNode[ntrees];
+
+    System.err.println("Allocating " + ntrees + " trees.");
+    System.err.println("  (" + (ntrees * treeSize) + " bytes)");
+    for (int i = 0; i < ntrees; i++) {
+      trees[i] = makeTree(treeHeight);
+      // doYoungGenAlloc(promoteRate*ntrees*treeSize, WORDS_DEAD);
+    }
+    System.err.println("  (" + nodes + " nodes)");
+
+    /* Allow any in-progress GC to catch up... */
+    // try { Thread.sleep(20000); } catch (InterruptedException x) {}
+  }
+
+  // Confirms that all trees are balanced and have the correct height.
+
+  private static void checkTrees() {
+    int ntrees = trees.length;
+    for (int i = 0; i < ntrees; i++) {
+      TreeNode t = trees[i];
+      int h1 = height(t);
+      int h2 = shortestPath(t);
+      if ((h1 != treeHeight) || (h2 != treeHeight)) {
+        System.err.println("*****BUG: " + h1 + " " + h2);
+      }
+    }
+  }
+
+  // Called only by replaceTree (below) and by itself.
+
+  private static void replaceTreeWork(TreeNode full, TreeNode partial, boolean dir) {
+    boolean canGoLeft = full.left != null && full.left.val > partial.val;
+    boolean canGoRight = full.right != null && full.right.val > partial.val;
+    if (canGoLeft && canGoRight) {
+      if (dir)
+        replaceTreeWork(full.left, partial, !dir);
+      else
+        replaceTreeWork(full.right, partial, !dir);
+    } else if (!canGoLeft && !canGoRight) {
+      if (dir)
+        full.left = partial;
+      else
+        full.right = partial;
+    } else if (!canGoLeft) {
+      full.left = partial;
+    } else {
+      full.right = partial;
+    }
+  }
+
+  // Given a balanced tree full and a smaller balanced tree partial,
+  // replaces an appropriate subtree of full by partial, taking care
+  // to preserve the shape of the full tree.
+
+  private static void replaceTree(TreeNode full, TreeNode partial) {
+    boolean dir = (partial.val % 2) == 0;
+    actuallyMut++;
+    replaceTreeWork(full, partial, dir);
+  }
+
+  // Allocates approximately n bytes of long-lived storage,
+  // replacing oldest existing long-lived storage.
+
+  private static void oldGenAlloc(long n) {
+    int full = (int) (n / treeSize);
+    long partial = n % treeSize;
+    // System.out.println("In oldGenAlloc, doing " + full + " full trees "
+    // + "and one partial tree of size " + partial);
+    for (int i = 0; i < full; i++) {
+      trees[where++] = makeTree(treeHeight);
+      if (where == trees.length) where = 0;
+    }
+    while (partial > INSIGNIFICANT) {
+      int h = bytesToHeight(partial);
+      TreeNode newTree = makeTree(h);
+      replaceTree(trees[where++], newTree);
+      if (where == trees.length) where = 0;
+      partial = partial - heightToBytes(h);
+    }
+  }
+
+  // Interchanges two randomly selected subtrees (of same size and depth).
+
+  private static void oldGenSwapSubtrees() {
+    // Randomly pick:
+    //   * two tree indices
+    //   * A depth
+    //   * A path to that depth.
+    int index1 = rnd.nextInt(trees.length);
+    int index2 = rnd.nextInt(trees.length);
+    int depth = rnd.nextInt(treeHeight);
+    int path = rnd.nextInt();
+    TreeNode tn1 = trees[index1];
+    TreeNode tn2 = trees[index2];
+    for (int i = 0; i < depth; i++) {
+      if ((path & 1) == 0) {
+        tn1 = tn1.left;
+        tn2 = tn2.left;
+      } else {
+        tn1 = tn1.right;
+        tn2 = tn2.right;
+      }
+      path >>= 1;
+    }
+    TreeNode tmp;
+    if ((path & 1) == 0) {
+      tmp = tn1.left;
+      tn1.left = tn2.left;
+      tn2.left = tmp;
+    } else {
+      tmp = tn1.right;
+      tn1.right = tn2.right;
+      tn2.right = tmp;
+    }
+    actuallyMut += 2;
+  }
+
+  // Update "n" old-generation pointers.
+
+  private static void oldGenMut(long n) {
+    for (int i = 0; i < n/2; i++) {
+      oldGenSwapSubtrees();
+    }
+  }
+
+  // Does the amount of mutator work appropriate for n bytes of young-gen
+  // garbage allocation.
+
+  private static void doMutWork(long n) {
+    int sum = 0;
+    long limit = workUnits*n/10;
+    for (long k = 0; k < limit; k++) sum++;
+    // We don't want dead code elimination to eliminate the loop above.
+    mutatorSum = mutatorSum + sum;
+  }
+
+  // Allocate n bytes of young-gen garbage, in units of "nwords"
+  // words.
+
+  private static void doYoungGenAlloc(long n, int nwords) {
+    final int nbytes = nwords*BYTES_PER_WORD;
+    int allocated = 0;
+    while (allocated < n) {
+      aexport = new int[nwords];
+      /* System.err.println("Step"); */
+      allocated += nbytes;
+    }
+    youngBytes = youngBytes + allocated;
+  }
+
+  // Allocate "n" bytes of young-gen data; and do the
+  // corresponding amount of old-gen allocation and pointer
+  // mutation.
+
+  // oldGenAlloc may perform some mutations, so this code
+  // takes those mutations into account.
+
+  private static void doStep(long n) {
+    long mutations = actuallyMut;
+
+    doYoungGenAlloc(n, WORDS_DEAD);
+    doMutWork(n);
+    oldGenAlloc(n / promoteRate);
+    oldGenMut(Math.max(0L, (mutations + ptrMutRate) - actuallyMut));
+  }
+
+  public static void main(String[] args) {
+    if (args.length != 5) {
+      System.err.println(msg1);
+      System.err.println(msg2);
+      System.err.println(msg3);
+      System.err.println(msg4);
+      System.err.println(msg5);
+      System.err.println(msg6);
+      return;
+    }
+
+    size = Integer.parseInt(args[0]);
+    workUnits = Integer.parseInt(args[1]);
+    promoteRate = Integer.parseInt(args[2]);
+    ptrMutRate = Integer.parseInt(args[3]);
+    steps = Integer.parseInt(args[4]);
+
+    System.out.println(size + " megabytes of live storage");
+    System.out.println(workUnits + " work units per step");
+    System.out.println("promotion ratio is 1:" + promoteRate);
+    System.out.println("pointer mutation rate is " + ptrMutRate);
+    System.out.println(steps + " steps");
+
+    init();
+//  checkTrees();
+    youngBytes = 0;
+    nodes = 0;
+
+    System.err.println("Initialization complete...");
+
+    long start = System.currentTimeMillis();
+
+    for (int step = 0; step < steps; step++) {
+      doStep(MEG);
+    }
+
+    long end = System.currentTimeMillis();
+    float secs = ((float)(end-start))/1000.0F;
+
+//  checkTrees();
+
+    NumberFormat nf = NumberFormat.getInstance();
+    nf.setMaximumFractionDigits(1);
+    System.out.println("\nTook " + nf.format(secs) + " sec in steady state.");
+    nf.setMaximumFractionDigits(2);
+    System.out.println("Allocated " + steps + " Mb of young gen garbage"
+                       + " (= " + nf.format(((float)steps)/secs) +
+                       " Mb/sec)");
+    System.out.println("    (actually allocated " +
+                       nf.format(((float) youngBytes)/MEG) + " megabytes)");
+    float promoted = ((float)steps) / (float)promoteRate;
+    System.out.println("Promoted " + promoted +
+                       " Mb (= " + nf.format(promoted/secs) + " Mb/sec)");
+    System.out.println("    (actually promoted " +
+                       nf.format(((float) (nodes * BYTES_PER_NODE))/MEG) +
+                       " megabytes)");
+    if (ptrMutRate != 0) {
+      System.out.println("Mutated " + actuallyMut +
+                         " pointers (= " +
+                         nf.format(actuallyMut/secs) + " ptrs/sec)");
+
+    }
+    // This output serves mainly to discourage optimization.
+    System.out.println("Checksum = " + (mutatorSum + aexport.length));
+
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/stress/TestMultiThreadStressRSet.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,305 @@
+/*
+ * 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.io.PrintStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+import sun.hotspot.WhiteBox;
+
+/*
+ * @test TestMultiThreadStressRSet.java
+ * @key stress
+ * @requires vm.gc=="G1" | vm.gc=="null"
+ * @requires os.maxMemory > 2G
+ *
+ * @summary Stress G1 Remembered Set using multiple threads
+ * @library /test/lib /testlibrary
+ * @build sun.hotspot.WhiteBox
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ *                              sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ *   -XX:+UseG1GC -XX:G1SummarizeRSetStatsPeriod=1 -Xlog:gc
+ *   -Xmx500m -XX:G1HeapRegionSize=1m -XX:MaxGCPauseMillis=1000 TestMultiThreadStressRSet 10 4
+ *
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ *   -XX:+UseG1GC -XX:G1SummarizeRSetStatsPeriod=100 -Xlog:gc
+ *   -Xmx1G -XX:G1HeapRegionSize=8m -XX:MaxGCPauseMillis=1000 TestMultiThreadStressRSet 60 16
+ *
+ * @run main/othervm/timeout=700 -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ *   -XX:+UseG1GC -XX:G1SummarizeRSetStatsPeriod=100 -Xlog:gc
+ *   -Xmx500m -XX:G1HeapRegionSize=1m -XX:MaxGCPauseMillis=1000 TestMultiThreadStressRSet 600 32
+ */
+public class TestMultiThreadStressRSet {
+
+    private static final Random RND = new Random(2015 * 2016);
+    private static final WhiteBox WB = WhiteBox.getWhiteBox();
+    private static final int REF_SIZE = WB.getHeapOopSize();
+    private static final int REGION_SIZE = WB.g1RegionSize();
+
+    // How many regions to use for the storage
+    private static final int STORAGE_REGIONS = 20;
+
+    // Size a single obj in the storage
+    private static final int OBJ_SIZE = 1024;
+
+    // How many regions of young/old gen to use in the BUFFER
+    private static final int BUFFER_YOUNG_REGIONS = 60;
+    private static final int BUFFER_OLD_REGIONS = 40;
+
+    // Total number of objects in the storage.
+    private final int N;
+
+    // The storage of byte[]
+    private final List<Object> STORAGE;
+
+    // Where references to the Storage will be stored
+    private final List<Object[]> BUFFER;
+
+    // The length of a buffer element.
+    // RSet deals with "cards" (areas of 512 bytes), not with single refs
+    // So, to affect the RSet the BUFFER refs should be allocated in different
+    // memory cards.
+    private final int BUF_ARR_LEN = 100 * (512 / REF_SIZE);
+
+    // Total number of objects in the young/old buffers
+    private final int YOUNG;
+    private final int OLD;
+
+    // To cause Remembered Sets change their coarse level the test uses a window
+    // within STORAGE. All the BUFFER elements refer to only STORAGE objects
+    // from the current window. The window is defined by a range.
+    // The first element has got the index: 'windowStart',
+    // the last one: 'windowStart + windowSize - 1'
+    // The window is shifting periodically.
+    private int windowStart;
+    private final int windowSize;
+
+    // Counter of created worker threads
+    private int counter = 0;
+
+    private volatile String errorMessage = null;
+    private volatile boolean isEnough = false;
+
+    public static void main(String args[]) {
+        if (args.length != 2) {
+            throw new IllegalArgumentException("TEST BUG: wrong arg count " + args.length);
+        }
+        long time = Long.parseLong(args[0]);
+        int threads = Integer.parseInt(args[1]);
+        new TestMultiThreadStressRSet().test(time * 1000, threads);
+    }
+
+    /**
+     * Initiates test parameters, fills out the STORAGE and BUFFER.
+     */
+    public TestMultiThreadStressRSet() {
+
+        N = (REGION_SIZE - 1) * STORAGE_REGIONS / OBJ_SIZE + 1;
+        STORAGE = new ArrayList<>(N);
+        int bytes = OBJ_SIZE - 20;
+        for (int i = 0; i < N - 1; i++) {
+            STORAGE.add(new byte[bytes]);
+        }
+        STORAGE.add(new byte[REGION_SIZE / 2 + 100]); // humongous
+        windowStart = 0;
+        windowSize = REGION_SIZE / OBJ_SIZE;
+
+        BUFFER = new ArrayList<>();
+        int sizeOfBufferObject = 20 + REF_SIZE * BUF_ARR_LEN;
+        OLD = REGION_SIZE * BUFFER_OLD_REGIONS / sizeOfBufferObject;
+        YOUNG = REGION_SIZE * BUFFER_YOUNG_REGIONS / sizeOfBufferObject;
+        for (int i = 0; i < OLD + YOUNG; i++) {
+            BUFFER.add(new Object[BUF_ARR_LEN]);
+        }
+    }
+
+    /**
+     * Does the testing. Steps:
+     * <ul>
+     * <li> starts the Shifter thread
+     * <li> during the given time starts new Worker threads, keeping the number
+     * of live thread under limit.
+     * <li> stops the Shifter thread
+     * </ul>
+     *
+     * @param timeInMillis how long to stress
+     * @param maxThreads the maximum number of Worker thread working together.
+     */
+    public void test(long timeInMillis, int maxThreads) {
+        if (timeInMillis <= 0 || maxThreads <= 0) {
+            throw new IllegalArgumentException("TEST BUG: be positive!");
+        }
+        System.out.println("%% Time to work: " + timeInMillis / 1000 + "s");
+        System.out.println("%% Number of threads: " + maxThreads);
+        long finish = System.currentTimeMillis() + timeInMillis;
+        Shifter shift = new Shifter(this, 1000, (int) (windowSize * 0.9));
+        shift.start();
+        for (int i = 0; i < maxThreads; i++) {
+            new Worker(this, 100).start();
+        }
+        try {
+            while (System.currentTimeMillis() < finish && errorMessage == null) {
+                Thread.sleep(100);
+            }
+        } catch (Throwable t) {
+            printAllStackTraces(System.err);
+            t.printStackTrace(System.err);
+            this.errorMessage = t.getMessage();
+        } finally {
+            isEnough = true;
+        }
+        System.out.println("%% Total work cycles: " + counter);
+        if (errorMessage != null) {
+            throw new RuntimeException(errorMessage);
+        }
+    }
+
+    /**
+     * Returns an element from from the BUFFER (an object array) to keep
+     * references to the storage.
+     *
+     * @return an Object[] from buffer.
+     */
+    private Object[] getFromBuffer() {
+        int index = counter % (OLD + YOUNG);
+        synchronized (BUFFER) {
+            if (index < OLD) {
+                if (counter % 100 == (counter / 100) % 100) {
+                    // need to generate garbage in the old gen to provoke mixed GC
+                    return replaceInBuffer(index);
+                } else {
+                    return BUFFER.get(index);
+                }
+            } else {
+                return replaceInBuffer(index);
+            }
+        }
+    }
+
+    private Object[] replaceInBuffer(int index) {
+        Object[] objs = new Object[BUF_ARR_LEN];
+        BUFFER.set(index, objs);
+        return objs;
+    }
+
+    /**
+     * Returns a random object from the current window within the storage.
+     * A storage element with index from windowStart to windowStart+windowSize.
+     *
+     * @return a random element from the current window within the storage.
+     */
+    private Object getRandomObject() {
+        int index = (windowStart + RND.nextInt(windowSize)) % N;
+        return STORAGE.get(index);
+    }
+
+    private static void printAllStackTraces(PrintStream ps) {
+        Map<Thread, StackTraceElement[]> traces = Thread.getAllStackTraces();
+        for (Thread t : traces.keySet()) {
+            ps.println(t.toString() + " " + t.getState());
+            for (StackTraceElement traceElement : traces.get(t)) {
+                ps.println("\tat " + traceElement);
+            }
+        }
+    }
+
+    /**
+     * Thread to create a number of references from BUFFER to STORAGE.
+     */
+    private static class Worker extends Thread {
+
+        final TestMultiThreadStressRSet boss;
+        final int refs; // number of refs to OldGen
+
+        /**
+         * @param boss the tests
+         * @param refsToOldGen how many references to the OldGen to create
+         */
+        Worker(TestMultiThreadStressRSet boss, int refsToOldGen) {
+            this.boss = boss;
+            this.refs = refsToOldGen;
+        }
+
+        @Override
+        public void run() {
+            try {
+                while (!boss.isEnough) {
+                    Object[] objs = boss.getFromBuffer();
+                    int step = objs.length / refs;
+                    for (int i = 0; i < refs; i += step) {
+                        objs[i] = boss.getRandomObject();
+                    }
+                    boss.counter++;
+                }
+            } catch (Throwable t) {
+                t.printStackTrace(System.out);
+                boss.errorMessage = t.getMessage();
+            }
+        }
+    }
+
+    /**
+     * Periodically shifts the current STORAGE window, removing references
+     * in BUFFER that refer to objects outside the window.
+     */
+    private static class Shifter extends Thread {
+
+        final TestMultiThreadStressRSet boss;
+        final int sleepTime;
+        final int shift;
+
+        Shifter(TestMultiThreadStressRSet boss, int sleepTime, int shift) {
+            this.boss = boss;
+            this.sleepTime = sleepTime;
+            this.shift = shift;
+        }
+
+        @Override
+        public void run() {
+            try {
+                while (!boss.isEnough) {
+                    Thread.sleep(sleepTime);
+                    boss.windowStart += shift;
+                    for (int i = 0; i < boss.OLD; i++) {
+                        Object[] objs = boss.BUFFER.get(i);
+                        for (int j = 0; j < objs.length; j++) {
+                            objs[j] = null;
+                        }
+                    }
+                    if (!WB.g1InConcurrentMark()) {
+                        System.out.println("%% start CMC");
+                        WB.g1StartConcMarkCycle();
+                    } else {
+                        System.out.println("%% CMC is already in progress");
+                    }
+                }
+            } catch (Throwable t) {
+                t.printStackTrace(System.out);
+                boss.errorMessage = t.getMessage();
+            }
+        }
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/stress/TestStressIHOPMultiThread.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,216 @@
+/*
+ * 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 TestStressIHOPMultiThread
+ * @bug 8148397
+ * @key stress
+ * @summary Stress test for IHOP
+ * @requires vm.gc=="G1" | vm.gc=="null"
+ * @run main/othervm/timeout=200 -Xmx128m -XX:G1HeapWastePercent=0 -XX:G1MixedGCCountTarget=1
+ *              -XX:+UseG1GC -XX:G1HeapRegionSize=1m -XX:+G1UseAdaptiveIHOP
+ *              -Xlog:gc+ihop=debug,gc+ihop+ergo=debug,gc+ergo=debug:TestStressIHOPMultiThread1.log
+ *              -Dtimeout=2 -DheapUsageMinBound=30 -DheapUsageMaxBound=80
+ *              -Dthreads=2 TestStressIHOPMultiThread
+ * @run main/othervm/timeout=200 -Xmx256m -XX:G1HeapWastePercent=0 -XX:G1MixedGCCountTarget=1
+ *              -XX:+UseG1GC -XX:G1HeapRegionSize=2m -XX:+G1UseAdaptiveIHOP
+ *              -Xlog:gc+ihop=debug,gc+ihop+ergo=debug,gc+ergo=debug:TestStressIHOPMultiThread2.log
+ *              -Dtimeout=2 -DheapUsageMinBound=60 -DheapUsageMaxBound=90
+ *              -Dthreads=3 TestStressIHOPMultiThread
+ * @run main/othervm/timeout=200 -Xmx256m -XX:G1HeapWastePercent=0 -XX:G1MixedGCCountTarget=1
+ *              -XX:+UseG1GC -XX:G1HeapRegionSize=4m -XX:-G1UseAdaptiveIHOP
+ *              -Xlog:gc+ihop=debug,gc+ihop+ergo=debug,gc+ergo=debug:TestStressIHOPMultiThread3.log
+ *              -Dtimeout=2 -DheapUsageMinBound=40 -DheapUsageMaxBound=90
+ *              -Dthreads=5 TestStressIHOPMultiThread
+ * @run main/othervm/timeout=200 -Xmx128m -XX:G1HeapWastePercent=0 -XX:G1MixedGCCountTarget=1
+ *              -XX:+UseG1GC -XX:G1HeapRegionSize=8m -XX:+G1UseAdaptiveIHOP
+ *              -Xlog:gc+ihop=debug,gc+ihop+ergo=debug,gc+ergo=debug:TestStressIHOPMultiThread4.log
+ *              -Dtimeout=2 -DheapUsageMinBound=20 -DheapUsageMaxBound=90
+ *              -Dthreads=10 TestStressIHOPMultiThread
+ * @run main/othervm/timeout=200 -Xmx512m -XX:G1HeapWastePercent=0 -XX:G1MixedGCCountTarget=1
+ *              -XX:+UseG1GC -XX:G1HeapRegionSize=16m -XX:+G1UseAdaptiveIHOP
+ *              -Xlog:gc+ihop=debug,gc+ihop+ergo=debug,gc+ergo=debug:TestStressIHOPMultiThread5.log
+ *              -Dtimeout=2 -DheapUsageMinBound=20 -DheapUsageMaxBound=90
+ *              -Dthreads=17 TestStressIHOPMultiThread
+ */
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Stress test for Adaptive IHOP. Starts a number of threads that fill and free
+ * specified amount of memory. Tests work with enabled IHOP logging.
+ *
+ */
+public class TestStressIHOPMultiThread {
+
+    public final static List<Object> GARBAGE = new LinkedList<>();
+
+    private final long HEAP_SIZE;
+    // Amount of memory to be allocated before iterations start
+    private final long HEAP_PREALLOC_SIZE;
+    // Amount of memory to be allocated and freed during iterations
+    private final long HEAP_ALLOC_SIZE;
+    private final int CHUNK_SIZE = 100000;
+
+    private final int TIMEOUT;
+    private final int THREADS;
+    private final int HEAP_LOW_BOUND;
+    private final int HEAP_HIGH_BOUND;
+
+    private volatile boolean running = true;
+    private final List<AllocationThread> threads;
+
+    public static void main(String[] args) throws InterruptedException {
+        new TestStressIHOPMultiThread().start();
+
+    }
+
+    TestStressIHOPMultiThread() {
+
+        TIMEOUT = Integer.getInteger("timeout") * 60;
+        THREADS = Integer.getInteger("threads");
+        HEAP_LOW_BOUND = Integer.getInteger("heapUsageMinBound");
+        HEAP_HIGH_BOUND = Integer.getInteger("heapUsageMaxBound");
+        HEAP_SIZE = Runtime.getRuntime().maxMemory();
+
+        HEAP_PREALLOC_SIZE = HEAP_SIZE * HEAP_LOW_BOUND / 100;
+        HEAP_ALLOC_SIZE = HEAP_SIZE * (HEAP_HIGH_BOUND - HEAP_LOW_BOUND) / 100;
+
+        threads = new ArrayList<>(THREADS);
+    }
+
+    public void start() throws InterruptedException {
+        fill();
+        createThreads();
+        waitForStress();
+        stressDone();
+        waitForFinish();
+    }
+
+    /**
+     * Fills HEAP_PREALLOC_SIZE bytes of garbage.
+     */
+    private void fill() {
+        long allocated = 0;
+        while (allocated < HEAP_PREALLOC_SIZE) {
+            GARBAGE.add(new byte[CHUNK_SIZE]);
+            allocated += CHUNK_SIZE;
+        }
+    }
+
+    /**
+     * Creates a number of threads which will fill and free amount of memory.
+     */
+    private void createThreads() {
+        for (int i = 0; i < THREADS; ++i) {
+            System.out.println("Create thread " + i);
+            AllocationThread thread =new TestStressIHOPMultiThread.AllocationThread(i, HEAP_ALLOC_SIZE / THREADS);
+            // Put reference to thread garbage into common garbage for avoiding possible optimization.
+            GARBAGE.add(thread.getList());
+            threads.add(thread);
+        }
+        threads.forEach(t -> t.start());
+    }
+
+    /**
+     * Wait each thread for finishing
+     */
+    private void waitForFinish() {
+        threads.forEach(thread -> {
+            thread.silentJoin();
+        });
+    }
+
+    private boolean isRunning() {
+        return running;
+    }
+
+    private void stressDone() {
+        running = false;
+    }
+
+    private void waitForStress() throws InterruptedException {
+        Thread.sleep(TIMEOUT * 1000);
+    }
+
+    private class AllocationThread extends Thread {
+
+        private final List<Object> garbage;
+
+        private final long amountOfGarbage;
+        private final int threadId;
+
+        public AllocationThread(int id, long amount) {
+            super("Thread " + id);
+            threadId = id;
+            amountOfGarbage = amount;
+            garbage = new LinkedList<>();
+        }
+
+        /**
+         * Returns list of garbage.
+         * @return List with thread garbage.
+         */
+        public List<Object> getList(){
+            return garbage;
+        }
+
+        @Override
+        public void run() {
+            System.out.println("Start the thread " + threadId);
+            while (TestStressIHOPMultiThread.this.isRunning()) {
+                allocate(amountOfGarbage);
+                free();
+            }
+        }
+
+        private void silentJoin() {
+            System.out.println("Join the thread " + threadId);
+            try {
+                join();
+            } catch (InterruptedException ie) {
+                throw new RuntimeException(ie);
+            }
+        }
+
+        /**
+         * Allocates thread local garbage
+         */
+        private void allocate(long amount) {
+            long allocated = 0;
+            while (allocated < amount && TestStressIHOPMultiThread.this.isRunning()) {
+                garbage.add(new byte[CHUNK_SIZE]);
+                allocated += CHUNK_SIZE;
+            }
+        }
+
+        /**
+         * Frees thread local garbage
+         */
+        private void free() {
+            garbage.clear();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/stress/TestStressRSetCoarsening.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,342 @@
+/*
+ * 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.util.concurrent.TimeoutException;
+import sun.hotspot.WhiteBox;
+
+/*
+ * @test TestStressRSetCoarsening.java
+ * @key stress
+ * @bug 8146984 8147087
+ * @requires vm.gc=="G1" | vm.gc=="null"
+ * @requires os.maxMemory > 3G
+ *
+ * @summary Stress G1 Remembered Set by creating a lot of cross region links
+ * @modules java.base/jdk.internal.misc
+ * @library /testlibrary /test/lib
+ * @build sun.hotspot.WhiteBox
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ *                              sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm/timeout=300
+ *     -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ *     -XX:+UseG1GC -Xlog:gc* -XX:MaxGCPauseMillis=1000
+ *     -Xmx500m -XX:G1HeapRegionSize=1m TestStressRSetCoarsening  1  0 300
+ * @run main/othervm/timeout=300
+ *     -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ *     -XX:+UseG1GC -Xlog:gc* -XX:MaxGCPauseMillis=1000
+ *     -Xmx500m -XX:G1HeapRegionSize=8m TestStressRSetCoarsening  1 10 300
+ * @run main/othervm/timeout=300
+ *     -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ *     -XX:+UseG1GC -Xlog:gc* -XX:MaxGCPauseMillis=1000
+ *     -Xmx500m -XX:G1HeapRegionSize=32m TestStressRSetCoarsening 42 10 300
+ * @run main/othervm/timeout=300
+ *     -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ *     -XX:+UseG1GC -Xlog:gc* -XX:MaxGCPauseMillis=1000
+ *     -Xmx500m -XX:G1HeapRegionSize=1m TestStressRSetCoarsening  2 0 300
+ * @run main/othervm/timeout=1800
+ *     -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ *     -XX:+UseG1GC -Xlog:gc* -XX:MaxGCPauseMillis=1000
+ *     -Xmx1G -XX:G1HeapRegionSize=1m TestStressRSetCoarsening 500 0  1800
+ * @run main/othervm/timeout=1800
+ *     -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ *     -XX:+UseG1GC -Xlog:gc* -XX:MaxGCPauseMillis=1000
+ *     -Xmx1G -XX:G1HeapRegionSize=1m TestStressRSetCoarsening 10  10 1800
+ */
+
+/**
+ * What the test does.
+ * Preparation stage:
+ *   Fill out ~90% of the heap with objects, each object is an object array.
+ *   If we want to allocate K objects per region, we calculate N to meet:
+ *      sizeOf(Object[N]) ~= regionSize / K
+ * Stress stage:
+ *   No more allocation, so no more GC.
+ *   We will perform a number of  iterations. On each iteration i,
+ *   for each pair of regions Rx and Ry we will set c[i] references
+ *   from Rx to Ry. If c[i] less than c[i-1] at the end of iteration
+ *   concurrent mark cycle will be initiated (to recalculate remembered sets).
+ *   As the result RSet will be growing up and down, up and down many times.
+ *
+ * The test expects: no crash and no timeouts.
+ *
+ * Test Parameters:
+ *   args[0] - number of objects per Heap Region (1 - means humongous)
+ *   args[1] - number of regions to refresh to provoke GC at the end of cycle.
+ *             (0 - means no GC, i.e. no reading from RSet)
+ *   args[2] - timeout in seconds (to stop execution to avoid jtreg timeout)
+ */
+public class TestStressRSetCoarsening {
+
+    public static void main(String... args) throws InterruptedException {
+        if (args.length != 3) {
+            throw new IllegalArgumentException("Wrong number of arguments " + args.length);
+        }
+        int objectsPerRegion = Integer.parseInt(args[0]); // 1 means humongous
+        int regsToRefresh = Integer.parseInt(args[1]);  // 0 means no regions to refresh at the end of cycle
+        int timeout = Integer.parseInt(args[2]); // in seconds, test should stop working eariler
+        new TestStressRSetCoarsening(objectsPerRegion, regsToRefresh, timeout).go();
+    }
+
+    private static final long KB = 1024;
+    private static final long MB = 1024 * KB;
+
+    private static final WhiteBox WB = WhiteBox.getWhiteBox();
+
+    public final Object[][] storage;
+
+    /**
+     * Number of objects per region. This is a test parameter.
+     */
+    public final int K;
+
+    /**
+     * Length of object array: sizeOf(Object[N]) ~= regionSize / K
+     * N will be calculated as function of K.
+     */
+    public final int N;
+
+    /**
+     * How many regions involved into testing.
+     * Will be calculated as heapFractionToAllocate * freeRegionCount.
+     */
+    public final int regionCount;
+
+    /**
+     * How much heap to use.
+     */
+    public final float heapFractionToAllocate = 0.9f;
+
+    /**
+     * How many regions to be refreshed at the end of cycle.
+     * This is a test parameter.
+     */
+    public final int regsToRefresh;
+
+    /**
+     * Initial time.
+     */
+    public final long start;
+
+    /**
+     * Time when the test should stop working.
+     */
+    public final long finishAt;
+
+    /**
+     * Does pre-calculation and allocate necessary objects.
+     *
+     * @param objPerRegions how many objects per G1 heap region
+     */
+    TestStressRSetCoarsening(int objPerRegions, int regsToRefresh, int timeout) {
+        this.K = objPerRegions;
+        this.regsToRefresh = regsToRefresh;
+        this.start = System.currentTimeMillis();
+        this.finishAt = start + timeout * 900; // 10% ahead of jtreg timeout
+
+        long regionSize = WB.g1RegionSize();
+
+        // How many free regions
+        Runtime rt = Runtime.getRuntime();
+        long used = rt.totalMemory() - rt.freeMemory();
+        long totalFree = rt.maxMemory() - used;
+        regionCount = (int) ((totalFree / regionSize) * heapFractionToAllocate);
+        long toAllocate = regionCount * regionSize;
+        System.out.println("%% Test parameters");
+        System.out.println("%%   Objects per region              : " + K);
+        System.out.println("%%   Heap fraction to allocate       : " + (int) (heapFractionToAllocate * 100) + "%");
+        System.out.println("%%   Regions to refresh to provoke GC: " + regsToRefresh);
+
+        System.out.println("%% Memory");
+        System.out.println("%%   used          :        " + used / MB + "M");
+        System.out.println("%%   available     :        " + totalFree / MB + "M");
+        System.out.println("%%   to allocate   :        " + toAllocate / MB + "M");
+        System.out.println("%%     (in regs)   :        " + regionCount);
+        System.out.println("%%   G1 Region Size:        " + regionSize / MB + "M");
+
+        int refSize = WB.getHeapOopSize();
+
+        // Calculate N:    K*sizeOf(Object[N]) ~= regionSize
+        //                 sizeOf(Object[N]) ~=  (N+4)*refSize
+        // ==>
+        //                 N = regionSize / K / refSize - 4;
+        int n = (int) ((regionSize / K) / refSize) - 5;  // best guess
+        long objSize = WB.getObjectSize(new Object[n]);
+        while (K*objSize > regionSize) {   // adjust to avoid OOME
+            n = n - 1;
+            objSize = WB.getObjectSize(new Object[n]);
+        }
+        N = n;
+
+        /*
+         *   --------------
+         *   region0   storage[0]        = new Object[N]
+         *             ...
+         *             storage[K-1]      = new Object[N]
+         *   ---------------
+         *   region1   storage[K]        = new Object[N]
+         *             ...
+         *             storage[2*K - 1]  = new Object[N]
+         *   --------------
+         *   ...
+         *   --------------
+         *   regionX   storage[X*K]         = new Object[N]
+         *             ...
+         *             storage[(X+1)*K -1]  = new Object[N]
+         *    where X = HeapFraction * TotalRegions
+         *   -------------
+         */
+        System.out.println("%% Objects");
+        System.out.println("%%   N (array length)      : " + N);
+        System.out.println("%%   K (objects in regions): " + K);
+        System.out.println("%%   Object size           : " + objSize +
+                "  (sizeOf(new Object[" + N + "])");
+        System.out.println("%%   Reference size        : " + refSize);
+
+        storage = new Object[regionCount * K][];
+        for (int i = 0; i < storage.length; i++) {
+            storage[i] = new Object[N];
+        }
+    }
+
+    public void go() throws InterruptedException {
+        // threshold for sparce -> fine
+        final int FINE = WB.getIntxVMFlag("G1RSetSparseRegionEntries").intValue();
+
+        // threshold for fine -> coarse
+        final int COARSE = WB.getIntxVMFlag("G1RSetRegionEntries").intValue();
+
+        // regToRegRefCounts - array of reference counts from region to region
+        // at the the end of iteration.
+        // The number of test iterations is array length - 1.
+        // If c[i] > c[i-1] then during the iteration i more references will
+        // be created.
+        // If c[i] < c[i-1] then some referenes will be cleaned.
+        int[] regToRegRefCounts = {0, FINE / 2, 0, FINE, (FINE + COARSE) / 2, 0,
+            COARSE, COARSE + 10, FINE + 1, FINE / 2, 0};
+
+        // For progress tracking
+        int[] progress = new int[regToRegRefCounts.length];
+        progress[0] = 0;
+        for (int i = 1; i < regToRegRefCounts.length; i++) {
+            progress[i] = progress[i - 1] + Math.abs(regToRegRefCounts[i] - regToRegRefCounts[i - 1]);
+        }
+        try {
+            for (int i = 1; i < regToRegRefCounts.length; i++) {
+                int pre = regToRegRefCounts[i - 1];
+                int cur = regToRegRefCounts[i];
+                float prog = ((float) progress[i - 1] / progress[progress.length - 1]);
+
+                System.out.println("%% step " + i
+                        + " out of " + (regToRegRefCounts.length - 1)
+                        + " (~" + (int) (100 * prog) + "% done)");
+                System.out.println("%%      " + pre + "  --> " + cur);
+                for (int to = 0; to < regionCount; to++) {
+                    // Select a celebrity object that we will install references to.
+                    // The celebrity will be referred from all other regions.
+                    // If the number of references after should be less than they
+                    // were before, select NULL.
+                    Object celebrity = cur > pre ? storage[to * K] : null;
+                    for (int from = 0; from < regionCount; from++) {
+                        if (to == from) {
+                            continue; // no need to refer to itself
+                        }
+
+                        int step = cur > pre ? +1 : -1;
+                        for (int rn = pre; rn != cur; rn += step) {
+                            storage[getY(to, from, rn)][getX(to, from, rn)] = celebrity;
+                            if (System.currentTimeMillis() > finishAt) {
+                                throw new TimeoutException();
+                            }
+                        }
+                    }
+                }
+                if (pre > cur) {
+                    // Number of references went down.
+                    // Need to provoke recalculation of RSet.
+                    WB.g1StartConcMarkCycle();
+                    while (WB.g1InConcurrentMark()) {
+                        Thread.sleep(1);
+                    }
+                }
+
+                // To force the use of rememebered set entries we need to provoke a GC.
+                // To induce some fragmentation, and some mixed GCs, we need
+                // to make a few objects unreachable.
+                for (int toClean = i * regsToRefresh; toClean < (i + 1) * regsToRefresh; toClean++) {
+                    int to = toClean % regionCount;
+                    // Need to remove all references from all regions to the region 'to'
+                    for (int from = 0; from < regionCount; from++) {
+                        if (to == from) {
+                            continue; // no need to refer to itself
+                        }
+                        for (int rn = 0; rn <= cur; rn++) {
+                            storage[getY(to, from, rn)][getX(to, from, rn)] = null;
+                        }
+                    }
+                    // 'Refresh' storage elements for the region 'to'
+                    // After that loop all 'old' objects in the region 'to'
+                    // should become unreachable.
+                    for (int k = 0; k < K; k++) {
+                        storage[(to * K + k) % storage.length] = new Object[N];
+                    }
+                }
+            }
+        } catch (TimeoutException e) {
+            System.out.println("%% TIMEOUT!!!");
+        }
+        long now = System.currentTimeMillis();
+        System.out.println("%% Summary");
+        System.out.println("%%   Time spent          : " + ((now - start) / 1000) + " seconds");
+        System.out.println("%%   Free memory left    : " + Runtime.getRuntime().freeMemory() / KB + "K");
+        System.out.println("%% Test passed");
+    }
+
+    /**
+     * Returns X index in the Storage of the reference #rn from the region
+     * 'from' to the region 'to'.
+     *
+     * @param to region # to refer to
+     * @param from region # to refer from
+     * @param rn number of reference
+     *
+     * @return X index in the range: [0 ... N-1]
+     */
+    private int getX(int to, int from, int rn) {
+        return (rn * regionCount + to) % N;
+    }
+
+    /**
+     * Returns Y index in the Storage of the reference #rn from the region
+     * 'from' to the region 'to'.
+     *
+     * @param to region # to refer to
+     * @param from region # to refer from
+     * @param rn number of reference
+     *
+     * @return Y index in the range: [0 ... K*regionCount -1]
+     */
+    private int getY(int to, int from, int rn) {
+        return ((rn * regionCount + to) / N + from * K) % (regionCount * K);
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/BoolReturn/BoolConstructor.java	Wed Jul 05 21:37:42 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.
+ */
+
+import jdk.test.lib.Asserts;
+
+public class BoolConstructor {
+
+    boolean field;
+    BoolConstructor(boolean b, boolean expected) {
+        field = b;
+        // System.out.println("b is " + b + " field is " + field);
+        Asserts.assertTrue(field == b, "BoolConstructor argument not converted correctly");
+        Asserts.assertTrue(field == expected, "BoolConstructor argument not stored correctly");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/BoolReturn/NativeSmallIntCallsTest.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,60 @@
+/*
+ * 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 8149170
+ * @summary Test native functions return booleans as 0/1 but differently than java functions
+ * @library /testlibrary
+ * @compile BoolConstructor.java
+ * @run main/native NativeSmallIntCallsTest
+ */
+
+// This test shows that returns from native calls for boolean truncate to JNI_TRUE if value != 0
+// and JNI_FALSE if value returned is 0.
+
+import jdk.test.lib.Asserts;
+
+public class NativeSmallIntCallsTest {
+    static native boolean nativeCastToBoolCallTrue();
+    static native boolean nativeCastToBoolCallFalse();
+    static native boolean nativeCallBoolConstructor(int visible, boolean expected);
+    static {
+        System.loadLibrary("NativeSmallIntCalls");
+    }
+
+    public static void main(java.lang.String[] unused) throws Exception {
+        // Call through jni
+        // JNI makes all results != 0 true for compatibility
+        boolean nativeTrueVal = nativeCastToBoolCallTrue();
+        Asserts.assertTrue(nativeTrueVal, "trueval is false!");
+
+        boolean nativeFalseVal = nativeCastToBoolCallFalse();
+        Asserts.assertTrue(nativeFalseVal, "falseval is false in native!");
+
+        // Call a constructor or method that passes jboolean values into Java from native
+        nativeCallBoolConstructor(1, true);
+        nativeCallBoolConstructor(0x10, true);
+        nativeCallBoolConstructor(0x100, false);
+        nativeCallBoolConstructor(0x1000, false);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/BoolReturn/libNativeSmallIntCalls.c	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,57 @@
+/*
+ * 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 <jni.h>
+
+JNIEXPORT void JNICALL
+Java_NativeSmallIntCallsTest_nativeCallBoolConstructor(JNIEnv* env, jobject obj, int visible, int expected) {
+    jclass cls;
+    jmethodID ctor;
+
+    cls = (*env)->FindClass(env, "BoolConstructor");
+    if(NULL == cls) {
+        return;
+    }
+
+    ctor = (*env)->GetMethodID(env, cls, "<init>", "(ZZ)V");
+    if(NULL == ctor) {
+        return;
+    }
+
+    // printf("visible 0x%x expected %d\n", visible, expected);
+
+    (*env)->NewObject(env, cls, ctor, (jboolean) visible, expected);
+}
+
+JNIEXPORT jboolean JNICALL
+Java_NativeSmallIntCallsTest_nativeCastToBoolCallTrue(JNIEnv* env, jobject obj) {
+
+    return 55;
+}
+
+JNIEXPORT jboolean JNICALL
+Java_NativeSmallIntCallsTest_nativeCastToBoolCallFalse(JNIEnv* env, jobject obj) {
+
+    return 44;
+}
+
--- a/hotspot/test/runtime/CompressedOops/CompressedClassPointers.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/test/runtime/CompressedOops/CompressedClassPointers.java	Wed Jul 05 21:37:42 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
@@ -85,8 +85,7 @@
     public static void heapBaseMinAddressTest() throws Exception {
         ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
             "-XX:HeapBaseMinAddress=1m",
-            "-XX:+UnlockDiagnosticVMOptions",
-            "-XX:+PrintCompressedOopsMode",
+            "-Xlog:gc+heap+coops=debug",
             "-version");
         OutputAnalyzer output = new OutputAnalyzer(pb.start());
         output.shouldContain("HeapBaseMinAddress must be at least");
--- a/hotspot/test/runtime/CompressedOops/UseCompressedOops.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/test/runtime/CompressedOops/UseCompressedOops.java	Wed Jul 05 21:37:42 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
@@ -169,7 +169,6 @@
         ArrayList<String> args = new ArrayList<>();
 
         // Always run with these three:
-        args.add("-XX:+UnlockDiagnosticVMOptions");
         args.add("-XX:+PrintCompressedOopsMode");
         args.add("-Xms32m");
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/Throwable/ThrowableIntrospectionSegfault.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,80 @@
+/*
+ * 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 8033735
+ * @summary check backtrace field introspection
+ * @library /testlibrary
+ * @run main ThrowableIntrospectionSegfault
+ */
+
+import java.lang.reflect.*;
+
+public class ThrowableIntrospectionSegfault {
+    public static void main(java.lang.String[] unused) {
+        // Construct a throwable object.
+        Throwable throwable = new Throwable();
+        throwable.fillInStackTrace();
+
+        // Retrieve a reflection handle to the private backtrace field.
+        Class class1 = throwable.getClass();
+        Field field;
+        try {
+            field = class1.getDeclaredField("backtrace");
+        }
+        catch (NoSuchFieldException e) {
+            System.err.println("Can't retrieve field handle Throwable.backtrace: " + e.toString());
+            return;
+        }
+        field.setAccessible(true);
+
+        // Retrieve the value of the backtrace field.
+        Object backtrace;
+        try {
+            backtrace = field.get(throwable);
+        }
+        catch (IllegalAccessException e) {
+            System.err.println( "Can't retrieve field value for Throwable.backtrace: " + e.toString());
+            return;
+        }
+
+        try {
+
+            // Retrieve the class of throwable.backtrace[0][0].
+            Class class2 = ((Object[]) ((Object[]) backtrace)[2])[0].getClass();
+
+            // Segfault occurs while executing this line, to retrieve the name of
+            // this class.
+            String class2Name = class2.getName();
+
+            System.err.println("class2Name=" + class2Name);
+            return;  // pass!   Passes if it doesn't crash.
+        } catch (ClassCastException e) {
+            // Passes if it doesn't crash. Also if the backtrace changes this test might get
+            // ClassCastException and that's ok too.
+            System.out.println("Catch exception " + e);
+            return;  // pass!   Passes if it doesn't crash.
+        }
+    }
+}
--- a/hotspot/test/runtime/logging/ClassInitializationTest.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/test/runtime/logging/ClassInitializationTest.java	Wed Jul 05 21:37:42 2017 +0200
@@ -62,6 +62,16 @@
             out.shouldContain("[Initialized").shouldContain("without side effects]");
             out.shouldHaveExitValue(0);
         }
+
+        // (3) classinit should turn off.
+        pb = ProcessTools.createJavaProcessBuilder("-Xlog:classinit=off",
+                                                   "-Xverify:all",
+                                                   "-Xmx64m",
+                                                   "BadMap50");
+        out = new OutputAnalyzer(pb.start());
+        out.shouldNotContain("[classinit]");
+        out.shouldNotContain("Fail over class verification to old verifier for: BadMap50");
+
     }
     public static class InnerClass {
         public static void main(String[] args) throws Exception {
--- a/hotspot/test/runtime/logging/ClassResolutionTest.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/test/runtime/logging/ClassResolutionTest.java	Wed Jul 05 21:37:42 2017 +0200
@@ -51,7 +51,8 @@
         };
 
         public static void main(String... args) throws Exception {
-            Thing1Handler.getThingNumber();
+            int x = Thing1Handler.getThingNumber();
+            System.out.println("ThingNumber: "+Integer.toString(x));
         }
     }
 
@@ -62,6 +63,7 @@
                                                                   ClassResolutionTestMain.class.getName());
         OutputAnalyzer o = new OutputAnalyzer(pb.start());
         o.shouldContain("[classresolve] ClassResolutionTest$ClassResolutionTestMain$Thing1Handler ClassResolutionTest$ClassResolutionTestMain$Thing1");
+        o.shouldContain("[classresolve] resolve JVM_CONSTANT_MethodHandle");
 
         // (2) classresolve should turn off.
         pb = ProcessTools.createJavaProcessBuilder("-Xlog:classresolve=debug",
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/logging/CompressedOopsTest.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,82 @@
+/*
+ * 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 8149991
+ * @requires (sun.arch.data.model == "64")
+ * @summary -Xlog:gc+heap+coops=info should have output from the code
+ * @library /testlibrary
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ * @build jdk.test.lib.OutputAnalyzer jdk.test.lib.Platform jdk.test.lib.ProcessTools
+ * @run driver CompressedOopsTest
+ */
+
+import jdk.test.lib.OutputAnalyzer;
+import jdk.test.lib.Platform;
+import jdk.test.lib.ProcessTools;
+
+public class CompressedOopsTest {
+    static void analyzeOutputOn(ProcessBuilder pb) throws Exception {
+        OutputAnalyzer output = new OutputAnalyzer(pb.start());
+        output.shouldContain("[gc,heap,coops] Heap address");
+        output.shouldHaveExitValue(0);
+    }
+
+    static void analyzeOutputOff(ProcessBuilder pb) throws Exception {
+        OutputAnalyzer output = new OutputAnalyzer(pb.start());
+        output.shouldNotContain("[gc,heap,coops]");
+        output.shouldHaveExitValue(0);
+    }
+
+    public static void main(String[] args) throws Exception {
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseCompressedOops",
+                                                   "-Xlog:gc+heap+coops=info",
+                                                   InnerClass.class.getName());
+        analyzeOutputOn(pb);
+
+        pb = ProcessTools.createJavaProcessBuilder("-XX:+UseCompressedOops",
+                                                   "-XX:+PrintCompressedOopsMode",
+                                                   InnerClass.class.getName());
+        analyzeOutputOn(pb);
+
+        pb = ProcessTools.createJavaProcessBuilder("-XX:+UseCompressedOops",
+                                                   "-XX:+PrintCompressedOopsMode",
+                                                   "-Xlog:gc+heap+coops=off",
+                                                   InnerClass.class.getName());
+        analyzeOutputOff(pb);
+
+        pb = ProcessTools.createJavaProcessBuilder("-XX:+UseCompressedOops",
+                                                   "-Xlog:gc+heap+coops=info",
+                                                   "-XX:-PrintCompressedOopsMode",
+                                                   InnerClass.class.getName());
+        analyzeOutputOff(pb);
+    }
+
+    public static class InnerClass {
+        public static void main(String[] args) throws Exception {
+            System.out.println("Compressed Oops (gc+heap+coops) test");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/logging/OsCpuLoggingTest.java	Wed Jul 05 21:37:42 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 8151939
+ * @summary os+cpu output should contain some os,cpu information
+ * @library /testlibrary
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ * @build jdk.test.lib.OutputAnalyzer jdk.test.lib.ProcessTools
+ * @run driver OsCpuLoggingTest
+ */
+
+import java.io.File;
+import java.util.Map;
+import jdk.test.lib.*;
+
+public class OsCpuLoggingTest {
+
+    static void analyzeOutputForOsLog(OutputAnalyzer output) throws Exception {
+        // Aix has it's own logging
+        if (!Platform.isAix()) {
+            output.shouldContain("SafePoint Polling address");
+        }
+        output.shouldHaveExitValue(0);
+    }
+
+    static void analyzeOutputForOsCpuLog(OutputAnalyzer output) throws Exception {
+        output.shouldContain("CPU:total");
+        output.shouldHaveExitValue(0);
+    }
+
+    public static void main(String[] args) throws Exception {
+
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xlog:os+cpu", "-version");
+        OutputAnalyzer output = new OutputAnalyzer(pb.start());
+        analyzeOutputForOsCpuLog(output);
+
+        pb = ProcessTools.createJavaProcessBuilder("-Xlog:os", "-version");
+        output = new OutputAnalyzer(pb.start());
+        analyzeOutputForOsLog(output);
+    }
+}
--- a/hotspot/test/runtime/modules/AccessCheck/ExportAllUnnamed.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/test/runtime/modules/AccessCheck/ExportAllUnnamed.java	Wed Jul 05 21:37:42 2017 +0200
@@ -28,11 +28,12 @@
  * @summary Test if package p2 in module m2 is exported to all unnamed,
  *          then class p1.c1 in an unnamed module can read p2.c2 in module m2.
  * @library /testlibrary /test/lib
+ * @modules java.base/jdk.internal.module
  * @compile myloaders/MySameClassLoader.java
  * @compile p2/c2.java
  * @compile p1/c1.java
- * @compile -XaddExports:java.base/jdk.internal.module=ALL-UNNAMED ExportAllUnnamed.java
- * @run main/othervm -XaddExports:java.base/jdk.internal.module=ALL-UNNAMED -Xbootclasspath/a:. ExportAllUnnamed
+ * @build ExportAllUnnamed
+ * @run main/othervm -Xbootclasspath/a:. ExportAllUnnamed
  */
 
 import static jdk.test.lib.Asserts.*;
--- a/hotspot/test/serviceability/logging/TestLogRotation.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/test/serviceability/logging/TestLogRotation.java	Wed Jul 05 21:37:42 2017 +0200
@@ -102,8 +102,10 @@
                 smallFilesNumber++;
             }
         }
-        if (logs.length != numberOfFiles) {
-            throw new Error("There are only " + logs.length + " logs instead " + numberOfFiles);
+        // Expect one more log file since the number-of-files doesn't include the active log file
+        int expectedNumberOfFiles = numberOfFiles + 1;
+        if (logs.length != expectedNumberOfFiles) {
+            throw new Error("There are " + logs.length + " logs instead of the expected " + expectedNumberOfFiles);
         }
         if (smallFilesNumber > 1) {
             throw new Error("There should maximum one log with size < " + logFileSizeK + "K");
--- a/hotspot/test/serviceability/logging/TestQuotedLogOutputs.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/test/serviceability/logging/TestQuotedLogOutputs.java	Wed Jul 05 21:37:42 2017 +0200
@@ -101,7 +101,7 @@
             output.shouldHaveExitValue(1);
             // Ensure error message was logged
             output.shouldMatch("([Mm]issing terminating quote)"
-                + "|(Could not open log file '')"
+                + "|(Error opening log file '')"
                 + "|(Output name can not be partially quoted)");
         }
     }
--- a/hotspot/test/serviceability/sa/DeadlockDetectionTest.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/test/serviceability/sa/DeadlockDetectionTest.java	Wed Jul 05 21:37:42 2017 +0200
@@ -80,6 +80,12 @@
             return;
         }
 
+        if (Platform.isOSX()) {
+            // Coredump stackwalking is not implemented for Darwin
+            System.out.println("This test is not expected to work on OS X. Skipping");
+            return;
+        }
+
 
         if (!LingeredApp.isLastModifiedWorking()) {
             // Exact behaviour of the test depends on operating system and the test nature,
--- a/hotspot/test/serviceability/tmtools/jstack/JstackThreadTest.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/test/serviceability/tmtools/jstack/JstackThreadTest.java	Wed Jul 05 21:37:42 2017 +0200
@@ -25,6 +25,8 @@
 import jdk.test.lib.JDKToolLauncher;
 import jdk.test.lib.OutputAnalyzer;
 import jdk.test.lib.ProcessTools;
+import utils.Utils;
+import java.util.concurrent.CountDownLatch;
 
 /*
  * @test JstackThreadTest
@@ -32,23 +34,22 @@
  * @summary jstack doesn't close quotation marks properly with threads' name greater than 1996 characters
  * @library /testlibrary
  * @build jdk.test.lib.*
- * @ignore 8153319
  * @run main JstackThreadTest
  */
 public class JstackThreadTest {
   static class NamedThread extends Thread {
-    NamedThread(String name) {
+   CountDownLatch latch;
+   NamedThread(String name, CountDownLatch latch) {
+      this.latch = latch;
       setName(name);
+
     }
     @Override
     public void run() {
-      try {
-            Thread.sleep(2000);
-          } catch(Exception e){
-            e.printStackTrace();
-          }
-        }
+     latch.countDown();
+     Utils.sleep();
     }
+   }
 
   public static void main(String[] args) throws Exception {
     StringBuilder sb = new StringBuilder();
@@ -60,8 +61,11 @@
   }
 
   private static void testWithName(String name) throws Exception {
+    //parent thread countDown latch
+    CountDownLatch latch = new CountDownLatch(1);
     // Start a thread with a long thread name
-    NamedThread thread = new NamedThread(name);
+    NamedThread thread = new NamedThread(name, latch);
+    thread.setDaemon(true);
     thread.start();
     ProcessBuilder processBuilder = new ProcessBuilder();
     JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jstack");
@@ -69,6 +73,8 @@
     launcher.addToolArg(Long.toString(ProcessTools.getProcessId()));
     processBuilder.command(launcher.getCommand());
     System.out.println(Arrays.toString(processBuilder.command().toArray()).replace(",", ""));
+    // Ensuring that Jstack will always run after NamedThread
+    latch.await();
     OutputAnalyzer output = ProcessTools.executeProcess(processBuilder);
     System.out.println(output.getOutput());
     output.shouldContain("\""+ name + "\"");
--- a/hotspot/test/serviceability/tmtools/jstat/GcCapacityTest.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/test/serviceability/tmtools/jstat/GcCapacityTest.java	Wed Jul 05 21:37:42 2017 +0200
@@ -27,13 +27,13 @@
  * @test
  * @summary Test checks the consistency of the output
  * displayed with jstat -gccapacity.
- * @ignore 8149778
  * @library /test/lib/share/classes
  * @library ../share
  * @requires vm.opt.ExplicitGCInvokesConcurrent != true
  * @build common.*
  * @build utils.*
- * @run main/othervm -XX:+UsePerfData GcCapacityTest
+ * @ignore 8149778
+ * @run main/othervm -XX:+UsePerfData -Xmx128M GcCapacityTest
  */
 public class GcCapacityTest {
 
--- a/hotspot/test/serviceability/tmtools/jstat/GcCauseTest01.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/test/serviceability/tmtools/jstat/GcCauseTest01.java	Wed Jul 05 21:37:42 2017 +0200
@@ -34,7 +34,7 @@
  * @build common.*
  * @build utils.*
  *
- * @run main/othervm -XX:+UsePerfData GcCauseTest01
+ * @run main/othervm -XX:+UsePerfData -Xmx128M GcCauseTest01
  */
 import utils.*;
 
--- a/hotspot/test/serviceability/tmtools/jstat/GcCauseTest02.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/test/serviceability/tmtools/jstat/GcCauseTest02.java	Wed Jul 05 21:37:42 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
@@ -32,7 +32,7 @@
  * @build common.*
  * @build utils.*
  *
- * @run main/othervm  -XX:+UsePerfData -Xms128M -XX:MaxMetaspaceSize=128M GcCauseTest02
+ * @run main/othervm -XX:+UsePerfData -Xmx128M -XX:MaxMetaspaceSize=128M GcCauseTest02
  */
 import utils.*;
 
--- a/hotspot/test/serviceability/tmtools/jstat/GcCauseTest03.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/test/serviceability/tmtools/jstat/GcCauseTest03.java	Wed Jul 05 21:37:42 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
@@ -32,7 +32,7 @@
  * @build common.*
  * @build utils.*
  *
- * @run main/othervm  -XX:+UsePerfData -Xms128M -XX:MaxMetaspaceSize=128M GcCauseTest03
+ * @run main/othervm -XX:+UsePerfData -Xmx128M -XX:MaxMetaspaceSize=128M GcCauseTest03
  */
 import utils.*;
 
--- a/hotspot/test/serviceability/tmtools/jstat/GcNewTest.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/test/serviceability/tmtools/jstat/GcNewTest.java	Wed Jul 05 21:37:42 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
@@ -33,7 +33,7 @@
  * @library ../share
  * @build common.*
  * @build utils.*
- * @run main/othervm -XX:+UsePerfData GcNewTest
+ * @run main/othervm -XX:+UsePerfData -Xmx128M GcNewTest
  */
 
 public class GcNewTest {
--- a/hotspot/test/serviceability/tmtools/jstat/GcTest01.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/test/serviceability/tmtools/jstat/GcTest01.java	Wed Jul 05 21:37:42 2017 +0200
@@ -37,7 +37,7 @@
  * @build common.*
  * @build utils.*
  *
- * @run main/othervm -XX:+UsePerfData GcTest01
+ * @run main/othervm -XX:+UsePerfData -Xmx128M GcTest01
  */
 import utils.*;
 
--- a/hotspot/test/serviceability/tmtools/jstat/GcTest02.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/test/serviceability/tmtools/jstat/GcTest02.java	Wed Jul 05 21:37:42 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
@@ -32,7 +32,7 @@
  * @library ../share
  * @build common.*
  * @build utils.*
- * @run main/othervm -XX:+UsePerfData -Xms128M -XX:MaxMetaspaceSize=128M GcTest02
+ * @run main/othervm -XX:+UsePerfData -Xmx128M -XX:MaxMetaspaceSize=128M GcTest02
  */
 
 public class GcTest02 {
@@ -58,10 +58,4 @@
         // Assert that space has been utilized acordingly
         JstatResults.assertSpaceUtilization(measurement2, targetMemoryUsagePercent);
     }
-
-    private static void assertThat(boolean result, String message) {
-        if (!result) {
-            throw new RuntimeException(message);
-        };
-    }
 }
--- a/hotspot/test/stress/gc/TestGCOld.java	Thu Apr 21 12:57:17 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,417 +0,0 @@
-/*
-* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
-* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-*
-* This code is free software; you can redistribute it and/or modify it
-* under the terms of the GNU General Public License version 2 only, as
-* published by the Free Software Foundation.
-*
-* This code is distributed in the hope that it will be useful, but WITHOUT
-* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-* version 2 for more details (a copy is included in the LICENSE file that
-* accompanied this code).
-*
-* You should have received a copy of the GNU General Public License version
-* 2 along with this work; if not, write to the Free Software Foundation,
-* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-*
-* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-* or visit www.oracle.com if you need additional information or have any
-* questions.
-*/
-
-/*
- * @test TestGCOld
- * @key gc
- * @key stress
- * @requires vm.gc=="null"
- * @summary Stress the GC by trying to make old objects more likely to be garbage than young objects.
- * @run main/othervm -Xmx384M -XX:+UseSerialGC TestGCOld 50 1 20 10 10000
- * @run main/othervm -Xmx384M -XX:+UseParallelGC TestGCOld 50 1 20 10 10000
- * @run main/othervm -Xmx384M -XX:+UseParallelGC -XX:-UseParallelOldGC TestGCOld 50 1 20 10 10000
- * @run main/othervm -Xmx384M -XX:+UseConcMarkSweepGC TestGCOld 50 1 20 10 10000
- * @run main/othervm -Xmx384M -XX:+UseG1GC TestGCOld 50 1 20 10 10000
- */
-
-import java.text.*;
-import java.util.Random;
-
-class TreeNode {
-    public TreeNode left, right;
-    public int val;                // will always be the height of the tree
-}
-
-
-/* Args:
-   live-data-size: in megabytes (approximate, will be rounded down).
-   work: units of mutator non-allocation work per byte allocated,
-     (in unspecified units.  This will affect the promotion rate
-      printed at the end of the run: more mutator work per step implies
-      fewer steps per second implies fewer bytes promoted per second.)
-   short/long ratio: ratio of short-lived bytes allocated to long-lived
-      bytes allocated.
-   pointer mutation rate: number of pointer mutations per step.
-   steps: number of steps to do.
-*/
-
-public class TestGCOld {
-
-  // Command-line parameters.
-
-  private static int size, workUnits, promoteRate, ptrMutRate, steps;
-
-  // Constants.
-
-  private static final int MEG = 1000000;
-  private static final int INSIGNIFICANT = 999; // this many bytes don't matter
-  private static final int BYTES_PER_WORD = 4;
-  private static final int BYTES_PER_NODE = 20; // bytes per TreeNode
-  private static final int WORDS_DEAD = 100;    // size of young garbage object
-
-  private final static int treeHeight = 14;
-  private final static long treeSize = heightToBytes(treeHeight);
-
-  private static final String msg1
-    = "Usage: java TestGCOld <size> <work> <ratio> <mutation> <steps>";
-  private static final String msg2
-    = "  where <size> is the live storage in megabytes";
-  private static final String msg3
-    = "        <work> is the mutator work per step (arbitrary units)";
-  private static final String msg4
-    = "        <ratio> is the ratio of short-lived to long-lived allocation";
-  private static final String msg5
-    = "        <mutation> is the mutations per step";
-  private static final String msg6
-    = "        <steps> is the number of steps";
-
-  // Counters (and global variables that discourage optimization)
-
-  private static long youngBytes = 0;    // total young bytes allocated
-  private static long nodes = 0;         // total tree nodes allocated
-  private static long actuallyMut = 0;   // pointer mutations in old trees
-  private static long mutatorSum = 0;    // checksum to discourage optimization
-  public static int[] aexport;           // exported array to discourage opt
-
-  // Global variables.
-
-  private static TreeNode[] trees;
-  private static int where = 0;               // roving index into trees
-  private static Random rnd = new Random();
-
-  // Returns the height of the given tree.
-
-  private static int height (TreeNode t) {
-    if (t == null) {
-      return 0;
-    }
-    else {
-      return 1 + Math.max (height (t.left), height (t.right));
-    }
-  }
-
-  // Returns the length of the shortest path in the given tree.
-
-  private static int shortestPath (TreeNode t) {
-    if (t == null) {
-      return 0;
-    }
-    else {
-      return 1 + Math.min (shortestPath (t.left), shortestPath (t.right));
-    }
-  }
-
-  // Returns the number of nodes in a balanced tree of the given height.
-
-  private static long heightToNodes (int h) {
-    if (h == 0) {
-      return 0;
-    }
-    else {
-      long n = 1;
-      while (h > 1) {
-        n = n + n;
-        h = h - 1;
-      }
-      return n + n - 1;
-    }
-  }
-
-  // Returns the number of bytes in a balanced tree of the given height.
-
-  private static long heightToBytes (int h) {
-    return BYTES_PER_NODE * heightToNodes (h);
-  }
-
-  // Returns the height of the largest balanced tree
-  // that has no more than the given number of nodes.
-
-  private static int nodesToHeight (long nodes) {
-    int h = 1;
-    long n = 1;
-    while (n + n - 1 <= nodes) {
-      n = n + n;
-      h = h + 1;
-    }
-    return h - 1;
-  }
-
-  // Returns the height of the largest balanced tree
-  // that occupies no more than the given number of bytes.
-
-  private static int bytesToHeight (long bytes) {
-    return nodesToHeight (bytes / BYTES_PER_NODE);
-  }
-
-  // Returns a newly allocated balanced binary tree of height h.
-
-  private static TreeNode makeTree(int h) {
-    if (h == 0) return null;
-    else {
-      TreeNode res = new TreeNode();
-      nodes++;
-      res.left = makeTree(h-1);
-      res.right = makeTree(h-1);
-      res.val = h;
-      return res;
-    }
-  }
-
-  // Allocates approximately size megabytes of trees and stores
-  // them into a global array.
-
-  private static void init() {
-    int ntrees = (int) ((size * MEG) / treeSize);
-    trees = new TreeNode[ntrees];
-
-    System.err.println("Allocating " + ntrees + " trees.");
-    System.err.println("  (" + (ntrees * treeSize) + " bytes)");
-    for (int i = 0; i < ntrees; i++) {
-      trees[i] = makeTree(treeHeight);
-      // doYoungGenAlloc(promoteRate*ntrees*treeSize, WORDS_DEAD);
-    }
-    System.err.println("  (" + nodes + " nodes)");
-
-    /* Allow any in-progress GC to catch up... */
-    // try { Thread.sleep(20000); } catch (InterruptedException x) {}
-  }
-
-  // Confirms that all trees are balanced and have the correct height.
-
-  private static void checkTrees() {
-    int ntrees = trees.length;
-    for (int i = 0; i < ntrees; i++) {
-      TreeNode t = trees[i];
-      int h1 = height(t);
-      int h2 = shortestPath(t);
-      if ((h1 != treeHeight) || (h2 != treeHeight)) {
-        System.err.println("*****BUG: " + h1 + " " + h2);
-      }
-    }
-  }
-
-  // Called only by replaceTree (below) and by itself.
-
-  private static void replaceTreeWork(TreeNode full, TreeNode partial, boolean dir) {
-    boolean canGoLeft = full.left != null && full.left.val > partial.val;
-    boolean canGoRight = full.right != null && full.right.val > partial.val;
-    if (canGoLeft && canGoRight) {
-      if (dir)
-        replaceTreeWork(full.left, partial, !dir);
-      else
-        replaceTreeWork(full.right, partial, !dir);
-    } else if (!canGoLeft && !canGoRight) {
-      if (dir)
-        full.left = partial;
-      else
-        full.right = partial;
-    } else if (!canGoLeft) {
-      full.left = partial;
-    } else {
-      full.right = partial;
-    }
-  }
-
-  // Given a balanced tree full and a smaller balanced tree partial,
-  // replaces an appropriate subtree of full by partial, taking care
-  // to preserve the shape of the full tree.
-
-  private static void replaceTree(TreeNode full, TreeNode partial) {
-    boolean dir = (partial.val % 2) == 0;
-    actuallyMut++;
-    replaceTreeWork(full, partial, dir);
-  }
-
-  // Allocates approximately n bytes of long-lived storage,
-  // replacing oldest existing long-lived storage.
-
-  private static void oldGenAlloc(long n) {
-    int full = (int) (n / treeSize);
-    long partial = n % treeSize;
-    // System.out.println("In oldGenAlloc, doing " + full + " full trees "
-    // + "and one partial tree of size " + partial);
-    for (int i = 0; i < full; i++) {
-      trees[where++] = makeTree(treeHeight);
-      if (where == trees.length) where = 0;
-    }
-    while (partial > INSIGNIFICANT) {
-      int h = bytesToHeight(partial);
-      TreeNode newTree = makeTree(h);
-      replaceTree(trees[where++], newTree);
-      if (where == trees.length) where = 0;
-      partial = partial - heightToBytes(h);
-    }
-  }
-
-  // Interchanges two randomly selected subtrees (of same size and depth).
-
-  private static void oldGenSwapSubtrees() {
-    // Randomly pick:
-    //   * two tree indices
-    //   * A depth
-    //   * A path to that depth.
-    int index1 = rnd.nextInt(trees.length);
-    int index2 = rnd.nextInt(trees.length);
-    int depth = rnd.nextInt(treeHeight);
-    int path = rnd.nextInt();
-    TreeNode tn1 = trees[index1];
-    TreeNode tn2 = trees[index2];
-    for (int i = 0; i < depth; i++) {
-      if ((path & 1) == 0) {
-        tn1 = tn1.left;
-        tn2 = tn2.left;
-      } else {
-        tn1 = tn1.right;
-        tn2 = tn2.right;
-      }
-      path >>= 1;
-    }
-    TreeNode tmp;
-    if ((path & 1) == 0) {
-      tmp = tn1.left;
-      tn1.left = tn2.left;
-      tn2.left = tmp;
-    } else {
-      tmp = tn1.right;
-      tn1.right = tn2.right;
-      tn2.right = tmp;
-    }
-    actuallyMut += 2;
-  }
-
-  // Update "n" old-generation pointers.
-
-  private static void oldGenMut(long n) {
-    for (int i = 0; i < n/2; i++) {
-      oldGenSwapSubtrees();
-    }
-  }
-
-  // Does the amount of mutator work appropriate for n bytes of young-gen
-  // garbage allocation.
-
-  private static void doMutWork(long n) {
-    int sum = 0;
-    long limit = workUnits*n/10;
-    for (long k = 0; k < limit; k++) sum++;
-    // We don't want dead code elimination to eliminate the loop above.
-    mutatorSum = mutatorSum + sum;
-  }
-
-  // Allocate n bytes of young-gen garbage, in units of "nwords"
-  // words.
-
-  private static void doYoungGenAlloc(long n, int nwords) {
-    final int nbytes = nwords*BYTES_PER_WORD;
-    int allocated = 0;
-    while (allocated < n) {
-      aexport = new int[nwords];
-      /* System.err.println("Step"); */
-      allocated += nbytes;
-    }
-    youngBytes = youngBytes + allocated;
-  }
-
-  // Allocate "n" bytes of young-gen data; and do the
-  // corresponding amount of old-gen allocation and pointer
-  // mutation.
-
-  // oldGenAlloc may perform some mutations, so this code
-  // takes those mutations into account.
-
-  private static void doStep(long n) {
-    long mutations = actuallyMut;
-
-    doYoungGenAlloc(n, WORDS_DEAD);
-    doMutWork(n);
-    oldGenAlloc(n / promoteRate);
-    oldGenMut(Math.max(0L, (mutations + ptrMutRate) - actuallyMut));
-  }
-
-  public static void main(String[] args) {
-    if (args.length != 5) {
-      System.err.println(msg1);
-      System.err.println(msg2);
-      System.err.println(msg3);
-      System.err.println(msg4);
-      System.err.println(msg5);
-      System.err.println(msg6);
-      return;
-    }
-
-    size = Integer.parseInt(args[0]);
-    workUnits = Integer.parseInt(args[1]);
-    promoteRate = Integer.parseInt(args[2]);
-    ptrMutRate = Integer.parseInt(args[3]);
-    steps = Integer.parseInt(args[4]);
-
-    System.out.println(size + " megabytes of live storage");
-    System.out.println(workUnits + " work units per step");
-    System.out.println("promotion ratio is 1:" + promoteRate);
-    System.out.println("pointer mutation rate is " + ptrMutRate);
-    System.out.println(steps + " steps");
-
-    init();
-//  checkTrees();
-    youngBytes = 0;
-    nodes = 0;
-
-    System.err.println("Initialization complete...");
-
-    long start = System.currentTimeMillis();
-
-    for (int step = 0; step < steps; step++) {
-      doStep(MEG);
-    }
-
-    long end = System.currentTimeMillis();
-    float secs = ((float)(end-start))/1000.0F;
-
-//  checkTrees();
-
-    NumberFormat nf = NumberFormat.getInstance();
-    nf.setMaximumFractionDigits(1);
-    System.out.println("\nTook " + nf.format(secs) + " sec in steady state.");
-    nf.setMaximumFractionDigits(2);
-    System.out.println("Allocated " + steps + " Mb of young gen garbage"
-                       + " (= " + nf.format(((float)steps)/secs) +
-                       " Mb/sec)");
-    System.out.println("    (actually allocated " +
-                       nf.format(((float) youngBytes)/MEG) + " megabytes)");
-    float promoted = ((float)steps) / (float)promoteRate;
-    System.out.println("Promoted " + promoted +
-                       " Mb (= " + nf.format(promoted/secs) + " Mb/sec)");
-    System.out.println("    (actually promoted " +
-                       nf.format(((float) (nodes * BYTES_PER_NODE))/MEG) +
-                       " megabytes)");
-    if (ptrMutRate != 0) {
-      System.out.println("Mutated " + actuallyMut +
-                         " pointers (= " +
-                         nf.format(actuallyMut/secs) + " ptrs/sec)");
-
-    }
-    // This output serves mainly to discourage optimization.
-    System.out.println("Checksum = " + (mutatorSum + aexport.length));
-
-  }
-}
--- a/hotspot/test/stress/gc/TestMultiThreadStressRSet.java	Thu Apr 21 12:57:17 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,305 +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.
- */
-
-import java.io.PrintStream;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-import sun.hotspot.WhiteBox;
-
-/*
- * @test TestMultiThreadStressRSet.java
- * @key stress
- * @requires vm.gc=="G1" | vm.gc=="null"
- * @requires os.maxMemory > 2G
- *
- * @summary Stress G1 Remembered Set using multiple threads
- * @library /test/lib /testlibrary
- * @build sun.hotspot.WhiteBox
- * @run main ClassFileInstaller sun.hotspot.WhiteBox
- *                              sun.hotspot.WhiteBox$WhiteBoxPermission
- * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
- *   -XX:+UseG1GC -XX:G1SummarizeRSetStatsPeriod=1 -Xlog:gc
- *   -Xmx500m -XX:G1HeapRegionSize=1m -XX:MaxGCPauseMillis=1000 TestMultiThreadStressRSet 10 4
- *
- * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
- *   -XX:+UseG1GC -XX:G1SummarizeRSetStatsPeriod=100 -Xlog:gc
- *   -Xmx1G -XX:G1HeapRegionSize=8m -XX:MaxGCPauseMillis=1000 TestMultiThreadStressRSet 60 16
- *
- * @run main/othervm/timeout=700 -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
- *   -XX:+UseG1GC -XX:G1SummarizeRSetStatsPeriod=100 -Xlog:gc
- *   -Xmx500m -XX:G1HeapRegionSize=1m -XX:MaxGCPauseMillis=1000 TestMultiThreadStressRSet 600 32
- */
-public class TestMultiThreadStressRSet {
-
-    private static final Random RND = new Random(2015 * 2016);
-    private static final WhiteBox WB = WhiteBox.getWhiteBox();
-    private static final int REF_SIZE = WB.getHeapOopSize();
-    private static final int REGION_SIZE = WB.g1RegionSize();
-
-    // How many regions to use for the storage
-    private static final int STORAGE_REGIONS = 20;
-
-    // Size a single obj in the storage
-    private static final int OBJ_SIZE = 1024;
-
-    // How many regions of young/old gen to use in the BUFFER
-    private static final int BUFFER_YOUNG_REGIONS = 60;
-    private static final int BUFFER_OLD_REGIONS = 40;
-
-    // Total number of objects in the storage.
-    private final int N;
-
-    // The storage of byte[]
-    private final List<Object> STORAGE;
-
-    // Where references to the Storage will be stored
-    private final List<Object[]> BUFFER;
-
-    // The length of a buffer element.
-    // RSet deals with "cards" (areas of 512 bytes), not with single refs
-    // So, to affect the RSet the BUFFER refs should be allocated in different
-    // memory cards.
-    private final int BUF_ARR_LEN = 100 * (512 / REF_SIZE);
-
-    // Total number of objects in the young/old buffers
-    private final int YOUNG;
-    private final int OLD;
-
-    // To cause Remembered Sets change their coarse level the test uses a window
-    // within STORAGE. All the BUFFER elements refer to only STORAGE objects
-    // from the current window. The window is defined by a range.
-    // The first element has got the index: 'windowStart',
-    // the last one: 'windowStart + windowSize - 1'
-    // The window is shifting periodically.
-    private int windowStart;
-    private final int windowSize;
-
-    // Counter of created worker threads
-    private int counter = 0;
-
-    private volatile String errorMessage = null;
-    private volatile boolean isEnough = false;
-
-    public static void main(String args[]) {
-        if (args.length != 2) {
-            throw new IllegalArgumentException("TEST BUG: wrong arg count " + args.length);
-        }
-        long time = Long.parseLong(args[0]);
-        int threads = Integer.parseInt(args[1]);
-        new TestMultiThreadStressRSet().test(time * 1000, threads);
-    }
-
-    /**
-     * Initiates test parameters, fills out the STORAGE and BUFFER.
-     */
-    public TestMultiThreadStressRSet() {
-
-        N = (REGION_SIZE - 1) * STORAGE_REGIONS / OBJ_SIZE + 1;
-        STORAGE = new ArrayList<>(N);
-        int bytes = OBJ_SIZE - 20;
-        for (int i = 0; i < N - 1; i++) {
-            STORAGE.add(new byte[bytes]);
-        }
-        STORAGE.add(new byte[REGION_SIZE / 2 + 100]); // humongous
-        windowStart = 0;
-        windowSize = REGION_SIZE / OBJ_SIZE;
-
-        BUFFER = new ArrayList<>();
-        int sizeOfBufferObject = 20 + REF_SIZE * BUF_ARR_LEN;
-        OLD = REGION_SIZE * BUFFER_OLD_REGIONS / sizeOfBufferObject;
-        YOUNG = REGION_SIZE * BUFFER_YOUNG_REGIONS / sizeOfBufferObject;
-        for (int i = 0; i < OLD + YOUNG; i++) {
-            BUFFER.add(new Object[BUF_ARR_LEN]);
-        }
-    }
-
-    /**
-     * Does the testing. Steps:
-     * <ul>
-     * <li> starts the Shifter thread
-     * <li> during the given time starts new Worker threads, keeping the number
-     * of live thread under limit.
-     * <li> stops the Shifter thread
-     * </ul>
-     *
-     * @param timeInMillis how long to stress
-     * @param maxThreads the maximum number of Worker thread working together.
-     */
-    public void test(long timeInMillis, int maxThreads) {
-        if (timeInMillis <= 0 || maxThreads <= 0) {
-            throw new IllegalArgumentException("TEST BUG: be positive!");
-        }
-        System.out.println("%% Time to work: " + timeInMillis / 1000 + "s");
-        System.out.println("%% Number of threads: " + maxThreads);
-        long finish = System.currentTimeMillis() + timeInMillis;
-        Shifter shift = new Shifter(this, 1000, (int) (windowSize * 0.9));
-        shift.start();
-        for (int i = 0; i < maxThreads; i++) {
-            new Worker(this, 100).start();
-        }
-        try {
-            while (System.currentTimeMillis() < finish && errorMessage == null) {
-                Thread.sleep(100);
-            }
-        } catch (Throwable t) {
-            printAllStackTraces(System.err);
-            t.printStackTrace(System.err);
-            this.errorMessage = t.getMessage();
-        } finally {
-            isEnough = true;
-        }
-        System.out.println("%% Total work cycles: " + counter);
-        if (errorMessage != null) {
-            throw new RuntimeException(errorMessage);
-        }
-    }
-
-    /**
-     * Returns an element from from the BUFFER (an object array) to keep
-     * references to the storage.
-     *
-     * @return an Object[] from buffer.
-     */
-    private Object[] getFromBuffer() {
-        int index = counter % (OLD + YOUNG);
-        synchronized (BUFFER) {
-            if (index < OLD) {
-                if (counter % 100 == (counter / 100) % 100) {
-                    // need to generate garbage in the old gen to provoke mixed GC
-                    return replaceInBuffer(index);
-                } else {
-                    return BUFFER.get(index);
-                }
-            } else {
-                return replaceInBuffer(index);
-            }
-        }
-    }
-
-    private Object[] replaceInBuffer(int index) {
-        Object[] objs = new Object[BUF_ARR_LEN];
-        BUFFER.set(index, objs);
-        return objs;
-    }
-
-    /**
-     * Returns a random object from the current window within the storage.
-     * A storage element with index from windowStart to windowStart+windowSize.
-     *
-     * @return a random element from the current window within the storage.
-     */
-    private Object getRandomObject() {
-        int index = (windowStart + RND.nextInt(windowSize)) % N;
-        return STORAGE.get(index);
-    }
-
-    private static void printAllStackTraces(PrintStream ps) {
-        Map<Thread, StackTraceElement[]> traces = Thread.getAllStackTraces();
-        for (Thread t : traces.keySet()) {
-            ps.println(t.toString() + " " + t.getState());
-            for (StackTraceElement traceElement : traces.get(t)) {
-                ps.println("\tat " + traceElement);
-            }
-        }
-    }
-
-    /**
-     * Thread to create a number of references from BUFFER to STORAGE.
-     */
-    private static class Worker extends Thread {
-
-        final TestMultiThreadStressRSet boss;
-        final int refs; // number of refs to OldGen
-
-        /**
-         * @param boss the tests
-         * @param refsToOldGen how many references to the OldGen to create
-         */
-        Worker(TestMultiThreadStressRSet boss, int refsToOldGen) {
-            this.boss = boss;
-            this.refs = refsToOldGen;
-        }
-
-        @Override
-        public void run() {
-            try {
-                while (!boss.isEnough) {
-                    Object[] objs = boss.getFromBuffer();
-                    int step = objs.length / refs;
-                    for (int i = 0; i < refs; i += step) {
-                        objs[i] = boss.getRandomObject();
-                    }
-                    boss.counter++;
-                }
-            } catch (Throwable t) {
-                t.printStackTrace(System.out);
-                boss.errorMessage = t.getMessage();
-            }
-        }
-    }
-
-    /**
-     * Periodically shifts the current STORAGE window, removing references
-     * in BUFFER that refer to objects outside the window.
-     */
-    private static class Shifter extends Thread {
-
-        final TestMultiThreadStressRSet boss;
-        final int sleepTime;
-        final int shift;
-
-        Shifter(TestMultiThreadStressRSet boss, int sleepTime, int shift) {
-            this.boss = boss;
-            this.sleepTime = sleepTime;
-            this.shift = shift;
-        }
-
-        @Override
-        public void run() {
-            try {
-                while (!boss.isEnough) {
-                    Thread.sleep(sleepTime);
-                    boss.windowStart += shift;
-                    for (int i = 0; i < boss.OLD; i++) {
-                        Object[] objs = boss.BUFFER.get(i);
-                        for (int j = 0; j < objs.length; j++) {
-                            objs[j] = null;
-                        }
-                    }
-                    if (!WB.g1InConcurrentMark()) {
-                        System.out.println("%% start CMC");
-                        WB.g1StartConcMarkCycle();
-                    } else {
-                        System.out.println("%% CMC is already in progress");
-                    }
-                }
-            } catch (Throwable t) {
-                t.printStackTrace(System.out);
-                boss.errorMessage = t.getMessage();
-            }
-        }
-    }
-}
-
--- a/hotspot/test/stress/gc/TestStressIHOPMultiThread.java	Thu Apr 21 12:57:17 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,216 +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.
- */
-
- /*
- * @test TestStressIHOPMultiThread
- * @bug 8148397
- * @key stress
- * @summary Stress test for IHOP
- * @requires vm.gc=="G1" | vm.gc=="null"
- * @run main/othervm/timeout=200 -Xmx128m -XX:G1HeapWastePercent=0 -XX:G1MixedGCCountTarget=1
- *              -XX:+UseG1GC -XX:G1HeapRegionSize=1m -XX:+G1UseAdaptiveIHOP
- *              -Xlog:gc+ihop=debug,gc+ihop+ergo=debug,gc+ergo=debug:TestStressIHOPMultiThread1.log
- *              -Dtimeout=2 -DheapUsageMinBound=30 -DheapUsageMaxBound=80
- *              -Dthreads=2 TestStressIHOPMultiThread
- * @run main/othervm/timeout=200 -Xmx256m -XX:G1HeapWastePercent=0 -XX:G1MixedGCCountTarget=1
- *              -XX:+UseG1GC -XX:G1HeapRegionSize=2m -XX:+G1UseAdaptiveIHOP
- *              -Xlog:gc+ihop=debug,gc+ihop+ergo=debug,gc+ergo=debug:TestStressIHOPMultiThread2.log
- *              -Dtimeout=2 -DheapUsageMinBound=60 -DheapUsageMaxBound=90
- *              -Dthreads=3 TestStressIHOPMultiThread
- * @run main/othervm/timeout=200 -Xmx256m -XX:G1HeapWastePercent=0 -XX:G1MixedGCCountTarget=1
- *              -XX:+UseG1GC -XX:G1HeapRegionSize=4m -XX:-G1UseAdaptiveIHOP
- *              -Xlog:gc+ihop=debug,gc+ihop+ergo=debug,gc+ergo=debug:TestStressIHOPMultiThread3.log
- *              -Dtimeout=2 -DheapUsageMinBound=40 -DheapUsageMaxBound=90
- *              -Dthreads=5 TestStressIHOPMultiThread
- * @run main/othervm/timeout=200 -Xmx128m -XX:G1HeapWastePercent=0 -XX:G1MixedGCCountTarget=1
- *              -XX:+UseG1GC -XX:G1HeapRegionSize=8m -XX:+G1UseAdaptiveIHOP
- *              -Xlog:gc+ihop=debug,gc+ihop+ergo=debug,gc+ergo=debug:TestStressIHOPMultiThread4.log
- *              -Dtimeout=2 -DheapUsageMinBound=20 -DheapUsageMaxBound=90
- *              -Dthreads=10 TestStressIHOPMultiThread
- * @run main/othervm/timeout=200 -Xmx512m -XX:G1HeapWastePercent=0 -XX:G1MixedGCCountTarget=1
- *              -XX:+UseG1GC -XX:G1HeapRegionSize=16m -XX:+G1UseAdaptiveIHOP
- *              -Xlog:gc+ihop=debug,gc+ihop+ergo=debug,gc+ergo=debug:TestStressIHOPMultiThread5.log
- *              -Dtimeout=2 -DheapUsageMinBound=20 -DheapUsageMaxBound=90
- *              -Dthreads=17 TestStressIHOPMultiThread
- */
-
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-
-/**
- * Stress test for Adaptive IHOP. Starts a number of threads that fill and free
- * specified amount of memory. Tests work with enabled IHOP logging.
- *
- */
-public class TestStressIHOPMultiThread {
-
-    public final static List<Object> GARBAGE = new LinkedList<>();
-
-    private final long HEAP_SIZE;
-    // Amount of memory to be allocated before iterations start
-    private final long HEAP_PREALLOC_SIZE;
-    // Amount of memory to be allocated and freed during iterations
-    private final long HEAP_ALLOC_SIZE;
-    private final int CHUNK_SIZE = 100000;
-
-    private final int TIMEOUT;
-    private final int THREADS;
-    private final int HEAP_LOW_BOUND;
-    private final int HEAP_HIGH_BOUND;
-
-    private volatile boolean running = true;
-    private final List<AllocationThread> threads;
-
-    public static void main(String[] args) throws InterruptedException {
-        new TestStressIHOPMultiThread().start();
-
-    }
-
-    TestStressIHOPMultiThread() {
-
-        TIMEOUT = Integer.getInteger("timeout") * 60;
-        THREADS = Integer.getInteger("threads");
-        HEAP_LOW_BOUND = Integer.getInteger("heapUsageMinBound");
-        HEAP_HIGH_BOUND = Integer.getInteger("heapUsageMaxBound");
-        HEAP_SIZE = Runtime.getRuntime().maxMemory();
-
-        HEAP_PREALLOC_SIZE = HEAP_SIZE * HEAP_LOW_BOUND / 100;
-        HEAP_ALLOC_SIZE = HEAP_SIZE * (HEAP_HIGH_BOUND - HEAP_LOW_BOUND) / 100;
-
-        threads = new ArrayList<>(THREADS);
-    }
-
-    public void start() throws InterruptedException {
-        fill();
-        createThreads();
-        waitForStress();
-        stressDone();
-        waitForFinish();
-    }
-
-    /**
-     * Fills HEAP_PREALLOC_SIZE bytes of garbage.
-     */
-    private void fill() {
-        long allocated = 0;
-        while (allocated < HEAP_PREALLOC_SIZE) {
-            GARBAGE.add(new byte[CHUNK_SIZE]);
-            allocated += CHUNK_SIZE;
-        }
-    }
-
-    /**
-     * Creates a number of threads which will fill and free amount of memory.
-     */
-    private void createThreads() {
-        for (int i = 0; i < THREADS; ++i) {
-            System.out.println("Create thread " + i);
-            AllocationThread thread =new TestStressIHOPMultiThread.AllocationThread(i, HEAP_ALLOC_SIZE / THREADS);
-            // Put reference to thread garbage into common garbage for avoiding possible optimization.
-            GARBAGE.add(thread.getList());
-            threads.add(thread);
-        }
-        threads.forEach(t -> t.start());
-    }
-
-    /**
-     * Wait each thread for finishing
-     */
-    private void waitForFinish() {
-        threads.forEach(thread -> {
-            thread.silentJoin();
-        });
-    }
-
-    private boolean isRunning() {
-        return running;
-    }
-
-    private void stressDone() {
-        running = false;
-    }
-
-    private void waitForStress() throws InterruptedException {
-        Thread.sleep(TIMEOUT * 1000);
-    }
-
-    private class AllocationThread extends Thread {
-
-        private final List<Object> garbage;
-
-        private final long amountOfGarbage;
-        private final int threadId;
-
-        public AllocationThread(int id, long amount) {
-            super("Thread " + id);
-            threadId = id;
-            amountOfGarbage = amount;
-            garbage = new LinkedList<>();
-        }
-
-        /**
-         * Returns list of garbage.
-         * @return List with thread garbage.
-         */
-        public List<Object> getList(){
-            return garbage;
-        }
-
-        @Override
-        public void run() {
-            System.out.println("Start the thread " + threadId);
-            while (TestStressIHOPMultiThread.this.isRunning()) {
-                allocate(amountOfGarbage);
-                free();
-            }
-        }
-
-        private void silentJoin() {
-            System.out.println("Join the thread " + threadId);
-            try {
-                join();
-            } catch (InterruptedException ie) {
-                throw new RuntimeException(ie);
-            }
-        }
-
-        /**
-         * Allocates thread local garbage
-         */
-        private void allocate(long amount) {
-            long allocated = 0;
-            while (allocated < amount && TestStressIHOPMultiThread.this.isRunning()) {
-                garbage.add(new byte[CHUNK_SIZE]);
-                allocated += CHUNK_SIZE;
-            }
-        }
-
-        /**
-         * Frees thread local garbage
-         */
-        private void free() {
-            garbage.clear();
-        }
-    }
-}
--- a/hotspot/test/stress/gc/TestStressRSetCoarsening.java	Thu Apr 21 12:57:17 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,335 +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.
- */
-
-import java.util.concurrent.TimeoutException;
-import sun.hotspot.WhiteBox;
-
-/*
- * @test TestStressRSetCoarsening.java
- * @key stress
- * @bug 8146984 8147087
- * @requires vm.gc=="G1" | vm.gc=="null"
- * @requires os.maxMemory > 3G
- *
- * @summary Stress G1 Remembered Set by creating a lot of cross region links
- * @modules java.base/jdk.internal.misc
- * @library /testlibrary /test/lib
- * @build sun.hotspot.WhiteBox
- * @run main ClassFileInstaller sun.hotspot.WhiteBox
- *                              sun.hotspot.WhiteBox$WhiteBoxPermission
- * @run main/othervm/timeout=300
- *     -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+UseG1GC
- *     -XX:+IgnoreUnrecognizedVMOptions -XX:+PrintGC -XX:+PrintGCTimeStamps -Xlog:gc
- *     -Xmx500m -XX:G1HeapRegionSize=1m -XX:MaxGCPauseMillis=1000 TestStressRSetCoarsening  1  0 300
- * @run main/othervm/timeout=300
- *     -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+UseG1GC
- *     -XX:+IgnoreUnrecognizedVMOptions -XX:+PrintGC -XX:+PrintGCTimeStamps -Xlog:gc
- *     -Xmx500m -XX:G1HeapRegionSize=8m -XX:MaxGCPauseMillis=1000 TestStressRSetCoarsening  1 10 300
- * @run main/othervm/timeout=300
- *     -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+UseG1GC
- *     -XX:+IgnoreUnrecognizedVMOptions -XX:+PrintGC -XX:+PrintGCTimeStamps -Xlog:gc
- *     -Xmx500m -XX:G1HeapRegionSize=32m -XX:MaxGCPauseMillis=1000 TestStressRSetCoarsening 42 10 300
- * @run main/othervm/timeout=300
- *     -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+UseG1GC
- *     -XX:+IgnoreUnrecognizedVMOptions -XX:+PrintGC -XX:+PrintGCTimeStamps -Xlog:gc
- *     -Xmx500m -XX:G1HeapRegionSize=1m -XX:MaxGCPauseMillis=1000 TestStressRSetCoarsening  2 0 300
- * @run main/othervm/timeout=1800
- *     -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+UseG1GC
- *     -XX:+IgnoreUnrecognizedVMOptions -XX:+PrintGC -XX:+PrintGCTimeStamps -Xlog:gc
- *     -Xmx1G -XX:G1HeapRegionSize=1m -XX:MaxGCPauseMillis=1000 TestStressRSetCoarsening 500 0  1800
- * @run main/othervm/timeout=1800
- *     -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+UseG1GC
- *     -XX:+IgnoreUnrecognizedVMOptions -XX:+PrintGC -XX:+PrintGCTimeStamps -Xlog:gc
- *     -Xmx1G -XX:G1HeapRegionSize=1m -XX:MaxGCPauseMillis=1000 TestStressRSetCoarsening 10  10 1800
- */
-
-/**
- * What the test does.
- * Preparation stage:
- *   Fill out ~90% of the heap with objects, each object is an object array.
- *   If we want to allocate K objects per region, we calculate N to meet:
- *      sizeOf(Object[N]) ~= regionSize / K
- * Stress stage:
- *   No more allocation, so no more GC.
- *   We will perform a number of  iterations. On each iteration i,
- *   for each pair of regions Rx and Ry we will set c[i] references
- *   from Rx to Ry. If c[i] less than c[i-1] at the end of iteration
- *   concurrent mark cycle will be initiated (to recalculate remembered sets).
- *   As the result RSet will be growing up and down, up and down many times.
- *
- * The test expects: no crash and no timeouts.
- *
- * Test Parameters:
- *   args[0] - number of objects per Heap Region (1 - means humongous)
- *   args[1] - number of regions to refresh to provoke GC at the end of cycle.
- *             (0 - means no GC, i.e. no reading from RSet)
- *   args[2] - timeout in seconds (to stop execution to avoid jtreg timeout)
- */
-public class TestStressRSetCoarsening {
-
-    public static void main(String... args) throws InterruptedException {
-        if (args.length != 3) {
-            throw new IllegalArgumentException("Wrong number of arguments " + args.length);
-        }
-        int objectsPerRegion = Integer.parseInt(args[0]); // 1 means humongous
-        int regsToRefresh = Integer.parseInt(args[1]);  // 0 means no regions to refresh at the end of cycle
-        int timeout = Integer.parseInt(args[2]); // in seconds, test should stop working eariler
-        new TestStressRSetCoarsening(objectsPerRegion, regsToRefresh, timeout).go();
-    }
-
-    private static final long KB = 1024;
-    private static final long MB = 1024 * KB;
-
-    private static final WhiteBox WB = WhiteBox.getWhiteBox();
-
-    public final Object[][] storage;
-
-    /**
-     * Number of objects per region. This is a test parameter.
-     */
-    public final int K;
-
-    /**
-     * Length of object array: sizeOf(Object[N]) ~= regionSize / K
-     * N will be calculated as function of K.
-     */
-    public final int N;
-
-    /**
-     * How many regions involved into testing.
-     * Will be calculated as heapFractionToAllocate * freeRegionCount.
-     */
-    public final int regionCount;
-
-    /**
-     * How much heap to use.
-     */
-    public final float heapFractionToAllocate = 0.9f;
-
-    /**
-     * How many regions to be refreshed at the end of cycle.
-     * This is a test parameter.
-     */
-    public final int regsToRefresh;
-
-    /**
-     * Initial time.
-     */
-    public final long start;
-
-    /**
-     * Time when the test should stop working.
-     */
-    public final long finishAt;
-
-    /**
-     * Does pre-calculation and allocate necessary objects.
-     *
-     * @param objPerRegions how many objects per G1 heap region
-     */
-    TestStressRSetCoarsening(int objPerRegions, int regsToRefresh, int timeout) {
-        this.K = objPerRegions;
-        this.regsToRefresh = regsToRefresh;
-        this.start = System.currentTimeMillis();
-        this.finishAt = start + timeout * 900; // 10% ahead of jtreg timeout
-
-        long regionSize = WB.g1RegionSize();
-
-        // How many free regions
-        Runtime rt = Runtime.getRuntime();
-        long used = rt.totalMemory() - rt.freeMemory();
-        long totalFree = rt.maxMemory() - used;
-        regionCount = (int) ((totalFree / regionSize) * heapFractionToAllocate);
-        long toAllocate = regionCount * regionSize;
-        System.out.println("%% Test parameters");
-        System.out.println("%%   Objects per region              : " + K);
-        System.out.println("%%   Heap fraction to allocate       : " + (int) (heapFractionToAllocate * 100) + "%");
-        System.out.println("%%   Regions to refresh to provoke GC: " + regsToRefresh);
-
-        System.out.println("%% Memory");
-        System.out.println("%%   used          :        " + used / MB + "M");
-        System.out.println("%%   available     :        " + totalFree / MB + "M");
-        System.out.println("%%   to allocate   :        " + toAllocate / MB + "M");
-        System.out.println("%%     (in regs)   :        " + regionCount);
-        System.out.println("%%   G1 Region Size:        " + regionSize / MB + "M");
-
-        int refSize = WB.getHeapOopSize();
-
-        // Calculate N:    K*sizeOf(Object[N]) ~= regionSize
-        //                 sizeOf(Object[N]) ~=  (N+4)*refSize
-        // ==>
-        //                 N = regionSize / K / refSize - 4;
-        N = (int) ((regionSize / K) / refSize) - 5;
-
-        /*
-         *   --------------
-         *   region0   storage[0]        = new Object[N]
-         *             ...
-         *             storage[K-1]      = new Object[N]
-         *   ---------------
-         *   region1   storage[K]        = new Object[N]
-         *             ...
-         *             storage[2*K - 1]  = new Object[N]
-         *   --------------
-         *   ...
-         *   --------------
-         *   regionX   storage[X*K]         = new Object[N]
-         *             ...
-         *             storage[(X+1)*K -1]  = new Object[N]
-         *    where X = HeapFraction * TotalRegions
-         *   -------------
-         */
-        System.out.println("%% Objects");
-        System.out.println("%%   N (array length)      : " + N);
-        System.out.println("%%   K (objects in regions): " + K);
-        System.out.println("%%   Reference size        : " + refSize);
-        System.out.println("%%   Approximate obj size  : " + (N + 2) * refSize / KB + "K)");
-
-        storage = new Object[regionCount * K][];
-        for (int i = 0; i < storage.length; i++) {
-            storage[i] = new Object[N];
-        }
-    }
-
-    public void go() throws InterruptedException {
-        // threshold for sparce -> fine
-        final int FINE = WB.getIntxVMFlag("G1RSetSparseRegionEntries").intValue();
-
-        // threshold for fine -> coarse
-        final int COARSE = WB.getIntxVMFlag("G1RSetRegionEntries").intValue();
-
-        // regToRegRefCounts - array of reference counts from region to region
-        // at the the end of iteration.
-        // The number of test iterations is array length - 1.
-        // If c[i] > c[i-1] then during the iteration i more references will
-        // be created.
-        // If c[i] < c[i-1] then some referenes will be cleaned.
-        int[] regToRegRefCounts = {0, FINE / 2, 0, FINE, (FINE + COARSE) / 2, 0,
-            COARSE, COARSE + 10, FINE + 1, FINE / 2, 0};
-
-        // For progress tracking
-        int[] progress = new int[regToRegRefCounts.length];
-        progress[0] = 0;
-        for (int i = 1; i < regToRegRefCounts.length; i++) {
-            progress[i] = progress[i - 1] + Math.abs(regToRegRefCounts[i] - regToRegRefCounts[i - 1]);
-        }
-        try {
-            for (int i = 1; i < regToRegRefCounts.length; i++) {
-                int pre = regToRegRefCounts[i - 1];
-                int cur = regToRegRefCounts[i];
-                float prog = ((float) progress[i - 1] / progress[progress.length - 1]);
-
-                System.out.println("%% step " + i
-                        + " out of " + (regToRegRefCounts.length - 1)
-                        + " (~" + (int) (100 * prog) + "% done)");
-                System.out.println("%%      " + pre + "  --> " + cur);
-                for (int to = 0; to < regionCount; to++) {
-                    // Select a celebrity object that we will install references to.
-                    // The celebrity will be referred from all other regions.
-                    // If the number of references after should be less than they
-                    // were before, select NULL.
-                    Object celebrity = cur > pre ? storage[to * K] : null;
-                    for (int from = 0; from < regionCount; from++) {
-                        if (to == from) {
-                            continue; // no need to refer to itself
-                        }
-
-                        int step = cur > pre ? +1 : -1;
-                        for (int rn = pre; rn != cur; rn += step) {
-                            storage[getY(to, from, rn)][getX(to, from, rn)] = celebrity;
-                            if (System.currentTimeMillis() > finishAt) {
-                                throw new TimeoutException();
-                            }
-                        }
-                    }
-                }
-                if (pre > cur) {
-                    // Number of references went down.
-                    // Need to provoke recalculation of RSet.
-                    WB.g1StartConcMarkCycle();
-                    while (WB.g1InConcurrentMark()) {
-                        Thread.sleep(1);
-                    }
-                }
-
-                // To force the use of rememebered set entries we need to provoke a GC.
-                // To induce some fragmentation, and some mixed GCs, we need
-                // to make a few objects unreachable.
-                for (int toClean = i * regsToRefresh; toClean < (i + 1) * regsToRefresh; toClean++) {
-                    int to = toClean % regionCount;
-                    // Need to remove all references from all regions to the region 'to'
-                    for (int from = 0; from < regionCount; from++) {
-                        if (to == from) {
-                            continue; // no need to refer to itself
-                        }
-                        for (int rn = 0; rn <= cur; rn++) {
-                            storage[getY(to, from, rn)][getX(to, from, rn)] = null;
-                        }
-                    }
-                    // 'Refresh' storage elements for the region 'to'
-                    // After that loop all 'old' objects in the region 'to'
-                    // should become unreachable.
-                    for (int k = 0; k < K; k++) {
-                        storage[(to * K + k) % storage.length] = new Object[N];
-                    }
-                }
-            }
-        } catch (TimeoutException e) {
-            System.out.println("%% TIMEOUT!!!");
-        }
-        long now = System.currentTimeMillis();
-        System.out.println("%% Summary");
-        System.out.println("%%   Time spent          : " + ((now - start) / 1000) + " seconds");
-        System.out.println("%%   Free memory left    : " + Runtime.getRuntime().freeMemory() / KB + "K");
-        System.out.println("%% Test passed");
-    }
-
-    /**
-     * Returns X index in the Storage of the reference #rn from the region
-     * 'from' to the region 'to'.
-     *
-     * @param to region # to refer to
-     * @param from region # to refer from
-     * @param rn number of reference
-     *
-     * @return X index in the range: [0 ... N-1]
-     */
-    private int getX(int to, int from, int rn) {
-        return (rn * regionCount + to) % N;
-    }
-
-    /**
-     * Returns Y index in the Storage of the reference #rn from the region
-     * 'from' to the region 'to'.
-     *
-     * @param to region # to refer to
-     * @param from region # to refer from
-     * @param rn number of reference
-     *
-     * @return Y index in the range: [0 ... K*regionCount -1]
-     */
-    private int getY(int to, int from, int rn) {
-        return ((rn * regionCount + to) / N + from * K) % (regionCount * K);
-    }
-}
-
--- a/hotspot/test/testlibrary/jdk/test/lib/OutputAnalyzer.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/hotspot/test/testlibrary/jdk/test/lib/OutputAnalyzer.java	Wed Jul 05 21:37:42 2017 +0200
@@ -378,14 +378,14 @@
    *  - exit code
    *  Note: the command line is printed by the ProcessTools
    */
-    private void reportDiagnosticSummary() {
-        String msg =
-            " stdout: [" + stdout + "];\n" +
-            " stderr: [" + stderr + "]\n" +
-            " exitValue = " + getExitValue() + "\n";
+  public void reportDiagnosticSummary() {
+      String msg =
+          " stdout: [" + stdout + "];\n" +
+          " stderr: [" + stderr + "]\n" +
+          " exitValue = " + getExitValue() + "\n";
 
-        System.err.println(msg);
-    }
+      System.err.println(msg);
+  }
 
 
   /**
--- a/jdk/.hgtags	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/.hgtags	Wed Jul 05 21:37:42 2017 +0200
@@ -357,3 +357,4 @@
 1565a0efe6f0ca411a6df277df1e069431c60988 jdk-9+112
 68f8be44b6a6b33dfa841ec671c0ba6e4056b372 jdk-9+113
 bb8379287f3736f38c52b2d1418784e2592461d1 jdk-9+114
+35225b837d66582037eeadeb471c13235dfd793d jdk-9+115
--- a/jdk/make/Import.gmk	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/make/Import.gmk	Wed Jul 05 21:37:42 2017 +0200
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2012, 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
@@ -83,20 +83,20 @@
   endif
 
   ifneq ($(OPENJDK_TARGET_OS), windows)
-    ifeq ($(JVM_VARIANT_SERVER), true)
+    ifeq ($(call check-jvm-variant, server), true)
       BASE_TARGETS += $(BASE_INSTALL_LIBRARIES_HERE)/server/$(LIBRARY_PREFIX)jsig$(SHARED_LIBRARY_SUFFIX)
       ifneq (, $(JSIG_DEBUGINFO))
         BASE_TARGETS += $(BASE_INSTALL_LIBRARIES_HERE)/server/$(foreach I,$(JSIG_DEBUGINFO),$(notdir $I))
       endif
     endif
-    ifeq ($(JVM_VARIANT_CLIENT), true)
+    ifeq ($(call check-jvm-variant, client), true)
       BASE_TARGETS += $(BASE_INSTALL_LIBRARIES_HERE)/client/$(LIBRARY_PREFIX)jsig$(SHARED_LIBRARY_SUFFIX)
       ifneq (, $(JSIG_DEBUGINFO))
         BASE_TARGETS += $(BASE_INSTALL_LIBRARIES_HERE)/client/$(foreach I,$(JSIG_DEBUGINFO),$(notdir $I))
       endif
     endif
     ifneq ($(OPENJDK_TARGET_OS), macosx)
-      ifeq ($(JVM_VARIANT_MINIMAL1), true)
+      ifeq ($(call check-jvm-variant, minimal), true)
         BASE_TARGETS += $(BASE_INSTALL_LIBRARIES_HERE)/minimal/$(LIBRARY_PREFIX)jsig$(SHARED_LIBRARY_SUFFIX)
         ifneq (,$(JSIG_DEBUGINFO))
           BASE_TARGETS += $(BASE_INSTALL_LIBRARIES_HERE)/minimal/$(foreach I,$(JSIG_DEBUGINFO),$(notdir $I))
--- a/jdk/make/copy/Copy-java.base.gmk	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/make/copy/Copy-java.base.gmk	Wed Jul 05 21:37:42 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
@@ -88,7 +88,7 @@
 #
 # How to install jvm.cfg.
 #
-ifeq ($(JVM_VARIANT_ZERO), true)
+ifeq ($(call check-jvm-variant, zero zeroshark), true)
   JVMCFG_ARCH := zero
 else
   JVMCFG_ARCH := $(OPENJDK_TARGET_CPU_LEGACY)
@@ -99,7 +99,7 @@
 else
   JVMCFG_SRC := $(JDK_TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS_TYPE)/conf/$(JVMCFG_ARCH)/jvm.cfg
   # Allow override by ALT_JVMCFG_SRC if it exists
-  JVMCFG_SRC := $(if $(wildcard $(ALT_JVMCFG_SRC)),$(ALT_JVMCFG_SRC),$(JVMCFG_SRC)) 
+  JVMCFG_SRC := $(if $(wildcard $(ALT_JVMCFG_SRC)),$(ALT_JVMCFG_SRC),$(JVMCFG_SRC))
 endif
 JVMCFG_DIR := $(LIB_DST_DIR)$(OPENJDK_TARGET_CPU_LIBDIR)
 JVMCFG := $(JVMCFG_DIR)/jvm.cfg
@@ -117,12 +117,12 @@
   # The main problem is deciding whether to use aliases for the VMs that are not
   # present and the current position is that we add aliases for client and server, but
   # not for minimal.
-  CLIENT_AND_SERVER := $(and $(findstring true, $(JVM_VARIANT_SERVER)), $(findstring true, $(JVM_VARIANT_CLIENT)))
-  ifeq ($(CLIENT_AND_SERVER), true)
+  CLIENT_AND_SERVER := $(call check-jvm-variant, client)+$(call check-jvm-variant, server)
+  ifeq ($(CLIENT_AND_SERVER), true+true)
     COPY_JVM_CFG_FILE := true
   else
     # For zero, the default jvm.cfg file is sufficient
-    ifeq ($(JVM_VARIANT_ZERO), true)
+    ifeq ($(call check-jvm-variant, zero zeroshark), true)
       COPY_JVM_CFG_FILE := true
     endif
   endif
@@ -136,21 +136,21 @@
 	$(MKDIR) -p $(@D)
 	$(RM) $(@)
         # Now check for other permutations
-        ifeq ($(JVM_VARIANT_SERVER), true)
+        ifeq ($(call check-jvm-variant, server), true)
 	  $(PRINTF) "-server KNOWN\n">>$(@)
 	  $(PRINTF) "-client ALIASED_TO -server\n">>$(@)
-          ifeq ($(JVM_VARIANT_MINIMAL1), true)
+          ifeq ($(call check-jvm-variant, minimal), true)
 	    $(PRINTF) "-minimal KNOWN\n">>$(@)
           endif
         else
-          ifeq ($(JVM_VARIANT_CLIENT), true)
+          ifeq ($(call check-jvm-variant, client), true)
 	    $(PRINTF) "-client KNOWN\n">>$(@)
 	    $(PRINTF) "-server ALIASED_TO -client\n">>$(@)
-            ifeq ($(JVM_VARIANT_MINIMAL1), true)
+            ifeq ($(call check-jvm-variant, minimal), true)
 	      $(PRINTF) "-minimal KNOWN\n">>$(@)
             endif
           else
-            ifeq ($(JVM_VARIANT_MINIMAL1), true)
+            ifeq ($(call check-jvm-variant, minimal), true)
 	      $(PRINTF) "-minimal KNOWN\n">>$(@)
 	      $(PRINTF) "-server ALIASED_TO -minimal\n">>$(@)
 	      $(PRINTF) "-client ALIASED_TO -minimal\n">>$(@)
--- a/jdk/make/data/fontconfig/windows.fontconfig.properties	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/make/data/fontconfig/windows.fontconfig.properties	Wed Jul 05 21:37:42 2017 +0200
@@ -37,6 +37,7 @@
 allfonts.chinese-hkscs=MingLiU_HKSCS
 allfonts.chinese-ms950-extb=MingLiU-ExtB
 allfonts.devanagari=Mangal
+allfonts.kannada=Tunga
 allfonts.dingbats=Wingdings
 allfonts.lucida=Lucida Sans Regular
 allfonts.symbol=Symbol
@@ -239,11 +240,11 @@
 
 sequence.fallback=lucida,symbols,\
                   chinese-ms950,chinese-hkscs,chinese-ms936,chinese-gb18030,\
-                  japanese,korean,chinese-ms950-extb,chinese-ms936-extb,georgian
+                  japanese,korean,chinese-ms950-extb,chinese-ms936-extb,georgian,kannada
 
 # Exclusion Ranges
 
-exclusion.alphabetic=0700-1e9f,1f00-20ab,20ad-f8ff
+exclusion.alphabetic=0700-1e9f,1f00-2017,2020-20ab,20ad-20b8,20bb-20bc,20be-f8ff
 exclusion.chinese-gb18030=0390-03d6,2200-22ef,2701-27be
 exclusion.hebrew=0041-005a,0060-007a,007f-00ff,20ac-20ac
 
@@ -295,6 +296,7 @@
 
 filename.Lucida_Sans_Regular=LucidaSansRegular.ttf
 filename.Mangal=MANGAL.TTF
+filename.Tunga=TUNGA.TTF
 filename.Symbol=SYMBOL.TTF
 filename.Wingdings=WINGDING.TTF
 
--- a/jdk/make/lib/Awt2dLibraries.gmk	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/make/lib/Awt2dLibraries.gmk	Wed Jul 05 21:37:42 2017 +0200
@@ -375,6 +375,7 @@
         OPTIMIZATION := LOW, \
         CFLAGS := $(CFLAGS_JDKLIB) $(LIBAWT_XAWT_CFLAGS) \
             $(X_CFLAGS), \
+        WARNINGS_AS_ERRORS_xlc := false, \
         DISABLED_WARNINGS_gcc := type-limits pointer-to-int-cast \
             deprecated-declarations unused-result maybe-uninitialized format \
             format-security int-to-pointer-cast parentheses, \
@@ -587,6 +588,7 @@
             $(CUPS_CFLAGS) \
             $(X_CFLAGS) \
             $(LIBAWT_HEADLESS_CFLAGS), \
+        DISABLED_WARNINGS_xlc := 1506-356, \
         DISABLED_WARNINGS_gcc := maybe-uninitialized int-to-pointer-cast, \
         DISABLED_WARNINGS_solstudio := E_DECLARATION_IN_CODE \
             E_EMPTY_TRANSLATION_UNIT, \
@@ -603,6 +605,10 @@
         OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libawt_headless, \
     ))
 
+    # AIX warning explanation:
+    # 1506-356 : (W) Compilation unit is empty.
+    #            This happens during the headless build
+
     $(BUILD_LIBAWT_HEADLESS): $(BUILD_LIBAWT)
 
     TARGETS += $(BUILD_LIBAWT_HEADLESS)
@@ -700,6 +706,7 @@
     CXXFLAGS := $(CXXFLAGS_JDKLIB) $(LIBFONTMANAGER_CFLAGS), \
     OPTIMIZATION := $(LIBFONTMANAGER_OPTIMIZATION), \
     CFLAGS_windows = -DCC_NOEX, \
+    WARNINGS_AS_ERRORS_xlc := false, \
     DISABLED_WARNINGS_gcc := sign-compare int-to-pointer-cast \
         type-limits missing-field-initializers, \
     DISABLED_WARNINGS_CXX_gcc := reorder delete-non-virtual-dtor strict-overflow \
--- a/jdk/make/lib/CoreLibraries.gmk	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/make/lib/CoreLibraries.gmk	Wed Jul 05 21:37:42 2017 +0200
@@ -146,6 +146,7 @@
         $(LIBJAVA_CFLAGS), \
     System.c_CFLAGS := $(VERSION_CFLAGS), \
     jdk_util.c_CFLAGS := $(VERSION_CFLAGS), \
+    WARNINGS_AS_ERRORS_xlc := false, \
     DISABLED_WARNINGS_gcc := unused-result, \
     DISABLED_WARNINGS_solstudio := E_STATEMENT_NOT_REACHED, \
     MAPFILE := $(LIBJAVA_MAPFILE), \
@@ -266,7 +267,7 @@
     LDFLAGS_windows := -export:JIMAGE_Open -export:JIMAGE_Close \
         -export:JIMAGE_PackageToModule \
         -export:JIMAGE_FindResource -export:JIMAGE_GetResource \
-        -export:JIMAGE_ResourceIterator, \
+        -export:JIMAGE_ResourceIterator -export:JIMAGE_ResourcePath, \
     LIBS_unix := -ljvm -ldl $(LIBCXX), \
     LIBS_solaris := -lc, \
     LIBS_macosx := -lc++, \
@@ -289,7 +290,7 @@
 
 LIBJLI_CFLAGS := $(CFLAGS_JDKLIB)
 
-ifeq ($(JVM_VARIANT_ZERO), true)
+ifeq ($(call check-jvm-variant, zero zeroshark), true)
   ERGO_FAMILY := zero
 else
   ifeq ($(OPENJDK_TARGET_CPU_ARCH), x86)
--- a/jdk/make/lib/NioLibraries.gmk	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/make/lib/NioLibraries.gmk	Wed Jul 05 21:37:42 2017 +0200
@@ -70,6 +70,7 @@
     SRC := $(BUILD_LIBNIO_SRC), \
     EXCLUDE_FILES := $(BUILD_LIBNIO_EXFILES), \
     OPTIMIZATION := HIGH, \
+    WARNINGS_AS_ERRORS_xlc := false, \
     CFLAGS := $(CFLAGS_JDKLIB) \
         $(BUILD_LIBNIO_CFLAGS), \
     MAPFILE := $(BUILD_LIBNIO_MAPFILE), \
--- a/jdk/make/mapfiles/libjava/mapfile-vers	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/make/mapfiles/libjava/mapfile-vers	Wed Jul 05 21:37:42 2017 +0200
@@ -139,8 +139,7 @@
 		Java_java_lang_Double_doubleToRawLongBits;
 		Java_java_lang_Float_intBitsToFloat;
 		Java_java_lang_Float_floatToRawIntBits;
-                Java_java_lang_StackFrameInfo_fillInStackFrames;
-                Java_java_lang_StackFrameInfo_setMethodInfo;
+                Java_java_lang_StackFrameInfo_toStackTraceElement0;
                 Java_java_lang_StackStreamFactory_checkStackWalkModes;
                 Java_java_lang_StackStreamFactory_00024AbstractStackWalker_callStackWalk;
                 Java_java_lang_StackStreamFactory_00024AbstractStackWalker_fetchStackFrames;
--- a/jdk/make/mapfiles/libjimage/mapfile-vers	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/make/mapfiles/libjimage/mapfile-vers	Wed Jul 05 21:37:42 2017 +0200
@@ -34,6 +34,7 @@
         JIMAGE_FindResource;
         JIMAGE_GetResource;
         JIMAGE_ResourceIterator;
+        JIMAGE_ResourcePath;
     local:
         *;
 };
--- a/jdk/src/java.base/aix/native/libnet/aix_close.c	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/aix/native/libnet/aix_close.c	Wed Jul 05 21:37:42 2017 +0200
@@ -1,5 +1,6 @@
 /*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, SAP SE 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,6 +51,8 @@
    ...
 */
 
+#include <assert.h>
+#include <limits.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <signal.h>
@@ -86,10 +89,35 @@
 static int sigWakeup = (SIGRTMAX - 1);
 
 /*
- * The fd table and the number of file descriptors
+ * fdTable holds one entry per file descriptor, up to a certain
+ * maximum.
+ * Theoretically, the number of possible file descriptors can get
+ * large, though usually it does not. Entries for small value file
+ * descriptors are kept in a simple table, which covers most scenarios.
+ * Entries for large value file descriptors are kept in an overflow
+ * table, which is organized as a sparse two dimensional array whose
+ * slabs are allocated on demand. This covers all corner cases while
+ * keeping memory consumption reasonable.
  */
-static fdEntry_t *fdTable = NULL;
-static int fdCount = 0;
+
+/* Base table for low value file descriptors */
+static fdEntry_t* fdTable = NULL;
+/* Maximum size of base table (in number of entries). */
+static const int fdTableMaxSize = 0x1000; /* 4K */
+/* Actual size of base table (in number of entries) */
+static int fdTableLen = 0;
+/* Max. theoretical number of file descriptors on system. */
+static int fdLimit = 0;
+
+/* Overflow table, should base table not be large enough. Organized as
+ *   an array of n slabs, each holding 64k entries.
+ */
+static fdEntry_t** fdOverflowTable = NULL;
+/* Number of slabs in the overflow table */
+static int fdOverflowTableLen = 0;
+/* Number of entries in one slab */
+static const int fdOverflowTableSlabSize = 0x10000; /* 64k */
+pthread_mutex_t fdOverflowTableLock = PTHREAD_MUTEX_INITIALIZER;
 
 /*
  * Null signal handler
@@ -108,42 +136,42 @@
     struct rlimit nbr_files;
     sigset_t sigset;
     struct sigaction sa;
+    int i = 0;
 
-    /* Check already initialized */
-    if (fdCount > 0 && fdTable != NULL) {
-        return;
-    }
-
-    /*
-     * Allocate table based on the maximum number of
-     * file descriptors.
-     */
+    /* Determine the maximum number of possible file descriptors. */
     if (-1 == getrlimit(RLIMIT_NOFILE, &nbr_files)) {
         fprintf(stderr, "library initialization failed - "
                 "unable to get max # of allocated fds\n");
         abort();
     }
-    fdCount = nbr_files.rlim_max;
-    /*
-     * We have a conceptual problem here, when the number of files is
-     * unlimited. As a kind of workaround, we ensure the table is big
-     * enough for handle even a large number of files. Since SAP itself
-     * recommends a limit of 32000 files, we just use 64000 as 'infinity'.
-     */
-    if (nbr_files.rlim_max == RLIM_INFINITY) {
-        fdCount = 64000;
+    if (nbr_files.rlim_max != RLIM_INFINITY) {
+        fdLimit = nbr_files.rlim_max;
+    } else {
+        /* We just do not know. */
+        fdLimit = INT_MAX;
     }
-    fdTable = (fdEntry_t *)calloc(fdCount, sizeof(fdEntry_t));
+
+    /* Allocate table for low value file descriptors. */
+    fdTableLen = fdLimit < fdTableMaxSize ? fdLimit : fdTableMaxSize;
+    fdTable = (fdEntry_t*) calloc(fdTableLen, sizeof(fdEntry_t));
     if (fdTable == NULL) {
         fprintf(stderr, "library initialization failed - "
                 "unable to allocate file descriptor table - out of memory");
         abort();
+    } else {
+        for (i = 0; i < fdTableLen; i ++) {
+            pthread_mutex_init(&fdTable[i].lock, NULL);
+        }
     }
 
-    {
-        int i;
-        for (i=0; i < fdCount; i++) {
-            pthread_mutex_init(&fdTable[i].lock, NULL);
+    /* Allocate overflow table, if needed */
+    if (fdLimit > fdTableMaxSize) {
+        fdOverflowTableLen = ((fdLimit - fdTableMaxSize) / fdOverflowTableSlabSize) + 1;
+        fdOverflowTable = (fdEntry_t**) calloc(fdOverflowTableLen, sizeof(fdEntry_t*));
+        if (fdOverflowTable == NULL) {
+            fprintf(stderr, "library initialization failed - "
+                    "unable to allocate file descriptor overflow table - out of memory");
+            abort();
         }
     }
 
@@ -161,17 +189,60 @@
 }
 
 /*
- * Return the fd table for this fd or NULL is fd out
- * of range.
+ * Return the fd table for this fd.
  */
 static inline fdEntry_t *getFdEntry(int fd)
 {
-    if (fd < 0 || fd >= fdCount) {
+    fdEntry_t* result = NULL;
+
+    if (fd < 0) {
         return NULL;
     }
-    return &fdTable[fd];
+
+    /* This should not happen. If it does, our assumption about
+     * max. fd value was wrong. */
+    assert(fd < fdLimit);
+
+    if (fd < fdTableMaxSize) {
+        /* fd is in base table. */
+        assert(fd < fdTableLen);
+        result = &fdTable[fd];
+    } else {
+        /* fd is in overflow table. */
+        const int indexInOverflowTable = fd - fdTableMaxSize;
+        const int rootindex = indexInOverflowTable / fdOverflowTableSlabSize;
+        const int slabindex = indexInOverflowTable % fdOverflowTableSlabSize;
+        fdEntry_t* slab = NULL;
+        assert(rootindex < fdOverflowTableLen);
+        assert(slabindex < fdOverflowTableSlabSize);
+        pthread_mutex_lock(&fdOverflowTableLock);
+        /* Allocate new slab in overflow table if needed */
+        if (fdOverflowTable[rootindex] == NULL) {
+            fdEntry_t* const newSlab =
+                (fdEntry_t*)calloc(fdOverflowTableSlabSize, sizeof(fdEntry_t));
+            if (newSlab == NULL) {
+                fprintf(stderr, "Unable to allocate file descriptor overflow"
+                        " table slab - out of memory");
+                pthread_mutex_unlock(&fdOverflowTableLock);
+                abort();
+            } else {
+                int i;
+                for (i = 0; i < fdOverflowTableSlabSize; i ++) {
+                    pthread_mutex_init(&newSlab[i].lock, NULL);
+                }
+                fdOverflowTable[rootindex] = newSlab;
+            }
+        }
+        pthread_mutex_unlock(&fdOverflowTableLock);
+        slab = fdOverflowTable[rootindex];
+        result = &slab[slabindex];
+    }
+
+    return result;
+
 }
 
+
 /*
  * Start a blocking operation :-
  *    Insert thread onto thread list for the fd.
--- a/jdk/src/java.base/linux/classes/sun/nio/fs/LinuxFileSystemProvider.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/linux/classes/sun/nio/fs/LinuxFileSystemProvider.java	Wed Jul 05 21:37:42 2017 +0200
@@ -102,8 +102,8 @@
 
     @Override
     FileTypeDetector getFileTypeDetector() {
-        Path userMimeTypes = Paths.get(AccessController.doPrivileged(
-            new GetPropertyAction("user.home")), ".mime.types");
+        String userHome = GetPropertyAction.getProperty("user.home");
+        Path userMimeTypes = Paths.get(userHome, ".mime.types");
         Path etcMimeTypes = Paths.get("/etc/mime.types");
 
         return chain(new GioFileTypeDetector(),
--- a/jdk/src/java.base/linux/native/libnet/linux_close.c	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/linux/native/libnet/linux_close.c	Wed Jul 05 21:37:42 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2013, 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
@@ -23,6 +23,8 @@
  * questions.
  */
 
+#include <assert.h>
+#include <limits.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <signal.h>
@@ -59,10 +61,35 @@
 static int sigWakeup = (__SIGRTMAX - 2);
 
 /*
- * The fd table and the number of file descriptors
+ * fdTable holds one entry per file descriptor, up to a certain
+ * maximum.
+ * Theoretically, the number of possible file descriptors can get
+ * large, though usually it does not. Entries for small value file
+ * descriptors are kept in a simple table, which covers most scenarios.
+ * Entries for large value file descriptors are kept in an overflow
+ * table, which is organized as a sparse two dimensional array whose
+ * slabs are allocated on demand. This covers all corner cases while
+ * keeping memory consumption reasonable.
  */
-static fdEntry_t *fdTable;
-static int fdCount;
+
+/* Base table for low value file descriptors */
+static fdEntry_t* fdTable = NULL;
+/* Maximum size of base table (in number of entries). */
+static const int fdTableMaxSize = 0x1000; /* 4K */
+/* Actual size of base table (in number of entries) */
+static int fdTableLen = 0;
+/* Max. theoretical number of file descriptors on system. */
+static int fdLimit = 0;
+
+/* Overflow table, should base table not be large enough. Organized as
+ *   an array of n slabs, each holding 64k entries.
+ */
+static fdEntry_t** fdOverflowTable = NULL;
+/* Number of slabs in the overflow table */
+static int fdOverflowTableLen = 0;
+/* Number of entries in one slab */
+static const int fdOverflowTableSlabSize = 0x10000; /* 64k */
+pthread_mutex_t fdOverflowTableLock = PTHREAD_MUTEX_INITIALIZER;
 
 /*
  * Null signal handler
@@ -78,18 +105,43 @@
     struct rlimit nbr_files;
     sigset_t sigset;
     struct sigaction sa;
+    int i = 0;
 
-    /*
-     * Allocate table based on the maximum number of
-     * file descriptors.
-     */
-    getrlimit(RLIMIT_NOFILE, &nbr_files);
-    fdCount = nbr_files.rlim_max;
-    fdTable = (fdEntry_t *)calloc(fdCount, sizeof(fdEntry_t));
+    /* Determine the maximum number of possible file descriptors. */
+    if (-1 == getrlimit(RLIMIT_NOFILE, &nbr_files)) {
+        fprintf(stderr, "library initialization failed - "
+                "unable to get max # of allocated fds\n");
+        abort();
+    }
+    if (nbr_files.rlim_max != RLIM_INFINITY) {
+        fdLimit = nbr_files.rlim_max;
+    } else {
+        /* We just do not know. */
+        fdLimit = INT_MAX;
+    }
+
+    /* Allocate table for low value file descriptors. */
+    fdTableLen = fdLimit < fdTableMaxSize ? fdLimit : fdTableMaxSize;
+    fdTable = (fdEntry_t*) calloc(fdTableLen, sizeof(fdEntry_t));
     if (fdTable == NULL) {
         fprintf(stderr, "library initialization failed - "
                 "unable to allocate file descriptor table - out of memory");
         abort();
+    } else {
+        for (i = 0; i < fdTableLen; i ++) {
+            pthread_mutex_init(&fdTable[i].lock, NULL);
+        }
+    }
+
+    /* Allocate overflow table, if needed */
+    if (fdLimit > fdTableMaxSize) {
+        fdOverflowTableLen = ((fdLimit - fdTableMaxSize) / fdOverflowTableSlabSize) + 1;
+        fdOverflowTable = (fdEntry_t**) calloc(fdOverflowTableLen, sizeof(fdEntry_t*));
+        if (fdOverflowTable == NULL) {
+            fprintf(stderr, "library initialization failed - "
+                    "unable to allocate file descriptor overflow table - out of memory");
+            abort();
+        }
     }
 
     /*
@@ -106,15 +158,57 @@
 }
 
 /*
- * Return the fd table for this fd or NULL is fd out
- * of range.
+ * Return the fd table for this fd.
  */
 static inline fdEntry_t *getFdEntry(int fd)
 {
-    if (fd < 0 || fd >= fdCount) {
+    fdEntry_t* result = NULL;
+
+    if (fd < 0) {
         return NULL;
     }
-    return &fdTable[fd];
+
+    /* This should not happen. If it does, our assumption about
+     * max. fd value was wrong. */
+    assert(fd < fdLimit);
+
+    if (fd < fdTableMaxSize) {
+        /* fd is in base table. */
+        assert(fd < fdTableLen);
+        result = &fdTable[fd];
+    } else {
+        /* fd is in overflow table. */
+        const int indexInOverflowTable = fd - fdTableMaxSize;
+        const int rootindex = indexInOverflowTable / fdOverflowTableSlabSize;
+        const int slabindex = indexInOverflowTable % fdOverflowTableSlabSize;
+        fdEntry_t* slab = NULL;
+        assert(rootindex < fdOverflowTableLen);
+        assert(slabindex < fdOverflowTableSlabSize);
+        pthread_mutex_lock(&fdOverflowTableLock);
+        /* Allocate new slab in overflow table if needed */
+        if (fdOverflowTable[rootindex] == NULL) {
+            fdEntry_t* const newSlab =
+                (fdEntry_t*)calloc(fdOverflowTableSlabSize, sizeof(fdEntry_t));
+            if (newSlab == NULL) {
+                fprintf(stderr, "Unable to allocate file descriptor overflow"
+                        " table slab - out of memory");
+                pthread_mutex_unlock(&fdOverflowTableLock);
+                abort();
+            } else {
+                int i;
+                for (i = 0; i < fdOverflowTableSlabSize; i ++) {
+                    pthread_mutex_init(&newSlab[i].lock, NULL);
+                }
+                fdOverflowTable[rootindex] = newSlab;
+            }
+        }
+        pthread_mutex_unlock(&fdOverflowTableLock);
+        slab = fdOverflowTable[rootindex];
+        result = &slab[slabindex];
+    }
+
+    return result;
+
 }
 
 /*
--- a/jdk/src/java.base/macosx/classes/sun/nio/ch/KQueueArrayWrapper.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/macosx/classes/sun/nio/ch/KQueueArrayWrapper.java	Wed Jul 05 21:37:42 2017 +0200
@@ -32,9 +32,9 @@
 package sun.nio.ch;
 
 import java.io.IOException;
-import java.io.FileDescriptor;
 import java.util.Iterator;
 import java.util.LinkedList;
+import sun.security.action.GetPropertyAction;
 
 /*
  * struct kevent {           // 32-bit    64-bit
@@ -84,10 +84,8 @@
     static {
         IOUtil.load();
         initStructSizes();
-        String datamodel = java.security.AccessController.doPrivileged(
-            new sun.security.action.GetPropertyAction("sun.arch.data.model")
-        );
-        is64bit = datamodel.equals("64");
+        String datamodel = GetPropertyAction.getProperty("sun.arch.data.model");
+        is64bit = "64".equals(datamodel);
     }
 
     KQueueArrayWrapper() {
--- a/jdk/src/java.base/macosx/classes/sun/nio/fs/MacOSXFileSystemProvider.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/macosx/classes/sun/nio/fs/MacOSXFileSystemProvider.java	Wed Jul 05 21:37:42 2017 +0200
@@ -28,7 +28,6 @@
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.nio.file.spi.FileTypeDetector;
-import java.security.AccessController;
 import sun.security.action.GetPropertyAction;
 
 /**
@@ -47,8 +46,8 @@
 
     @Override
     FileTypeDetector getFileTypeDetector() {
-        Path userMimeTypes = Paths.get(AccessController.doPrivileged(
-            new GetPropertyAction("user.home")), ".mime.types");
+        Path userMimeTypes = Paths.get(
+            GetPropertyAction.getProperty("user.home"), ".mime.types");
 
         return chain(new MimeTypesFileTypeDetector(userMimeTypes),
                      new UTIFileTypeDetector());
--- a/jdk/src/java.base/macosx/native/libnet/bsd_close.c	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/macosx/native/libnet/bsd_close.c	Wed Jul 05 21:37:42 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2012, 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
@@ -23,6 +23,8 @@
  * questions.
  */
 
+#include <assert.h>
+#include <limits.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <sys/param.h>
@@ -61,18 +63,35 @@
 static int sigWakeup = SIGIO;
 
 /*
- * The fd table and the number of file descriptors
+ * fdTable holds one entry per file descriptor, up to a certain
+ * maximum.
+ * Theoretically, the number of possible file descriptors can get
+ * large, though usually it does not. Entries for small value file
+ * descriptors are kept in a simple table, which covers most scenarios.
+ * Entries for large value file descriptors are kept in an overflow
+ * table, which is organized as a sparse two dimensional array whose
+ * slabs are allocated on demand. This covers all corner cases while
+ * keeping memory consumption reasonable.
  */
-static fdEntry_t *fdTable;
-static int fdCount;
 
-/*
- * This limit applies if getlimit() returns unlimited.
- * Unfortunately, this means if someone wants a higher limit
- * then they have to set an explicit limit, higher than this,
- * which is probably counter-intuitive.
+/* Base table for low value file descriptors */
+static fdEntry_t* fdTable = NULL;
+/* Maximum size of base table (in number of entries). */
+static const int fdTableMaxSize = 0x1000; /* 4K */
+/* Actual size of base table (in number of entries) */
+static int fdTableLen = 0;
+/* Max. theoretical number of file descriptors on system. */
+static int fdLimit = 0;
+
+/* Overflow table, should base table not be large enough. Organized as
+ *   an array of n slabs, each holding 64k entries.
  */
-#define MAX_FD_COUNT 4096
+static fdEntry_t** fdOverflowTable = NULL;
+/* Number of slabs in the overflow table */
+static int fdOverflowTableLen = 0;
+/* Number of entries in one slab */
+static const int fdOverflowTableSlabSize = 0x10000; /* 64k */
+pthread_mutex_t fdOverflowTableLock = PTHREAD_MUTEX_INITIALIZER;
 
 /*
  * Null signal handler
@@ -88,26 +107,43 @@
     struct rlimit nbr_files;
     sigset_t sigset;
     struct sigaction sa;
-    int i;
+    int i = 0;
 
-    /*
-     * Allocate table based on the maximum number of
-     * file descriptors.
-     */
-    getrlimit(RLIMIT_NOFILE, &nbr_files);
-    if (nbr_files.rlim_max == RLIM_INFINITY) {
-        fdCount = MAX_FD_COUNT;
+    /* Determine the maximum number of possible file descriptors. */
+    if (-1 == getrlimit(RLIMIT_NOFILE, &nbr_files)) {
+        fprintf(stderr, "library initialization failed - "
+                "unable to get max # of allocated fds\n");
+        abort();
+    }
+    if (nbr_files.rlim_max != RLIM_INFINITY) {
+        fdLimit = nbr_files.rlim_max;
     } else {
-        fdCount = nbr_files.rlim_max;
+        /* We just do not know. */
+        fdLimit = INT_MAX;
     }
-    fdTable = (fdEntry_t *)calloc(fdCount, sizeof(fdEntry_t));
+
+    /* Allocate table for low value file descriptors. */
+    fdTableLen = fdLimit < fdTableMaxSize ? fdLimit : fdTableMaxSize;
+    fdTable = (fdEntry_t*) calloc(fdTableLen, sizeof(fdEntry_t));
     if (fdTable == NULL) {
         fprintf(stderr, "library initialization failed - "
                 "unable to allocate file descriptor table - out of memory");
         abort();
+    } else {
+        for (i = 0; i < fdTableLen; i ++) {
+            pthread_mutex_init(&fdTable[i].lock, NULL);
+        }
     }
-    for (i=0; i<fdCount; i++) {
-        pthread_mutex_init(&fdTable[i].lock, NULL);
+
+    /* Allocate overflow table, if needed */
+    if (fdLimit > fdTableMaxSize) {
+        fdOverflowTableLen = ((fdLimit - fdTableMaxSize) / fdOverflowTableSlabSize) + 1;
+        fdOverflowTable = (fdEntry_t**) calloc(fdOverflowTableLen, sizeof(fdEntry_t*));
+        if (fdOverflowTable == NULL) {
+            fprintf(stderr, "library initialization failed - "
+                    "unable to allocate file descriptor overflow table - out of memory");
+            abort();
+        }
     }
 
     /*
@@ -124,17 +160,60 @@
 }
 
 /*
- * Return the fd table for this fd or NULL is fd out
- * of range.
+ * Return the fd table for this fd.
  */
 static inline fdEntry_t *getFdEntry(int fd)
 {
-    if (fd < 0 || fd >= fdCount) {
+    fdEntry_t* result = NULL;
+
+    if (fd < 0) {
         return NULL;
     }
-    return &fdTable[fd];
+
+    /* This should not happen. If it does, our assumption about
+     * max. fd value was wrong. */
+    assert(fd < fdLimit);
+
+    if (fd < fdTableMaxSize) {
+        /* fd is in base table. */
+        assert(fd < fdTableLen);
+        result = &fdTable[fd];
+    } else {
+        /* fd is in overflow table. */
+        const int indexInOverflowTable = fd - fdTableMaxSize;
+        const int rootindex = indexInOverflowTable / fdOverflowTableSlabSize;
+        const int slabindex = indexInOverflowTable % fdOverflowTableSlabSize;
+        fdEntry_t* slab = NULL;
+        assert(rootindex < fdOverflowTableLen);
+        assert(slabindex < fdOverflowTableSlabSize);
+        pthread_mutex_lock(&fdOverflowTableLock);
+        /* Allocate new slab in overflow table if needed */
+        if (fdOverflowTable[rootindex] == NULL) {
+            fdEntry_t* const newSlab =
+                (fdEntry_t*)calloc(fdOverflowTableSlabSize, sizeof(fdEntry_t));
+            if (newSlab == NULL) {
+                fprintf(stderr, "Unable to allocate file descriptor overflow"
+                        " table slab - out of memory");
+                pthread_mutex_unlock(&fdOverflowTableLock);
+                abort();
+            } else {
+                int i;
+                for (i = 0; i < fdOverflowTableSlabSize; i ++) {
+                    pthread_mutex_init(&newSlab[i].lock, NULL);
+                }
+                fdOverflowTable[rootindex] = newSlab;
+            }
+        }
+        pthread_mutex_unlock(&fdOverflowTableLock);
+        slab = fdOverflowTable[rootindex];
+        result = &slab[slabindex];
+    }
+
+    return result;
+
 }
 
+
 /*
  * Start a blocking operation :-
  *    Insert thread onto thread list for the fd.
--- a/jdk/src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java	Wed Jul 05 21:37:42 2017 +0200
@@ -512,11 +512,17 @@
         byte[] sOut = new byte[s.length];
         GCTR gctrForSToTag = new GCTR(embeddedCipher, this.preCounterBlock);
         gctrForSToTag.doFinal(s, 0, s.length, sOut, 0);
+
+        // check entire authentication tag for time-consistency
+        int mismatch = 0;
         for (int i = 0; i < tagLenBytes; i++) {
-            if (tag[i] != sOut[i]) {
-                throw new AEADBadTagException("Tag mismatch!");
-            }
+            mismatch |= tag[i] ^ sOut[i];
         }
+
+        if (mismatch != 0) {
+            throw new AEADBadTagException("Tag mismatch!");
+        }
+
         return len;
     }
 
--- a/jdk/src/java.base/share/classes/java/io/DataInput.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/io/DataInput.java	Wed Jul 05 21:37:42 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 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
@@ -182,10 +182,11 @@
      * not all bytes of {@code b} have been
      * updated with data from the input stream.
      *
-     * @param     b   the buffer into which the data is read.
-     * @exception  EOFException  if this stream reaches the end before reading
-     *               all the bytes.
-     * @exception  IOException   if an I/O error occurs.
+     * @param   b   the buffer into which the data is read.
+     * @throws  NullPointerException if {@code b} is {@code null}.
+     * @throws  EOFException  if this stream reaches the end before reading
+     *          all the bytes.
+     * @throws  IOException   if an I/O error occurs.
      */
     void readFully(byte b[]) throws IOException;
 
@@ -226,12 +227,16 @@
      * and so on. The number of bytes read is,
      * at most, equal to {@code len}.
      *
-     * @param     b   the buffer into which the data is read.
-     * @param off  an int specifying the offset into the data.
-     * @param len  an int specifying the number of bytes to read.
-     * @exception  EOFException  if this stream reaches the end before reading
-     *               all the bytes.
-     * @exception  IOException   if an I/O error occurs.
+     * @param   b    the buffer into which the data is read.
+     * @param   off  an int specifying the offset in the data array {@code b}.
+     * @param   len  an int specifying the number of bytes to read.
+     * @throws  NullPointerException if {@code b} is {@code null}.
+     * @throws  IndexOutOfBoundsException if {@code off} is negative,
+     *          {@code len} is negative, or {@code len} is greater than
+     *          {@code b.length - off}.
+     * @throws  EOFException  if this stream reaches the end before reading
+     *          all the bytes.
+     * @throws  IOException   if an I/O error occurs.
      */
     void readFully(byte b[], int off, int len) throws IOException;
 
--- a/jdk/src/java.base/share/classes/java/io/DataInputStream.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/io/DataInputStream.java	Wed Jul 05 21:37:42 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 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
@@ -150,38 +150,43 @@
     }
 
     /**
-     * See the general contract of the <code>readFully</code>
-     * method of <code>DataInput</code>.
+     * See the general contract of the {@code readFully}
+     * method of {@code DataInput}.
      * <p>
      * Bytes
      * for this operation are read from the contained
      * input stream.
      *
-     * @param      b   the buffer into which the data is read.
-     * @exception  EOFException  if this input stream reaches the end before
-     *             reading all the bytes.
-     * @exception  IOException   the stream has been closed and the contained
-     *             input stream does not support reading after close, or
-     *             another I/O error occurs.
-     * @see        java.io.FilterInputStream#in
+     * @param   b   the buffer into which the data is read.
+     * @throws  NullPointerException if {@code b} is {@code null}.
+     * @throws  EOFException  if this input stream reaches the end before
+     *          reading all the bytes.
+     * @throws  IOException   the stream has been closed and the contained
+     *          input stream does not support reading after close, or
+     *          another I/O error occurs.
+     * @see     java.io.FilterInputStream#in
      */
     public final void readFully(byte b[]) throws IOException {
         readFully(b, 0, b.length);
     }
 
     /**
-     * See the general contract of the <code>readFully</code>
-     * method of <code>DataInput</code>.
+     * See the general contract of the {@code readFully}
+     * method of {@code DataInput}.
      * <p>
      * Bytes
      * for this operation are read from the contained
      * input stream.
      *
      * @param      b     the buffer into which the data is read.
-     * @param      off   the start offset of the data.
+     * @param      off   the start offset in the data array {@code b}.
      * @param      len   the number of bytes to read.
+     * @exception  NullPointerException if {@code b} is {@code null}.
+     * @exception  IndexOutOfBoundsException if {@code off} is negative,
+     *             {@code len} is negative, or {@code len} is greater than
+     *             {@code b.length - off}.
      * @exception  EOFException  if this input stream reaches the end before
-     *               reading all the bytes.
+     *             reading all the bytes.
      * @exception  IOException   the stream has been closed and the contained
      *             input stream does not support reading after close, or
      *             another I/O error occurs.
--- a/jdk/src/java.base/share/classes/java/io/File.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/io/File.java	Wed Jul 05 21:37:42 2017 +0200
@@ -31,7 +31,6 @@
 import java.net.URISyntaxException;
 import java.util.List;
 import java.util.ArrayList;
-import java.security.AccessController;
 import java.security.SecureRandom;
 import java.nio.file.Path;
 import java.nio.file.FileSystems;
@@ -1896,8 +1895,8 @@
         private TempDirectory() { }
 
         // temporary directory location
-        private static final File tmpdir = new File(AccessController
-            .doPrivileged(new GetPropertyAction("java.io.tmpdir")));
+        private static final File tmpdir = new File(
+                GetPropertyAction.getProperty("java.io.tmpdir"));
         static File location() {
             return tmpdir;
         }
--- a/jdk/src/java.base/share/classes/java/io/ObjectInputStream.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/io/ObjectInputStream.java	Wed Jul 05 21:37:42 2017 +0200
@@ -40,6 +40,9 @@
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import static java.io.ObjectStreamClass.processQueue;
+import jdk.internal.misc.JavaObjectInputStreamAccess;
+import jdk.internal.misc.ObjectStreamClassValidator;
+import jdk.internal.misc.SharedSecrets;
 import jdk.internal.misc.Unsafe;
 import sun.reflect.misc.ReflectUtil;
 
@@ -853,10 +856,14 @@
      * exactly 'length' bytes.
      *
      * @param   buf the buffer into which the data is read
-     * @param   off the start offset of the data
+     * @param   off the start offset in the destination array {@code buf}
      * @param   len the maximum number of bytes read
      * @return  the actual number of bytes read, -1 is returned when the end of
      *          the stream is reached.
+     * @throws  NullPointerException if {@code buf} is {@code null}.
+     * @throws  IndexOutOfBoundsException if {@code off} is negative,
+     *          {@code len} is negative, or {@code len} is greater than
+     *          {@code buf.length - off}.
      * @throws  IOException If an I/O error has occurred.
      * @see java.io.DataInputStream#readFully(byte[],int,int)
      */
@@ -1014,6 +1021,7 @@
      * Reads bytes, blocking until all bytes are read.
      *
      * @param   buf the buffer into which the data is read
+     * @throws  NullPointerException If {@code buf} is {@code null}.
      * @throws  EOFException If end of file is reached.
      * @throws  IOException If other I/O error has occurred.
      */
@@ -1025,8 +1033,12 @@
      * Reads bytes, blocking until all bytes are read.
      *
      * @param   buf the buffer into which the data is read
-     * @param   off the start offset of the data
+     * @param   off the start offset into the data array {@code buf}
      * @param   len the maximum number of bytes to read
+     * @throws  NullPointerException If {@code buf} is {@code null}.
+     * @throws  IndexOutOfBoundsException If {@code off} is negative,
+     *          {@code len} is negative, or {@code len} is greater than
+     *          {@code buf.length - off}.
      * @throws  EOFException If end of file is reached.
      * @throws  IOException If other I/O error has occurred.
      */
@@ -1509,23 +1521,28 @@
         throws IOException
     {
         byte tc = bin.peekByte();
+        ObjectStreamClass descriptor;
         switch (tc) {
             case TC_NULL:
-                return (ObjectStreamClass) readNull();
-
+                descriptor = (ObjectStreamClass) readNull();
+                break;
             case TC_REFERENCE:
-                return (ObjectStreamClass) readHandle(unshared);
-
+                descriptor = (ObjectStreamClass) readHandle(unshared);
+                break;
             case TC_PROXYCLASSDESC:
-                return readProxyDesc(unshared);
-
+                descriptor = readProxyDesc(unshared);
+                break;
             case TC_CLASSDESC:
-                return readNonProxyDesc(unshared);
-
+                descriptor = readNonProxyDesc(unshared);
+                break;
             default:
                 throw new StreamCorruptedException(
                     String.format("invalid type code: %02X", tc));
         }
+        if (descriptor != null) {
+            validateDescriptor(descriptor);
+        }
+        return descriptor;
     }
 
     private boolean isCustomSubclass() {
@@ -1915,6 +1932,8 @@
                 if (obj == null || handles.lookupException(passHandle) != null) {
                     defaultReadFields(null, slotDesc); // skip field values
                 } else if (slotDesc.hasReadObjectMethod()) {
+                    ThreadDeath t = null;
+                    boolean reset = false;
                     SerialCallbackContext oldContext = curContext;
                     if (oldContext != null)
                         oldContext.check();
@@ -1933,10 +1952,19 @@
                          */
                         handles.markException(passHandle, ex);
                     } finally {
-                        curContext.setUsed();
-                        if (oldContext!= null)
-                            oldContext.check();
-                        curContext = oldContext;
+                        do {
+                            try {
+                                curContext.setUsed();
+                                if (oldContext!= null)
+                                    oldContext.check();
+                                curContext = oldContext;
+                                reset = true;
+                            } catch (ThreadDeath x) {
+                                t = x;  // defer until reset is true
+                            }
+                        } while (!reset);
+                        if (t != null)
+                            throw t;
                     }
 
                     /*
@@ -3647,4 +3675,20 @@
         }
     }
 
+    private void validateDescriptor(ObjectStreamClass descriptor) {
+        ObjectStreamClassValidator validating = validator;
+        if (validating != null) {
+            validating.validateDescriptor(descriptor);
+        }
+    }
+
+    // controlled access to ObjectStreamClassValidator
+    private volatile ObjectStreamClassValidator validator;
+
+    private static void setValidator(ObjectInputStream ois, ObjectStreamClassValidator validator) {
+        ois.validator = validator;
+    }
+    static {
+        SharedSecrets.setJavaObjectInputStreamAccess(ObjectInputStream::setValidator);
+    }
 }
--- a/jdk/src/java.base/share/classes/java/io/RandomAccessFile.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/io/RandomAccessFile.java	Wed Jul 05 21:37:42 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 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
@@ -418,10 +418,11 @@
      * read. This method blocks until the requested number of bytes are
      * read, the end of the stream is detected, or an exception is thrown.
      *
-     * @param      b   the buffer into which the data is read.
-     * @exception  EOFException  if this file reaches the end before reading
-     *               all the bytes.
-     * @exception  IOException   if an I/O error occurs.
+     * @param   b   the buffer into which the data is read.
+     * @throws  NullPointerException if {@code b} is {@code null}.
+     * @throws  EOFException  if this file reaches the end before reading
+     *              all the bytes.
+     * @throws  IOException   if an I/O error occurs.
      */
     public final void readFully(byte b[]) throws IOException {
         readFully(b, 0, b.length);
@@ -434,12 +435,16 @@
      * read. This method blocks until the requested number of bytes are
      * read, the end of the stream is detected, or an exception is thrown.
      *
-     * @param      b     the buffer into which the data is read.
-     * @param      off   the start offset of the data.
-     * @param      len   the number of bytes to read.
-     * @exception  EOFException  if this file reaches the end before reading
-     *               all the bytes.
-     * @exception  IOException   if an I/O error occurs.
+     * @param   b     the buffer into which the data is read.
+     * @param   off   the start offset into the data array {@code b}.
+     * @param   len   the number of bytes to read.
+     * @throws  NullPointerException if {@code b} is {@code null}.
+     * @throws  IndexOutOfBoundsException if {@code off} is negative,
+     *                {@code len} is negative, or {@code len} is greater than
+     *                {@code b.length - off}.
+     * @throws  EOFException  if this file reaches the end before reading
+     *                all the bytes.
+     * @throws  IOException   if an I/O error occurs.
      */
     public final void readFully(byte b[], int off, int len) throws IOException {
         int n = 0;
--- a/jdk/src/java.base/share/classes/java/lang/Boolean.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/Boolean.java	Wed Jul 05 21:37:42 2017 +0200
@@ -79,13 +79,16 @@
      * Allocates a {@code Boolean} object representing the
      * {@code value} argument.
      *
-     * <p><b>Note: It is rarely appropriate to use this constructor.
-     * Unless a <i>new</i> instance is required, the static factory
-     * {@link #valueOf(boolean)} is generally a better choice. It is
-     * likely to yield significantly better space and time performance.</b>
+     * @param   value   the value of the {@code Boolean}.
      *
-     * @param   value   the value of the {@code Boolean}.
+     * @deprecated
+     * It is rarely appropriate to use this constructor. The static factory
+     * {@link #valueOf(boolean)} is generally a better choice, as it is
+     * likely to yield significantly better space and time performance.
+     * Also consider using the final fields {@link #TRUE} and {@link #FALSE}
+     * if possible.
      */
+    @Deprecated(since="9")
     public Boolean(boolean value) {
         this.value = value;
     }
@@ -94,15 +97,18 @@
      * Allocates a {@code Boolean} object representing the value
      * {@code true} if the string argument is not {@code null}
      * and is equal, ignoring case, to the string {@code "true"}.
-     * Otherwise, allocate a {@code Boolean} object representing the
-     * value {@code false}. Examples:<p>
-     * {@code new Boolean("True")} produces a {@code Boolean} object
-     * that represents {@code true}.<br>
-     * {@code new Boolean("yes")} produces a {@code Boolean} object
-     * that represents {@code false}.
+     * Otherwise, allocates a {@code Boolean} object representing the
+     * value {@code false}.
      *
      * @param   s   the string to be converted to a {@code Boolean}.
+     *
+     * @deprecated
+     * It is rarely appropriate to use this constructor.
+     * Use {@link #parseBoolean(String)} to convert a string to a
+     * {@code boolean} primitive, or use {@link #valueOf(String)}
+     * to convert a string to a {@code Boolean} object.
      */
+    @Deprecated(since="9")
     public Boolean(String s) {
         this(parseBoolean(s));
     }
--- a/jdk/src/java.base/share/classes/java/lang/Byte.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/Byte.java	Wed Jul 05 21:37:42 2017 +0200
@@ -297,7 +297,13 @@
      *
      * @param value     the value to be represented by the
      *                  {@code Byte}.
+     *
+     * @deprecated
+     * It is rarely appropriate to use this constructor. The static factory
+     * {@link #valueOf(byte)} is generally a better choice, as it is
+     * likely to yield significantly better space and time performance.
      */
+    @Deprecated(since="9")
     public Byte(byte value) {
         this.value = value;
     }
@@ -311,10 +317,16 @@
      *
      * @param s         the {@code String} to be converted to a
      *                  {@code Byte}
-     * @throws           NumberFormatException If the {@code String}
+     * @throws          NumberFormatException if the {@code String}
      *                  does not contain a parsable {@code byte}.
-     * @see        java.lang.Byte#parseByte(java.lang.String, int)
+     *
+     * @deprecated
+     * It is rarely appropriate to use this constructor.
+     * Use {@link #parseByte(String)} to convert a string to a
+     * {@code byte} primitive, or use {@link #valueOf(String)}
+     * to convert a string to a {@code Byte} object.
      */
+    @Deprecated(since="9")
     public Byte(String s) throws NumberFormatException {
         this.value = parseByte(s, 10);
     }
--- a/jdk/src/java.base/share/classes/java/lang/Character.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/Character.java	Wed Jul 05 21:37:42 2017 +0200
@@ -1256,14 +1256,14 @@
             new UnicodeBlock("SPECIALS");
 
         /**
-         * @deprecated As of J2SE 5, use {@link #HIGH_SURROGATES},
-         *             {@link #HIGH_PRIVATE_USE_SURROGATES}, and
-         *             {@link #LOW_SURROGATES}. These new constants match
-         *             the block definitions of the Unicode Standard.
-         *             The {@link #of(char)} and {@link #of(int)} methods
-         *             return the new constants, not SURROGATES_AREA.
-         */
-        @Deprecated
+         * @deprecated
+         * Instead of {@code SURROGATES_AREA}, use {@link #HIGH_SURROGATES},
+         * {@link #HIGH_PRIVATE_USE_SURROGATES}, and {@link #LOW_SURROGATES}.
+         * These constants match the block definitions of the Unicode Standard.
+         * The {@link #of(char)} and {@link #of(int)} methods return the
+         * standard constants.
+         */
+        @Deprecated(since="1.5")
         public static final UnicodeBlock SURROGATES_AREA =
             new UnicodeBlock("SURROGATES_AREA");
 
@@ -7451,7 +7451,13 @@
      *
      * @param  value   the value to be represented by the
      *                  {@code Character} object.
-     */
+     *
+     * @deprecated
+     * It is rarely appropriate to use this constructor. The static factory
+     * {@link #valueOf(char)} is generally a better choice, as it is
+     * likely to yield significantly better space and time performance.
+     */
+    @Deprecated(since="9")
     public Character(char value) {
         this.value = value;
     }
@@ -8799,7 +8805,7 @@
      * @since   1.0.2
      * @deprecated Replaced by isJavaIdentifierStart(char).
      */
-    @Deprecated
+    @Deprecated(since="1.1")
     public static boolean isJavaLetter(char ch) {
         return isJavaIdentifierStart(ch);
     }
@@ -8835,7 +8841,7 @@
      * @since   1.0.2
      * @deprecated Replaced by isJavaIdentifierPart(char).
      */
-    @Deprecated
+    @Deprecated(since="1.1")
     public static boolean isJavaLetterOrDigit(char ch) {
         return isJavaIdentifierPart(ch);
     }
@@ -9580,7 +9586,7 @@
      * @see        Character#isWhitespace(char)
      * @deprecated Replaced by isWhitespace(char).
      */
-    @Deprecated
+    @Deprecated(since="1.1")
     public static boolean isSpace(char ch) {
         return (ch <= 0x0020) &&
             (((((1L << 0x0009) |
--- a/jdk/src/java.base/share/classes/java/lang/ClassLoader.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/ClassLoader.java	Wed Jul 05 21:37:42 2017 +0200
@@ -727,7 +727,7 @@
      * @deprecated  Replaced by {@link #defineClass(String, byte[], int, int)
      * defineClass(String, byte[], int, int)}
      */
-    @Deprecated
+    @Deprecated(since="1.1")
     protected final Class<?> defineClass(byte[] b, int off, int len)
         throws ClassFormatError
     {
@@ -817,6 +817,9 @@
         if (!checkName(name))
             throw new NoClassDefFoundError("IllegalName: " + name);
 
+        // Note:  Checking logic in java.lang.invoke.MemberName.checkForTypeAlias
+        // relies on the fact that spoofing is impossible if a class has a name
+        // of the form "java.*"
         if ((name != null) && name.startsWith("java.")
                 && this != getBuiltinPlatformClassLoader()) {
             throw new SecurityException
@@ -2012,7 +2015,7 @@
      *
      * @since  1.2
      */
-    @Deprecated
+    @Deprecated(since="9")
     protected Package getPackage(String name) {
         Package pkg = getDefinedPackage(name);
         if (pkg == null) {
--- a/jdk/src/java.base/share/classes/java/lang/Double.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/Double.java	Wed Jul 05 21:37:42 2017 +0200
@@ -589,7 +589,13 @@
      * represents the primitive {@code double} argument.
      *
      * @param   value   the value to be represented by the {@code Double}.
+     *
+     * @deprecated
+     * It is rarely appropriate to use this constructor. The static factory
+     * {@link #valueOf(double)} is generally a better choice, as it is
+     * likely to yield significantly better space and time performance.
      */
+    @Deprecated(since="9")
     public Double(double value) {
         this.value = value;
     }
@@ -601,10 +607,16 @@
      * {@code double} value as if by the {@code valueOf} method.
      *
      * @param  s  a string to be converted to a {@code Double}.
-     * @throws    NumberFormatException  if the string does not contain a
+     * @throws    NumberFormatException if the string does not contain a
      *            parsable number.
-     * @see       java.lang.Double#valueOf(java.lang.String)
+     *
+     * @deprecated
+     * It is rarely appropriate to use this constructor.
+     * Use {@link #parseDouble(String)} to convert a string to a
+     * {@code double} primitive, or use {@link #valueOf(String)}
+     * to convert a string to a {@code Double} object.
      */
+    @Deprecated(since="9")
     public Double(String s) throws NumberFormatException {
         value = parseDouble(s);
     }
--- a/jdk/src/java.base/share/classes/java/lang/Float.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/Float.java	Wed Jul 05 21:37:42 2017 +0200
@@ -502,7 +502,13 @@
      * represents the primitive {@code float} argument.
      *
      * @param   value   the value to be represented by the {@code Float}.
+     *
+     * @deprecated
+     * It is rarely appropriate to use this constructor. The static factory
+     * {@link #valueOf(float)} is generally a better choice, as it is
+     * likely to yield significantly better space and time performance.
      */
+    @Deprecated(since="9")
     public Float(float value) {
         this.value = value;
     }
@@ -512,7 +518,13 @@
      * represents the argument converted to type {@code float}.
      *
      * @param   value   the value to be represented by the {@code Float}.
+     *
+     * @deprecated
+     * It is rarely appropriate to use this constructor. Instead, use the
+     * static factory method {@link #valueOf(float)} method as follows:
+     * {@code Float.valueOf((float)value)}.
      */
+    @Deprecated(since="9")
     public Float(double value) {
         this.value = (float)value;
     }
@@ -523,11 +535,17 @@
      * represented by the string. The string is converted to a
      * {@code float} value as if by the {@code valueOf} method.
      *
-     * @param      s   a string to be converted to a {@code Float}.
-     * @throws  NumberFormatException  if the string does not contain a
-     *               parsable number.
-     * @see        java.lang.Float#valueOf(java.lang.String)
+     * @param   s   a string to be converted to a {@code Float}.
+     * @throws      NumberFormatException if the string does not contain a
+     *              parsable number.
+     *
+     * @deprecated
+     * It is rarely appropriate to use this constructor.
+     * Use {@link #parseFloat(String)} to convert a string to a
+     * {@code float} primitive, or use {@link #valueOf(String)}
+     * to convert a string to a {@code Float} object.
      */
+    @Deprecated(since="9")
     public Float(String s) throws NumberFormatException {
         value = parseFloat(s);
     }
--- a/jdk/src/java.base/share/classes/java/lang/Integer.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/Integer.java	Wed Jul 05 21:37:42 2017 +0200
@@ -1106,7 +1106,13 @@
      *
      * @param   value   the value to be represented by the
      *                  {@code Integer} object.
+     *
+     * @deprecated
+     * It is rarely appropriate to use this constructor. The static factory
+     * {@link #valueOf(int)} is generally a better choice, as it is
+     * likely to yield significantly better space and time performance.
      */
+    @Deprecated(since="9")
     public Integer(int value) {
         this.value = value;
     }
@@ -1118,12 +1124,17 @@
      * {@code int} value in exactly the manner used by the
      * {@code parseInt} method for radix 10.
      *
-     * @param      s   the {@code String} to be converted to an
-     *                 {@code Integer}.
-     * @exception  NumberFormatException  if the {@code String} does not
-     *               contain a parsable integer.
-     * @see        java.lang.Integer#parseInt(java.lang.String, int)
+     * @param   s   the {@code String} to be converted to an {@code Integer}.
+     * @throws      NumberFormatException if the {@code String} does not
+     *              contain a parsable integer.
+     *
+     * @deprecated
+     * It is rarely appropriate to use this constructor.
+     * Use {@link #parseInt(String)} to convert a string to a
+     * {@code int} primitive, or use {@link #valueOf(String)}
+     * to convert a string to an {@code Integer} object.
      */
+    @Deprecated(since="9")
     public Integer(String s) throws NumberFormatException {
         this.value = parseInt(s, 10);
     }
--- a/jdk/src/java.base/share/classes/java/lang/Long.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/Long.java	Wed Jul 05 21:37:42 2017 +0200
@@ -1340,7 +1340,13 @@
      *
      * @param   value   the value to be represented by the
      *          {@code Long} object.
+     *
+     * @deprecated
+     * It is rarely appropriate to use this constructor. The static factory
+     * {@link #valueOf(long)} is generally a better choice, as it is
+     * likely to yield significantly better space and time performance.
      */
+    @Deprecated(since="9")
     public Long(long value) {
         this.value = value;
     }
@@ -1356,8 +1362,14 @@
      *             {@code Long}.
      * @throws     NumberFormatException  if the {@code String} does not
      *             contain a parsable {@code long}.
-     * @see        java.lang.Long#parseLong(java.lang.String, int)
+     *
+     * @deprecated
+     * It is rarely appropriate to use this constructor.
+     * Use {@link #parseLong(String)} to convert a string to a
+     * {@code long} primitive, or use {@link #valueOf(String)}
+     * to convert a string to a {@code Long} object.
      */
+    @Deprecated(since="9")
     public Long(String s) throws NumberFormatException {
         this.value = parseLong(s, 10);
     }
--- a/jdk/src/java.base/share/classes/java/lang/Package.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/Package.java	Wed Jul 05 21:37:42 2017 +0200
@@ -333,7 +333,7 @@
      * @see ClassLoader#getDefinedPackage
      */
     @CallerSensitive
-    @Deprecated
+    @Deprecated(since="9")
     @SuppressWarnings("deprecation")
     public static Package getPackage(String name) {
         ClassLoader l = ClassLoader.getClassLoader(Reflection.getCallerClass());
--- a/jdk/src/java.base/share/classes/java/lang/ProcessBuilder.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/ProcessBuilder.java	Wed Jul 05 21:37:42 2017 +0200
@@ -30,13 +30,12 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
-import java.nio.channels.Pipe;
 import java.util.Arrays;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
+import sun.security.action.GetPropertyAction;
+
 /**
  * This class is used to create operating system processes.
  *
@@ -468,11 +467,9 @@
      * @since 1.7
      */
     public abstract static class Redirect {
-        private static final File NULL_FILE = AccessController.doPrivileged(
-                (PrivilegedAction<File>) () -> {
-                    return new File((System.getProperty("os.name")
-                            .startsWith("Windows") ? "NUL" : "/dev/null"));
-                }
+        private static final File NULL_FILE = new File(
+                (GetPropertyAction.getProperty("os.name")
+                        .startsWith("Windows") ? "NUL" : "/dev/null")
         );
 
         /**
--- a/jdk/src/java.base/share/classes/java/lang/Runtime.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/Runtime.java	Wed Jul 05 21:37:42 2017 +0200
@@ -289,6 +289,7 @@
      *      finalizers being called on live objects while other threads are
      *      concurrently manipulating those objects, resulting in erratic
      *      behavior or deadlock.
+     *      This method is subject to removal in a future version of Java SE.
      *
      * @throws  SecurityException
      *        if a security manager exists and its {@code checkExit}
@@ -299,7 +300,7 @@
      * @see     java.lang.SecurityManager#checkExit(int)
      * @since   1.1
      */
-    @Deprecated
+    @Deprecated(since="1.2", forRemoval=true)
     public static void runFinalizersOnExit(boolean value) {
         SecurityManager security = System.getSecurityManager();
         if (security != null) {
@@ -717,41 +718,27 @@
     }
 
     /**
-     * Enables/Disables tracing of instructions.
-     * If the {@code boolean} argument is {@code true}, this
-     * method suggests that the Java virtual machine emit debugging
-     * information for each instruction in the virtual machine as it
-     * is executed. The format of this information, and the file or other
-     * output stream to which it is emitted, depends on the host environment.
-     * The virtual machine may ignore this request if it does not support
-     * this feature. The destination of the trace output is system
-     * dependent.
-     * <p>
-     * If the {@code boolean} argument is {@code false}, this
-     * method causes the virtual machine to stop performing the
-     * detailed instruction trace it is performing.
+     * Not implemented, does nothing.
      *
-     * @param   on   {@code true} to enable instruction tracing;
-     *               {@code false} to disable this feature.
+     * @deprecated
+     * This method was intended to control instruction tracing.
+     * It has been superseded by JVM-specific tracing mechanisms.
+     *
+     * @param on ignored
      */
+    @Deprecated(since="9", forRemoval=true)
     public void traceInstructions(boolean on) { }
 
     /**
-     * Enables/Disables tracing of method calls.
-     * If the {@code boolean} argument is {@code true}, this
-     * method suggests that the Java virtual machine emit debugging
-     * information for each method in the virtual machine as it is
-     * called. The format of this information, and the file or other output
-     * stream to which it is emitted, depends on the host environment. The
-     * virtual machine may ignore this request if it does not support
-     * this feature.
-     * <p>
-     * Calling this method with argument false suggests that the
-     * virtual machine cease emitting per-call debugging information.
+     * Not implemented, does nothing.
      *
-     * @param   on   {@code true} to enable instruction tracing;
-     *               {@code false} to disable this feature.
+     * @deprecated
+     * This method was intended to control method call tracing.
+     * It has been superseded by JVM-specific tracing mechanisms.
+     *
+     * @param on ignored
      */
+    @Deprecated(since="9", forRemoval=true)
     public void traceMethodCalls(boolean on) { }
 
     /**
@@ -894,8 +881,9 @@
      * stream in the local encoding into a character stream in Unicode is via
      * the {@code InputStreamReader} and {@code BufferedReader}
      * classes.
+     * This method is subject to removal in a future version of Java SE.
      */
-    @Deprecated
+    @Deprecated(since="1.1", forRemoval=true)
     public InputStream getLocalizedInputStream(InputStream in) {
         return in;
     }
@@ -915,6 +903,7 @@
      * Unicode character stream into a byte stream in the local encoding is via
      * the {@code OutputStreamWriter}, {@code BufferedWriter}, and
      * {@code PrintWriter} classes.
+     * This method is subject to removal in a future version of Java SE.
      *
      * @param      out OutputStream to localize
      * @return     a localized output stream
@@ -923,7 +912,7 @@
      * @see        java.io.OutputStreamWriter#OutputStreamWriter(java.io.OutputStream)
      * @see        java.io.PrintWriter#PrintWriter(java.io.OutputStream)
      */
-    @Deprecated
+    @Deprecated(since="1.1", forRemoval=true)
     public OutputStream getLocalizedOutputStream(OutputStream out) {
         return out;
     }
--- a/jdk/src/java.base/share/classes/java/lang/SecurityManager.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/SecurityManager.java	Wed Jul 05 21:37:42 2017 +0200
@@ -229,7 +229,7 @@
      *  It is recommended that the <code>checkPermission</code>
      *  call be used instead.
      */
-    @Deprecated
+    @Deprecated(since="1.2")
     protected boolean inCheck;
 
     /*
@@ -262,7 +262,7 @@
      *  It is recommended that the <code>checkPermission</code>
      *  call be used instead.
      */
-    @Deprecated
+    @Deprecated(since="1.2")
     public boolean getInCheck() {
         return inCheck;
     }
@@ -345,7 +345,7 @@
      * @see  java.lang.ClassLoader#getSystemClassLoader() getSystemClassLoader
      * @see  #checkPermission(java.security.Permission) checkPermission
      */
-    @Deprecated
+    @Deprecated(since="1.2")
     protected ClassLoader currentClassLoader() {
         ClassLoader cl = currentClassLoader0();
         if ((cl != null) && hasAllPermission())
@@ -391,7 +391,7 @@
      * @see  java.lang.ClassLoader#getSystemClassLoader() getSystemClassLoader
      * @see  #checkPermission(java.security.Permission) checkPermission
      */
-    @Deprecated
+    @Deprecated(since="1.2")
     protected Class<?> currentLoadedClass() {
         Class<?> c = currentLoadedClass0();
         if ((c != null) && hasAllPermission())
@@ -411,7 +411,7 @@
      *  call be used instead.
      *
      */
-    @Deprecated
+    @Deprecated(since="1.2")
     protected native int classDepth(String name);
 
     /**
@@ -449,7 +449,7 @@
      * @see   java.lang.ClassLoader#getSystemClassLoader() getSystemClassLoader
      * @see   #checkPermission(java.security.Permission) checkPermission
      */
-    @Deprecated
+    @Deprecated(since="1.2")
     protected int classLoaderDepth() {
         int depth = classLoaderDepth0();
         if (depth != -1) {
@@ -474,7 +474,7 @@
      *  It is recommended that the <code>checkPermission</code>
      *  call be used instead.
      */
-    @Deprecated
+    @Deprecated(since="1.2")
     protected boolean inClass(String name) {
         return classDepth(name) >= 0;
     }
@@ -491,7 +491,7 @@
      *  call be used instead.
      * @see        #currentClassLoader() currentClassLoader
      */
-    @Deprecated
+    @Deprecated(since="1.2")
     protected boolean inClassLoader() {
         return currentClassLoader() != null;
     }
@@ -1217,7 +1217,7 @@
      * @deprecated Use #checkPermission(java.security.Permission) instead
      * @see        #checkPermission(java.security.Permission) checkPermission
      */
-    @Deprecated
+    @Deprecated(since="1.4")
     public void checkMulticast(InetAddress maddr, byte ttl) {
         String host = maddr.getHostAddress();
         if (!host.startsWith("[") && host.indexOf(':') != -1) {
@@ -1297,9 +1297,10 @@
      *             was trusted to bring up a top-level window. The method has been
      *             obsoleted and code should instead use {@link #checkPermission}
      *             to check {@code AWTPermission("showWindowWithoutWarningBanner")}.
+     *             This method is subject to removal in a future version of Java SE.
      * @see        #checkPermission(java.security.Permission) checkPermission
      */
-    @Deprecated
+    @Deprecated(since="1.8", forRemoval=true)
     public boolean checkTopLevelWindow(Object window) {
         if (window == null) {
             throw new NullPointerException("window can't be null");
@@ -1340,9 +1341,10 @@
      *             thread could access the system clipboard. The method has been
      *             obsoleted and code should instead use {@link #checkPermission}
      *             to check {@code AWTPermission("accessClipboard")}.
+     *             This method is subject to removal in a future version of Java SE.
      * @see        #checkPermission(java.security.Permission) checkPermission
      */
-    @Deprecated
+    @Deprecated(since="1.8", forRemoval=true)
     public void checkSystemClipboardAccess() {
         checkPermission(SecurityConstants.ALL_PERMISSION);
     }
@@ -1358,9 +1360,10 @@
      *             thread could access the AWT event queue. The method has been
      *             obsoleted and code should instead use {@link #checkPermission}
      *             to check {@code AWTPermission("accessEventQueue")}.
+     *             This method is subject to removal in a future version of Java SE.
      * @see        #checkPermission(java.security.Permission) checkPermission
      */
-    @Deprecated
+    @Deprecated(since="1.8", forRemoval=true)
     public void checkAwtEventQueueAccess() {
         checkPermission(SecurityConstants.ALL_PERMISSION);
     }
@@ -1626,12 +1629,13 @@
      *             Users of this method should instead invoke {@link #checkPermission}
      *             directly.  This method will be changed in a future release
      *             to check the permission {@code java.security.AllPermission}.
+     *             This method is subject to removal in a future version of Java SE.
      *
      * @see java.lang.reflect.Member
      * @since 1.1
      * @see        #checkPermission(java.security.Permission) checkPermission
      */
-    @Deprecated
+    @Deprecated(since="1.8", forRemoval=true)
     @CallerSensitive
     public void checkMemberAccess(Class<?> clazz, int which) {
         if (clazz == null) {
--- a/jdk/src/java.base/share/classes/java/lang/Short.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/Short.java	Wed Jul 05 21:37:42 2017 +0200
@@ -302,7 +302,13 @@
      *
      * @param value     the value to be represented by the
      *                  {@code Short}.
+     *
+     * @deprecated
+     * It is rarely appropriate to use this constructor. The static factory
+     * {@link #valueOf(short)} is generally a better choice, as it is
+     * likely to yield significantly better space and time performance.
      */
+    @Deprecated(since="9")
     public Short(short value) {
         this.value = value;
     }
@@ -318,8 +324,14 @@
      *          {@code Short}
      * @throws  NumberFormatException If the {@code String}
      *          does not contain a parsable {@code short}.
-     * @see     java.lang.Short#parseShort(java.lang.String, int)
+     *
+     * @deprecated
+     * It is rarely appropriate to use this constructor.
+     * Use {@link #parseShort(String)} to convert a string to a
+     * {@code short} primitive, or use {@link #valueOf(String)}
+     * to convert a string to a {@code Short} object.
      */
+    @Deprecated(since="9")
     public Short(String s) throws NumberFormatException {
         this.value = parseShort(s, 10);
     }
--- a/jdk/src/java.base/share/classes/java/lang/StackFrameInfo.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/StackFrameInfo.java	Wed Jul 05 21:37:42 2017 +0200
@@ -37,24 +37,14 @@
     private final static JavaLangInvokeAccess jlInvokeAccess =
         SharedSecrets.getJavaLangInvokeAccess();
 
-    // -XX:+MemberNameInStackFrame will initialize MemberName and all other fields;
-    // otherwise, VM will set the hidden fields (injected by the VM).
-    // -XX:+MemberNameInStackFrame is temporary to enable performance measurement
-    //
-    // Footprint improvement: MemberName::clazz and MemberName::name
-    // can replace StackFrameInfo::declaringClass and StackFrameInfo::methodName
-    // Currently VM sets StackFrameInfo::methodName instead of expanding MemberName::name
+    // Footprint improvement: MemberName::clazz can replace
+    // StackFrameInfo::declaringClass.
 
     final StackWalker walker;
     final Class<?> declaringClass;
     final Object memberName;
-    final int bci;
-
-    // methodName, fileName, and lineNumber will be lazily set by the VM
-    // when first requested.
-    private String methodName;
-    private String fileName = null;     // default for unavailable filename
-    private int    lineNumber = -1;     // default for unavailable lineNumber
+    final short bci;
+    private volatile StackTraceElement ste;
 
     /*
      * Create StackFrameInfo for StackFrameTraverser and LiveStackFrameTraverser
@@ -78,77 +68,53 @@
         return declaringClass;
     }
 
-    // Call the VM to set methodName, lineNumber, and fileName
-    private synchronized void ensureMethodInfoInitialized() {
-        if (methodName == null) {
-            setMethodInfo();
-        }
-    }
-
     @Override
     public String getMethodName() {
-        ensureMethodInfoInitialized();
-        return methodName;
+        return jlInvokeAccess.getName(memberName);
     }
 
     @Override
-    public Optional<String> getFileName() {
-        ensureMethodInfoInitialized();
-        return fileName != null ? Optional.of(fileName) : Optional.empty();
+    public final Optional<String> getFileName() {
+        StackTraceElement ste = toStackTraceElement();
+        return ste.getFileName() != null ? Optional.of(ste.getFileName()) : Optional.empty();
     }
 
     @Override
-    public OptionalInt getLineNumber() {
-        ensureMethodInfoInitialized();
-        return lineNumber > 0 ? OptionalInt.of(lineNumber) : OptionalInt.empty();
+    public final OptionalInt getLineNumber() {
+        StackTraceElement ste = toStackTraceElement();
+        return ste.getLineNumber() > 0 ? OptionalInt.of(ste.getLineNumber()) : OptionalInt.empty();
     }
 
     @Override
-    public boolean isNativeMethod() {
-        ensureMethodInfoInitialized();
-        return lineNumber == -2;
+    public final boolean isNativeMethod() {
+        StackTraceElement ste = toStackTraceElement();
+        return ste.isNativeMethod();
     }
 
     @Override
     public String toString() {
-        ensureMethodInfoInitialized();
-        // similar format as StackTraceElement::toString
-        if (isNativeMethod()) {
-            return getClassName() + "." + getMethodName() + "(Native Method)";
-        } else {
-            // avoid allocating Optional objects
-            return getClassName() + "." + getMethodName() +
-                "(" + (fileName != null ? fileName : "Unknown Source") +
-                      (lineNumber > 0 ? ":" + lineNumber : " bci:" + bci) + ")";
-        }
+        StackTraceElement ste = toStackTraceElement();
+        return ste.toString();
     }
 
     /**
-     * Lazily initialize method name, file name, line number
+     * Fill in the fields of the given StackTraceElement
      */
-    private native void setMethodInfo();
-
-    /**
-     * Fill in source file name and line number of the given StackFrame array.
-     */
-    static native void fillInStackFrames(int startIndex,
-                                         Object[] stackframes,
-                                         int fromIndex, int toIndex);
+    private native void toStackTraceElement0(StackTraceElement ste);
 
     @Override
     public StackTraceElement toStackTraceElement() {
-        ensureMethodInfoInitialized();
-
-        Module module = declaringClass.getModule();
-        String moduleName = module.isNamed() ? module.getName() : null;
-        String moduleVersion = null;
-        if (module.isNamed() && module.getDescriptor().version().isPresent()) {
-            moduleVersion = module.getDescriptor().version().get().toString();
+        StackTraceElement s = ste;
+        if (s == null) {
+            synchronized (this) {
+                s = ste;
+                if (s == null) {
+                    s = new StackTraceElement();
+                    toStackTraceElement0(s);
+                    ste = s;
+                }
+            }
         }
-        return new StackTraceElement(moduleName, moduleVersion,
-                                     getClassName(), getMethodName(),
-                                     fileName,
-                                     lineNumber);
+        return s;
     }
-
 }
--- a/jdk/src/java.base/share/classes/java/lang/StackStreamFactory.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/StackStreamFactory.java	Wed Jul 05 21:37:42 2017 +0200
@@ -24,29 +24,22 @@
  */
 package java.lang;
 
-import jdk.internal.misc.VM;
 import jdk.internal.reflect.MethodAccessor;
-
-import java.io.PrintStream;
 import java.lang.StackWalker.Option;
 import java.lang.StackWalker.StackFrame;
 
 import java.lang.annotation.Native;
 import java.lang.reflect.Method;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.Arrays;
-import java.util.EnumSet;
 import java.util.HashSet;
 import java.util.NoSuchElementException;
 import java.util.Objects;
-import java.util.Optional;
 import java.util.Set;
 import java.util.Spliterator;
 import java.util.function.Consumer;
 import java.util.function.Function;
 import java.util.stream.Stream;
 import java.util.stream.StreamSupport;
+import sun.security.action.GetPropertyAction;
 
 import static java.lang.StackStreamFactory.WalkerState.*;
 
@@ -61,8 +54,7 @@
  * to avoid overhead of Stream/Lambda
  * 1. Support traversing Stream<StackFrame>
  * 2. StackWalker::getCallerClass
- * 3. Throwable::init and Throwable::getStackTrace
- * 4. AccessControlContext getting ProtectionDomain
+ * 3. AccessControlContext getting ProtectionDomain
  */
 final class StackStreamFactory {
     private StackStreamFactory() {}
@@ -79,25 +71,22 @@
     // 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 FILTER_FILL_IN_STACKTRACE = 0x10;
     @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;
-
     /*
      * For Throwable to use StackWalker, set useNewThrowable to true.
      * Performance work and extensive testing is needed to replace the
      * VM built-in backtrace filled in Throwable with the StackWalker.
      */
-    final static boolean useNewThrowable = getProperty("stackwalk.newThrowable", false);
     final static boolean isDebug = getProperty("stackwalk.debug", false);
 
     static <T> StackFrameTraverser<T>
         makeStackTraverser(StackWalker walker, Function<? super Stream<StackFrame>, ? extends T> function)
     {
         if (walker.hasLocalsOperandsOption())
-            return new LiveStackInfoTraverser<T>(walker, function);
+            return new LiveStackInfoTraverser<>(walker, function);
         else
-            return new StackFrameTraverser<T>(walker, function);
+            return new StackFrameTraverser<>(walker, function);
     }
 
     /**
@@ -107,40 +96,31 @@
         return new CallerClassFinder(walker);
     }
 
-    static boolean useStackTrace(Throwable t) {
-        if (t instanceof VirtualMachineError)
-            return false;
-
-        return VM.isBooted() && StackStreamFactory.useNewThrowable;
-    }
-
-    /*
-     * This should only be used by Throwable::<init>.
-     */
-    static StackTrace makeStackTrace(Throwable ex) {
-        return StackTrace.dump(ex);
-    }
-
-    /*
-     * This creates StackTrace for Thread::dumpThread to use.
-     */
-    static StackTrace makeStackTrace() {
-        return StackTrace.dump();
-    }
-
     enum WalkerState {
         NEW,     // the stream is new and stack walking has not started
         OPEN,    // the stream is open when it is being traversed.
         CLOSED;  // the stream is closed when the stack walking is done
     }
 
-    static abstract class AbstractStackWalker<T> {
+    /**
+     * Subclass of AbstractStackWalker implements a specific stack walking logic.
+     * It needs to set up the frame buffer and stack walking mode.
+     *
+     * It initiates the VM stack walking via the callStackWalk method that serves
+     * as the anchored frame and VM will call up to AbstractStackWalker::doStackWalk.
+     *
+     * @param <R> the type of the result returned from stack walking
+     * @param <T> the type of the data gathered for each frame.
+     *            For example, StackFrameInfo for StackWalker::walk or
+     *            Class<?> for StackWalker::getCallerClass
+     */
+    static abstract class AbstractStackWalker<R, T> {
         protected final StackWalker walker;
         protected final Thread thread;
         protected final int maxDepth;
         protected final long mode;
-        protected int depth;                 // traversed stack depth
-        protected FrameBuffer frameBuffer;   // buffer for VM to fill in
+        protected int depth;    // traversed stack depth
+        protected FrameBuffer<? extends T> frameBuffer;
         protected long anchor;
 
         // buffers to fill in stack frame information
@@ -158,16 +138,13 @@
         private int toStackWalkMode(StackWalker walker, int mode) {
             int newMode = mode;
             if (walker.hasOption(Option.SHOW_HIDDEN_FRAMES) &&
-                    !fillCallerClassOnly(newMode) /* don't show hidden frames for getCallerClass */)
+                    (mode & FILL_CLASS_REFS_ONLY) != FILL_CLASS_REFS_ONLY)
                 newMode |= SHOW_HIDDEN_FRAMES;
             if (walker.hasLocalsOperandsOption())
                 newMode |= FILL_LIVE_STACK_FRAMES;
             return newMode;
         }
 
-        private boolean fillCallerClassOnly(int mode) {
-            return (mode|FILL_CLASS_REFS_ONLY) != FILL_CLASS_REFS_ONLY;
-        }
         /**
          * A callback method to consume the stack frames.  This method is invoked
          * once stack walking begins (i.e. it is only invoked when walkFrames is called).
@@ -180,7 +157,7 @@
          *
          * @return the number of consumed frames
          */
-         protected abstract T consumeFrames();
+         protected abstract R consumeFrames();
 
         /**
          * Initialize FrameBuffer.  Subclass should implement this method to
@@ -253,7 +230,7 @@
          * Walks stack frames until {@link #consumeFrames} is done consuming
          * the frames it is interested in.
          */
-        final T walk() {
+        final R walk() {
             checkState(NEW);
             try {
                 // VM will need to stablize the stack before walking.  It will invoke
@@ -319,7 +296,7 @@
             }
 
             this.anchor = anchor;  // set anchor for this bulk stack frame traversal
-            frameBuffer.setBatch(bufStartIndex, bufEndIndex);
+            frameBuffer.setBatch(depth, bufStartIndex, bufEndIndex);
 
             // traverse all frames and perform the action on the stack frames, if specified
             return consumeFrames();
@@ -382,15 +359,14 @@
          * If all fetched stack frames are traversed, AbstractStackWalker::fetchStackFrames will
          * fetch the next batch of stack frames to continue.
          */
-        private T beginStackWalk() {
+        private R beginStackWalk() {
             // initialize buffers for VM to fill the stack frame info
             initFrameBuffer();
 
             return callStackWalk(mode, 0,
                                  frameBuffer.curBatchFrameCount(),
                                  frameBuffer.startIndex(),
-                                 frameBuffer.classes,
-                                 frameBuffer.stackFrames);
+                                 frameBuffer.frames());
         }
 
         /*
@@ -405,8 +381,7 @@
 
             int endIndex = fetchStackFrames(mode, anchor, batchSize,
                                             startIndex,
-                                            frameBuffer.classes,
-                                            frameBuffer.stackFrames);
+                                            frameBuffer.frames());
             if (isDebug) {
                 System.out.format("  more stack walk requesting %d got %d to %d frames%n",
                                   batchSize, frameBuffer.startIndex(), endIndex);
@@ -415,27 +390,26 @@
             if (numFrames == 0) {
                 frameBuffer.freeze(); // done stack walking
             } else {
-                frameBuffer.setBatch(startIndex, endIndex);
+                frameBuffer.setBatch(depth, startIndex, endIndex);
             }
             return numFrames;
         }
 
         /**
          * Begins stack walking.  This method anchors this frame and invokes
-         * AbstractStackWalker::doStackWalk after fetching the firt batch of stack frames.
+         * AbstractStackWalker::doStackWalk after fetching the first batch of stack frames.
          *
          * @param mode        mode of stack walking
          * @param skipframes  number of frames to be skipped before filling the frame buffer.
          * @param batchSize   the batch size, max. number of elements to be filled in the frame buffers.
          * @param startIndex  start index of the frame buffers to be filled.
-         * @param classes     Classes buffer of the stack frames
-         * @param frames      StackFrame buffer, or null
+         * @param frames      Either a Class<?> array, if mode is {@link #FILL_CLASS_REFS_ONLY}
+         *                    or a {@link StackFrameInfo} (or derivative) array otherwise.
          * @return            Result of AbstractStackWalker::doStackWalk
          */
-        private native T callStackWalk(long mode, int skipframes,
+        private native R callStackWalk(long mode, int skipframes,
                                        int batchSize, int startIndex,
-                                       Class<?>[] classes,
-                                       StackFrame[] frames);
+                                       T[] frames);
 
         /**
          * Fetch the next batch of stack frames.
@@ -444,185 +418,14 @@
          * @param anchor
          * @param batchSize   the batch size, max. number of elements to be filled in the frame buffers.
          * @param startIndex  start index of the frame buffers to be filled.
-         * @param classes     Classes buffer of the stack frames
-         * @param frames      StackFrame buffer, or null
+         * @param frames      Either a Class<?> array, if mode is {@link #FILL_CLASS_REFS_ONLY}
+         *                    or a {@link StackFrameInfo} (or derivative) array otherwise.
          *
          * @return the end index to the frame buffers
          */
         private native int fetchStackFrames(long mode, long anchor,
                                             int batchSize, int startIndex,
-                                            Class<?>[] classes,
-                                            StackFrame[] frames);
-
-
-        /*
-         * Frame buffer
-         *
-         * Each specialized AbstractStackWalker subclass may subclass the FrameBuffer.
-         */
-        class FrameBuffer {
-            static final int START_POS = 2;     // 0th and 1st elements are reserved
-
-            // buffers for VM to fill stack frame info
-            int currentBatchSize;    // current batch size
-            Class<?>[] classes;      // caller class for fast path
-
-            StackFrame[] stackFrames;
-
-            int origin;         // index to the current traversed stack frame
-            int fence;          // index to the last frame in the current batch
-
-            FrameBuffer(int initialBatchSize) {
-                if (initialBatchSize < MIN_BATCH_SIZE) {
-                    throw new IllegalArgumentException(initialBatchSize + " < minimum batch size: " + MIN_BATCH_SIZE);
-                }
-                this.origin = START_POS;
-                this.fence = 0;
-                this.currentBatchSize = initialBatchSize;
-                this.classes = new Class<?>[currentBatchSize];
-            }
-
-            int curBatchFrameCount() {
-                return currentBatchSize-START_POS;
-            }
-
-            /*
-             * Tests if this frame buffer is empty.  All frames are fetched.
-             */
-            final boolean isEmpty() {
-                return origin >= fence || (origin == START_POS && fence == 0);
-            }
-
-            /*
-             * Freezes this frame buffer.  The stack stream source is done fetching.
-             */
-            final void freeze() {
-                origin = 0;
-                fence = 0;
-            }
-
-            /*
-             * Tests if this frame buffer is active.  It is inactive when
-             * it is done for traversal.  All stack frames have been traversed.
-             */
-            final boolean isActive() {
-                return origin > 0 && (fence == 0 || origin < fence || fence == currentBatchSize);
-            }
-
-            /**
-             * Gets the class at the current frame and move to the next frame.
-             */
-            final Class<?> next() {
-                if (isEmpty()) {
-                    throw new NoSuchElementException("origin=" + origin + " fence=" + fence);
-                }
-                Class<?> c = classes[origin++];
-                if (isDebug) {
-                    int index = origin-1;
-                    System.out.format("  next frame at %d: %s (origin %d fence %d)%n", index,
-                                      Objects.toString(c), index, fence);
-                }
-                return c;
-            }
-
-            /**
-             * Gets the class at the current frame.
-             */
-            final Class<?> get() {
-                if (isEmpty()) {
-                    throw new NoSuchElementException("origin=" + origin + " fence=" + fence);
-                }
-                return classes[origin];
-            }
-
-            /*
-             * Returns the index of the current frame.
-             */
-            final int getIndex() {
-                return origin;
-            }
-
-            /*
-             * Set the start and end index of a new batch of stack frames that have
-             * been filled in this frame buffer.
-             */
-            final void setBatch(int startIndex, int endIndex) {
-                if (startIndex <= 0 || endIndex <= 0)
-                    throw new IllegalArgumentException("startIndex=" + startIndex + " endIndex=" + endIndex);
-
-                this.origin = startIndex;
-                this.fence = endIndex;
-                if (depth == 0 && fence > 0) {
-                    // filter the frames due to the stack stream implementation
-                    for (int i = START_POS; i < fence; i++) {
-                        Class<?> c = classes[i];
-                        if (isDebug) System.err.format("  frame %d: %s%n", i, c);
-                        if (filterStackWalkImpl(c)) {
-                            origin++;
-                        } else {
-                            break;
-                        }
-                    }
-                }
-            }
-
-            /*
-             * Checks if the origin is the expected start index.
-             */
-            final void check(int skipFrames) {
-                int index = skipFrames + START_POS;
-                if (origin != index) {
-                    // stack walk must continue with the previous frame depth
-                    throw new IllegalStateException("origin " + origin + " != " + index);
-                }
-            }
-
-            // ------ subclass may override the following methods -------
-            /**
-             * Resizes the buffers for VM to fill in the next batch of stack frames.
-             * The next batch will start at the given startIndex with the maximum number
-             * of elements.
-             *
-             * <p> Subclass may override this method to manage the allocated buffers.
-             *
-             * @param startIndex the start index for the first frame of the next batch to fill in.
-             * @param elements the number of elements for the next batch to fill in.
-             *
-             */
-            void resize(int startIndex, int elements) {
-                if (!isActive())
-                    throw new IllegalStateException("inactive frame buffer can't be resized");
-
-                int size = startIndex+elements;
-                if (classes.length < size) {
-                    // copy the elements in classes array to the newly allocated one.
-                    // classes[0] is a Thread object
-                    Class<?>[] prev = classes;
-                    classes = new Class<?>[size];
-                    System.arraycopy(prev, 0, classes, 0, START_POS);
-                }
-                currentBatchSize = size;
-            }
-
-            /*
-             * Returns the start index for this frame buffer is refilled.
-             *
-             * This implementation reuses the allocated buffer for the next batch
-             * of stack frames.  For subclass to retain the fetched stack frames,
-             * it should override this method to return the index at which the frame
-             * should be filled in for the next batch.
-             */
-            int startIndex() {
-                return START_POS;
-            }
-
-            /**
-             * Returns next StackFrame object in the current batch of stack frames
-             */
-            StackFrame nextStackFrame() {
-                throw new InternalError("should not reach here");
-            }
-        }
+                                            T[] frames);
     }
 
     /*
@@ -630,46 +433,66 @@
      *
      * This class implements Spliterator::forEachRemaining and Spliterator::tryAdvance.
      */
-    static class StackFrameTraverser<T> extends AbstractStackWalker<T>
+    static class StackFrameTraverser<T> extends AbstractStackWalker<T, StackFrameInfo>
             implements Spliterator<StackFrame>
     {
         static {
             stackWalkImplClasses.add(StackFrameTraverser.class);
         }
         private static final int CHARACTERISTICS = Spliterator.ORDERED | Spliterator.IMMUTABLE;
-        class Buffer extends FrameBuffer {
-            Buffer(int initialBatchSize) {
+
+        final class StackFrameBuffer extends FrameBuffer<StackFrameInfo> {
+            private StackFrameInfo[] stackFrames;
+            StackFrameBuffer(int initialBatchSize) {
                 super(initialBatchSize);
 
-                this.stackFrames = new StackFrame[initialBatchSize];
+                this.stackFrames = new StackFrameInfo[initialBatchSize];
                 for (int i = START_POS; i < initialBatchSize; i++) {
                     stackFrames[i] = new StackFrameInfo(walker);
                 }
             }
 
             @Override
+            StackFrameInfo[] frames() {
+                return stackFrames;
+            }
+
+            @Override
             void resize(int startIndex, int elements) {
-                super.resize(startIndex, elements);
+                if (!isActive())
+                    throw new IllegalStateException("inactive frame buffer can't be resized");
+
+                assert startIndex == START_POS :
+                       "bad start index " + startIndex + " expected " + START_POS;
 
                 int size = startIndex+elements;
                 if (stackFrames.length < size) {
-                    stackFrames = new StackFrame[size];
+                    StackFrameInfo[] newFrames = new StackFrameInfo[size];
+                    // copy initial magic...
+                    System.arraycopy(stackFrames, 0, newFrames, 0, startIndex);
+                    stackFrames = newFrames;
                 }
-                for (int i = startIndex(); i < size; i++) {
+                for (int i = startIndex; i < size; i++) {
                     stackFrames[i] = new StackFrameInfo(walker);
                 }
+                currentBatchSize = size;
             }
 
             @Override
-            StackFrame nextStackFrame() {
+            StackFrameInfo nextStackFrame() {
                 if (isEmpty()) {
                     throw new NoSuchElementException("origin=" + origin + " fence=" + fence);
                 }
 
-                StackFrame frame = stackFrames[origin];
+                StackFrameInfo frame = stackFrames[origin];
                 origin++;
                 return frame;
             }
+
+            @Override
+            final Class<?> at(int index) {
+                return stackFrames[index].declaringClass;
+            }
         }
 
         final Function<? super Stream<StackFrame>, ? extends T> function;  // callback
@@ -694,7 +517,7 @@
                 return null;
             }
 
-            StackFrame frame = frameBuffer.nextStackFrame();
+            StackFrameInfo frame = frameBuffer.nextStackFrame();
             depth++;
             return frame;
         }
@@ -711,7 +534,7 @@
 
         @Override
         protected void initFrameBuffer() {
-            this.frameBuffer = new Buffer(getNextBatchSize());
+            this.frameBuffer = new StackFrameBuffer(getNextBatchSize());
         }
 
         @Override
@@ -782,7 +605,7 @@
      * CallerClassFinder is specialized to return Class<?> for each stack frame.
      * StackFrame is not requested.
      */
-    static class CallerClassFinder extends AbstractStackWalker<Integer> {
+    static final class CallerClassFinder extends AbstractStackWalker<Integer, Class<?>> {
         static {
             stackWalkImplClasses.add(CallerClassFinder.class);
         }
@@ -791,6 +614,54 @@
 
         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";
+        }
+
+        final class ClassBuffer extends FrameBuffer<Class<?>> {
+            Class<?>[] classes;      // caller class for fast path
+            ClassBuffer(int batchSize) {
+                super(batchSize);
+                classes = new Class<?>[batchSize];
+            }
+
+            @Override
+            Class<?>[] frames() { return classes;}
+
+            @Override
+            final Class<?> at(int index) { return classes[index];}
+
+
+            // ------ subclass may override the following methods -------
+            /**
+             * Resizes the buffers for VM to fill in the next batch of stack frames.
+             * The next batch will start at the given startIndex with the maximum number
+             * of elements.
+             *
+             * <p> Subclass may override this method to manage the allocated buffers.
+             *
+             * @param startIndex the start index for the first frame of the next batch to fill in.
+             * @param elements the number of elements for the next batch to fill in.
+             *
+             */
+            @Override
+            void resize(int startIndex, int elements) {
+                if (!isActive())
+                    throw new IllegalStateException("inactive frame buffer can't be resized");
+
+                assert startIndex == START_POS :
+                       "bad start index " + startIndex + " expected " + START_POS;
+
+                int size = startIndex+elements;
+                if (classes.length < size) {
+                    // copy the elements in classes array to the newly allocated one.
+                    // classes[0] is a Thread object
+                    Class<?>[] prev = classes;
+                    classes = new Class<?>[size];
+                    System.arraycopy(prev, 0, classes, 0, startIndex);
+                }
+                currentBatchSize = size;
+            }
         }
 
         Class<?> findCaller() {
@@ -811,15 +682,15 @@
                 if (isMethodHandleFrame(caller)) continue;
                 frames[n++] = caller;
             }
-
-            if (frames[1] == null)
+            if (frames[1] == null) {
                 throw new IllegalStateException("no caller frame");
+            }
             return n;
         }
 
         @Override
         protected void initFrameBuffer() {
-            this.frameBuffer = new FrameBuffer(getNextBatchSize());
+            this.frameBuffer = new ClassBuffer(getNextBatchSize());
         }
 
         @Override
@@ -833,215 +704,64 @@
         }
     }
 
-    /*
-     * StackTrace caches all frames in the buffer.  StackTraceElements are
-     * created lazily when Throwable::getStackTrace is called.
-     */
-    static class StackTrace extends AbstractStackWalker<Integer> {
-        static {
-            stackWalkImplClasses.add(StackTrace.class);
-        }
-
-        class GrowableBuffer extends FrameBuffer {
-            GrowableBuffer(int initialBatchSize) {
-                super(initialBatchSize);
-
-                this.stackFrames = new StackFrame[initialBatchSize];
-                for (int i = START_POS; i < initialBatchSize; i++) {
-                    stackFrames[i] = new StackFrameInfo(walker);
-                }
-            }
-
-            /*
-             * Returns the next index to fill
-             */
-            @Override
-            int startIndex() {
-                return origin;
-            }
-
-            /**
-             * Initialize the buffers for VM to fill in the stack frame information.
-             * The next batch will start at the given startIndex to
-             * the length of the buffer.
-             */
-            @Override
-            void resize(int startIndex, int elements) {
-                // Expand the frame buffer.
-                // Do not call super.resize that will reuse the filled elements
-                // in this frame buffer
-                int size = startIndex+elements;
-                if (classes.length < size) {
-                    // resize the frame buffer
-                    classes = Arrays.copyOf(classes, size);
-                    stackFrames = Arrays.copyOf(stackFrames, size);
-                }
-                for (int i = startIndex; i < size; i++) {
-                    stackFrames[i] = new StackFrameInfo(walker);
-                }
-                currentBatchSize = size;
-            }
-
-            StackTraceElement get(int index) {
-                return new StackTraceElement(classes[index].getName(), "unknown", null, -1);
-            }
-
-            /**
-             * Returns an array of StackTraceElement for all stack frames cached in
-             * this StackTrace object.
-             * <p>
-             * This method is intended for Throwable::getOurStackTrace use only.
-             */
-            StackTraceElement[] toStackTraceElements() {
-                int startIndex = START_POS;
-                for (int i = startIndex; i < classes.length; i++) {
-                    if (classes[i] != null && filterStackWalkImpl(classes[i])) {
-                        startIndex++;
-                    } else {
-                        break;
-                    }
-                }
-
-                // VM fills in the method name, filename, line number info
-                StackFrameInfo.fillInStackFrames(0, stackFrames, startIndex, startIndex + depth);
-
-                StackTraceElement[] stes = new StackTraceElement[depth];
-                for (int i = startIndex, j = 0; i < classes.length && j < depth; i++, j++) {
-                    if (isDebug) {
-                        System.err.println("StackFrame: " + i + " " + stackFrames[i]);
-                    }
-                    stes[j] = stackFrames[i].toStackTraceElement();
-                }
-                return stes;
-            }
-        }
-
-        private static final int MAX_STACK_FRAMES = 1024;
-        private static final StackWalker STACKTRACE_WALKER =
-            StackWalker.newInstanceNoCheck(EnumSet.of(Option.SHOW_REFLECT_FRAMES));
-
-        private StackTraceElement[] stes;
-        static StackTrace dump() {
-            return new StackTrace();
-        }
-
-        static StackTrace dump(Throwable ex) {
-            return new StackTrace(ex);
-        }
-
-        private StackTrace() {
-            this(STACKTRACE_WALKER, DEFAULT_MODE);
-        }
-
-        /*
-         * Throwable::fillInStackTrace and <init> of Throwable and subclasses
-         * are filtered in the VM.
-         */
-        private StackTrace(Throwable ex) {
-            this(STACKTRACE_WALKER, FILTER_FILL_IN_STACKTRACE);  // skip Throwable::init frames
-            if (isDebug) {
-                System.err.println("dump stack for " + ex.getClass().getName());
-            }
-        }
-
-        StackTrace(StackWalker walker, int mode) {
-            super(walker, mode, MAX_STACK_FRAMES);
-
-            // snapshot the stack trace
-            walk();
-        }
-
-        @Override
-        protected Integer consumeFrames() {
-            // traverse all frames and perform the action on the stack frames, if specified
-            int n = 0;
-            while (n < maxDepth && nextFrame() != null) {
-                n++;
-            }
-            return n;
-        }
-
-        @Override
-        protected void initFrameBuffer() {
-            this.frameBuffer = new GrowableBuffer(getNextBatchSize());
-        }
-
-        // TODO: implement better heuristic
-        @Override
-        protected int batchSize(int lastBatchFrameCount) {
-            // chunk size of VM backtrace is 32
-            return lastBatchFrameCount == 0 ? 32 : 32;
-        }
-
-        /**
-         * Returns an array of StackTraceElement for all stack frames cached in
-         * this StackTrace object.
-         * <p>
-         * This method is intended for Throwable::getOurStackTrace use only.
-         */
-        synchronized StackTraceElement[] getStackTraceElements() {
-            if (stes == null) {
-                stes = ((GrowableBuffer) frameBuffer).toStackTraceElements();
-                // release the frameBuffer memory
-                frameBuffer = null;
-            }
-            return stes;
-        }
-
-        /*
-         * Prints stack trace to the given PrintStream.
-         *
-         * Further implementation could skip creating StackTraceElement objects
-         * print directly to the PrintStream.
-         */
-        void printStackTrace(PrintStream s) {
-            StackTraceElement[] stes = getStackTraceElements();
-            synchronized (s) {
-                s.println("Stack trace");
-                for (StackTraceElement traceElement : stes)
-                    s.println("\tat " + traceElement);
-            }
-        }
-    }
-
-    static class LiveStackInfoTraverser<T> extends StackFrameTraverser<T> {
+    static final class LiveStackInfoTraverser<T> extends StackFrameTraverser<T> {
         static {
             stackWalkImplClasses.add(LiveStackInfoTraverser.class);
         }
         // VM will fill in all method info and live stack info directly in StackFrameInfo
-        class Buffer extends FrameBuffer {
-            Buffer(int initialBatchSize) {
+        final class LiveStackFrameBuffer extends FrameBuffer<LiveStackFrameInfo> {
+            private LiveStackFrameInfo[] stackFrames;
+            LiveStackFrameBuffer(int initialBatchSize) {
                 super(initialBatchSize);
-                this.stackFrames = new StackFrame[initialBatchSize];
+                this.stackFrames = new LiveStackFrameInfo[initialBatchSize];
                 for (int i = START_POS; i < initialBatchSize; i++) {
                     stackFrames[i] = new LiveStackFrameInfo(walker);
                 }
             }
 
             @Override
+            LiveStackFrameInfo[] frames() {
+                return stackFrames;
+            }
+
+            @Override
             void resize(int startIndex, int elements) {
-                super.resize(startIndex, elements);
+                if (!isActive()) {
+                    throw new IllegalStateException("inactive frame buffer can't be resized");
+                }
+                assert startIndex == START_POS :
+                       "bad start index " + startIndex + " expected " + START_POS;
+
                 int size = startIndex + elements;
-
                 if (stackFrames.length < size) {
-                    this.stackFrames = new StackFrame[size];
+                    LiveStackFrameInfo[] newFrames = new LiveStackFrameInfo[size];
+                    // copy initial magic...
+                    System.arraycopy(stackFrames, 0, newFrames, 0, startIndex);
+                    stackFrames = newFrames;
                 }
 
                 for (int i = startIndex(); i < size; i++) {
                     stackFrames[i] = new LiveStackFrameInfo(walker);
                 }
+
+                currentBatchSize = size;
             }
 
             @Override
-            StackFrame nextStackFrame() {
+            LiveStackFrameInfo nextStackFrame() {
                 if (isEmpty()) {
                     throw new NoSuchElementException("origin=" + origin + " fence=" + fence);
                 }
 
-                StackFrame frame = stackFrames[origin];
+                LiveStackFrameInfo frame = stackFrames[origin];
                 origin++;
                 return frame;
             }
+
+            @Override
+            final Class<?> at(int index) {
+                return stackFrames[index].declaringClass;
+            }
         }
 
         LiveStackInfoTraverser(StackWalker walker,
@@ -1051,7 +771,183 @@
 
         @Override
         protected void initFrameBuffer() {
-            this.frameBuffer = new Buffer(getNextBatchSize());
+            this.frameBuffer = new LiveStackFrameBuffer(getNextBatchSize());
+        }
+    }
+
+    /*
+     * Frame buffer
+     *
+     * Each specialized AbstractStackWalker subclass may subclass the FrameBuffer.
+     */
+    static abstract class FrameBuffer<F> {
+        static final int START_POS = 2;     // 0th and 1st elements are reserved
+
+        // buffers for VM to fill stack frame info
+        int currentBatchSize;    // current batch size
+        int origin;         // index to the current traversed stack frame
+        int fence;          // index to the last frame in the current batch
+
+        FrameBuffer(int initialBatchSize) {
+            if (initialBatchSize < MIN_BATCH_SIZE) {
+                throw new IllegalArgumentException(initialBatchSize +
+                        " < minimum batch size: " + MIN_BATCH_SIZE);
+            }
+            this.origin = START_POS;
+            this.fence = 0;
+            this.currentBatchSize = initialBatchSize;
+        }
+
+        /**
+         * Returns an array of frames that may be used to store frame objects
+         * when walking the stack.
+         *
+         * May be an array of {@code Class<?>} if the {@code AbstractStackWalker}
+         * mode is {@link #FILL_CLASS_REFS_ONLY}, or an array of
+         * {@link StackFrameInfo} (or derivative) array otherwise.
+         *
+         * @return An array of frames that may be used to store frame objects
+         * when walking the stack. Must not be null.
+         */
+        abstract F[] frames(); // must not return null
+
+        /**
+         * Resizes the buffers for VM to fill in the next batch of stack frames.
+         * The next batch will start at the given startIndex with the maximum number
+         * of elements.
+         *
+         * <p> Subclass may override this method to manage the allocated buffers.
+         *
+         * @param startIndex the start index for the first frame of the next batch to fill in.
+         * @param elements the number of elements for the next batch to fill in.
+         *
+         */
+        abstract void resize(int startIndex, int elements);
+
+        /**
+         * Return the class at the given position in the current batch.
+         * @param index the position of the frame.
+         * @return the class at the given position in the current batch.
+         */
+        abstract Class<?> at(int index);
+
+        // ------ subclass may override the following methods -------
+
+        /*
+         * Returns the start index for this frame buffer is refilled.
+         *
+         * This implementation reuses the allocated buffer for the next batch
+         * of stack frames.  For subclass to retain the fetched stack frames,
+         * it should override this method to return the index at which the frame
+         * should be filled in for the next batch.
+         */
+        int startIndex() {
+            return START_POS;
+        }
+
+        /**
+         * Returns next StackFrame object in the current batch of stack frames
+         */
+        F nextStackFrame() {
+            throw new InternalError("should not reach here");
+        }
+
+        // ------ FrameBuffer implementation ------
+
+        final int curBatchFrameCount() {
+            return currentBatchSize-START_POS;
+        }
+
+        /*
+         * Tests if this frame buffer is empty.  All frames are fetched.
+         */
+        final boolean isEmpty() {
+            return origin >= fence || (origin == START_POS && fence == 0);
+        }
+
+        /*
+         * Freezes this frame buffer.  The stack stream source is done fetching.
+         */
+        final void freeze() {
+            origin = 0;
+            fence = 0;
+        }
+
+        /*
+         * Tests if this frame buffer is active.  It is inactive when
+         * it is done for traversal.  All stack frames have been traversed.
+         */
+        final boolean isActive() {
+            return origin > 0 && (fence == 0 || origin < fence || fence == currentBatchSize);
+        }
+
+        /**
+         * Gets the class at the current frame and move to the next frame.
+         */
+        final Class<?> next() {
+            if (isEmpty()) {
+                throw new NoSuchElementException("origin=" + origin + " fence=" + fence);
+            }
+            Class<?> c = at(origin);
+            origin++;
+            if (isDebug) {
+                int index = origin-1;
+                System.out.format("  next frame at %d: %s (origin %d fence %d)%n", index,
+                        Objects.toString(c), index, fence);
+            }
+            return c;
+        }
+
+        /**
+         * Gets the class at the current frame.
+         */
+        final Class<?> get() {
+            if (isEmpty()) {
+                throw new NoSuchElementException("origin=" + origin + " fence=" + fence);
+            }
+            return at(origin);
+        }
+
+        /*
+         * Returns the index of the current frame.
+         */
+        final int getIndex() {
+            return origin;
+        }
+
+        /*
+         * Set the start and end index of a new batch of stack frames that have
+         * been filled in this frame buffer.
+         */
+        final void setBatch(int depth, int startIndex, int endIndex) {
+            if (startIndex <= 0 || endIndex <= 0)
+                throw new IllegalArgumentException("startIndex=" + startIndex + " endIndex=" + endIndex);
+
+            this.origin = startIndex;
+            this.fence = endIndex;
+            if (depth == 0 && fence > 0) {
+                // filter the frames due to the stack stream implementation
+                for (int i = START_POS; i < fence; i++) {
+                    Class<?> c = at(i);
+                    if (isDebug) System.err.format("  frame %d: %s%n", i, c);
+                    if (filterStackWalkImpl(c)) {
+                        origin++;
+                    } else {
+                        break;
+                    }
+                }
+            }
+        }
+
+        /*
+         * Checks if the origin is the expected start index.
+         */
+        final void check(int skipFrames) {
+            int index = skipFrames + START_POS;
+            if (origin != index) {
+                // stack walk must continue with the previous frame depth
+                throw new IllegalStateException("origin " + origin + " != " + index);
+            }
         }
     }
 
@@ -1093,14 +989,9 @@
     }
 
     private static boolean getProperty(String key, boolean value) {
-        String s = AccessController.doPrivileged(new PrivilegedAction<>() {
-            @Override
-            public String run() {
-                return System.getProperty(key);
-            }
-        });
+        String s = GetPropertyAction.getProperty(key);
         if (s != null) {
-            return Boolean.valueOf(s);
+            return Boolean.parseBoolean(s);
         }
         return value;
     }
--- a/jdk/src/java.base/share/classes/java/lang/String.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/String.java	Wed Jul 05 21:37:42 2017 +0200
@@ -363,7 +363,7 @@
      * @see  #String(byte[], java.nio.charset.Charset)
      * @see  #String(byte[])
      */
-    @Deprecated
+    @Deprecated(since="1.1")
     public String(byte ascii[], int hibyte, int offset, int count) {
         checkBoundsOffCount(offset, count, ascii.length);
         if (count == 0) {
@@ -415,7 +415,7 @@
      * @see  #String(byte[], java.nio.charset.Charset)
      * @see  #String(byte[])
      */
-    @Deprecated
+    @Deprecated(since="1.1")
     public String(byte ascii[], int hibyte) {
         this(ascii, hibyte, 0, ascii.length);
     }
@@ -911,7 +911,7 @@
      *                 dst.length}
      *          </ul>
      */
-    @Deprecated
+    @Deprecated(since="1.1")
     public void getBytes(int srcBegin, int srcEnd, byte dst[], int dstBegin) {
         checkBoundsBeginEnd(srcBegin, srcEnd, length());
         Objects.requireNonNull(dst);
--- a/jdk/src/java.base/share/classes/java/lang/System.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/System.java	Wed Jul 05 21:37:42 2017 +0200
@@ -1715,6 +1715,7 @@
      *      finalizers being called on live objects while other threads are
      *      concurrently manipulating those objects, resulting in erratic
      *      behavior or deadlock.
+     *      This method is subject to removal in a future version of Java SE.
      * @param value indicating enabling or disabling of finalization
      * @throws  SecurityException
      *        if a security manager exists and its <code>checkExit</code>
@@ -1725,7 +1726,7 @@
      * @see     java.lang.SecurityManager#checkExit(int)
      * @since   1.1
      */
-    @Deprecated
+    @Deprecated(since="1.2", forRemoval=true)
     public static void runFinalizersOnExit(boolean value) {
         Runtime.runFinalizersOnExit(value);
     }
--- a/jdk/src/java.base/share/classes/java/lang/Thread.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/Thread.java	Wed Jul 05 21:37:42 2017 +0200
@@ -890,7 +890,7 @@
      *       <a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">Why
      *       are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
      */
-    @Deprecated
+    @Deprecated(since="1.2")
     public final void stop() {
         SecurityManager security = System.getSecurityManager();
         if (security != null) {
@@ -922,8 +922,9 @@
      *        For more information, see
      *        <a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">Why
      *        are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
+     *        This method is subject to removal in a future version of Java SE.
      */
-    @Deprecated
+    @Deprecated(since="1.2", forRemoval=true)
     public final synchronized void stop(Throwable obj) {
         throw new UnsupportedOperationException();
     }
@@ -1043,9 +1044,10 @@
      *     "frozen" processes. For more information, see
      *     <a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">
      *     Why are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
+     *     This method is subject to removal in a future version of Java SE.
      * @throws NoSuchMethodError always
      */
-    @Deprecated
+    @Deprecated(since="1.5", forRemoval=true)
     public void destroy() {
         throw new NoSuchMethodError();
     }
@@ -1083,7 +1085,7 @@
      *   <a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">Why
      *   are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
      */
-    @Deprecated
+    @Deprecated(since="1.2")
     public final void suspend() {
         checkAccess();
         suspend0();
@@ -1109,7 +1111,7 @@
      *     <a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">Why
      *     are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
      */
-    @Deprecated
+    @Deprecated(since="1.2")
     public final void resume() {
         checkAccess();
         resume0();
@@ -1270,8 +1272,10 @@
      * @deprecated The definition of this call depends on {@link #suspend},
      *             which is deprecated.  Further, the results of this call
      *             were never well-defined.
+     *             This method is subject to removal in a future version of Java SE.
+     * @see        StackWalker
      */
-    @Deprecated
+    @Deprecated(since="1.2", forRemoval=true)
     public native int countStackFrames();
 
     /**
@@ -1388,7 +1392,7 @@
      * This method is used only for debugging.
      */
     public static void dumpStack() {
-        StackStreamFactory.makeStackTrace().printStackTrace(System.err);
+        new Exception("Stack trace").printStackTrace();
     }
 
     /**
@@ -1610,8 +1614,7 @@
             }
             return stackTrace;
         } else {
-            // Don't need JVM help for current thread
-            return StackStreamFactory.makeStackTrace().getStackTraceElements();
+            return (new Exception()).getStackTrace();
         }
     }
 
--- a/jdk/src/java.base/share/classes/java/lang/ThreadGroup.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/ThreadGroup.java	Wed Jul 05 21:37:42 2017 +0200
@@ -607,7 +607,7 @@
      * @deprecated    This method is inherently unsafe.  See
      *     {@link Thread#stop} for details.
      */
-    @Deprecated
+    @Deprecated(since="1.2")
     public final void stop() {
         if (stopOrSuspend(false))
             Thread.currentThread().stop();
@@ -669,7 +669,7 @@
      * @deprecated    This method is inherently deadlock-prone.  See
      *     {@link Thread#suspend} for details.
      */
-    @Deprecated
+    @Deprecated(since="1.2")
     @SuppressWarnings("deprecation")
     public final void suspend() {
         if (stopOrSuspend(true))
@@ -732,7 +732,7 @@
      *       both of which have been deprecated, as they are inherently
      *       deadlock-prone.  See {@link Thread#suspend} for details.
      */
-    @Deprecated
+    @Deprecated(since="1.2")
     @SuppressWarnings("deprecation")
     public final void resume() {
         int ngroupsSnapshot;
@@ -1073,7 +1073,7 @@
      *             which is deprecated.  Further, the behavior of this call
      *             was never specified.
      */
-    @Deprecated
+    @Deprecated(since="1.2")
     public boolean allowThreadSuspension(boolean b) {
         this.vmAllowSuspension = b;
         if (!b) {
--- a/jdk/src/java.base/share/classes/java/lang/Throwable.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/Throwable.java	Wed Jul 05 21:37:42 2017 +0200
@@ -785,11 +785,7 @@
     public synchronized Throwable fillInStackTrace() {
         if (stackTrace != null ||
             backtrace != null /* Out of protocol state */ ) {
-            if (backtrace == null && StackStreamFactory.useStackTrace(this)) {
-                backtrace = StackStreamFactory.makeStackTrace(this);
-            } else {
-                fillInStackTrace(0);
-            }
+            fillInStackTrace(0);
             stackTrace = UNASSIGNED_STACK;
         }
         return this;
@@ -830,15 +826,11 @@
         // backtrace if this is the first call to this method
         if (stackTrace == UNASSIGNED_STACK ||
             (stackTrace == null && backtrace != null) /* Out of protocol state */) {
-            if (backtrace instanceof StackStreamFactory.StackTrace) {
-                stackTrace = ((StackStreamFactory.StackTrace)backtrace).getStackTraceElements();
-            } else {
-                stackTrace = new StackTraceElement[depth];
-                for (int i = 0; i < depth; i++) {
-                    stackTrace[i] = new StackTraceElement();
-                }
-                getStackTraceElements(stackTrace);
+            stackTrace = new StackTraceElement[depth];
+            for (int i = 0; i < depth; i++) {
+                stackTrace[i] = new StackTraceElement();
             }
+            getStackTraceElements(stackTrace);
         } else if (stackTrace == null) {
             return UNASSIGNED_STACK;
         }
--- a/jdk/src/java.base/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java	Wed Jul 05 21:37:42 2017 +0200
@@ -88,8 +88,7 @@
 
     static {
         final String key = "jdk.internal.lambda.dumpProxyClasses";
-        String path = AccessController.doPrivileged(
-                new GetPropertyAction(key));
+        String path = GetPropertyAction.getProperty(key);
         dumper = (null == path) ? null : ProxyClassesDumper.getInstance(path);
     }
 
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MemberName.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MemberName.java	Wed Jul 05 21:37:42 2017 +0200
@@ -733,6 +733,7 @@
     }
 
     @Override
+    @SuppressWarnings("deprecation")
     public int hashCode() {
         // Avoid autoboxing getReferenceKind(), since this is used early and will force
         // early initialization of Byte$ByteCache
@@ -826,7 +827,7 @@
         assert(isResolved() == isResolved);
     }
 
-    void checkForTypeAlias() {
+    void checkForTypeAlias(Class<?> refc) {
         if (isInvocable()) {
             MethodType type;
             if (this.type instanceof MethodType)
@@ -834,16 +835,16 @@
             else
                 this.type = type = getMethodType();
             if (type.erase() == type)  return;
-            if (VerifyAccess.isTypeVisible(type, clazz))  return;
-            throw new LinkageError("bad method type alias: "+type+" not visible from "+clazz);
+            if (VerifyAccess.isTypeVisible(type, refc))  return;
+            throw new LinkageError("bad method type alias: "+type+" not visible from "+refc);
         } else {
             Class<?> type;
             if (this.type instanceof Class<?>)
                 type = (Class<?>) this.type;
             else
                 this.type = type = getFieldType();
-            if (VerifyAccess.isTypeVisible(type, clazz))  return;
-            throw new LinkageError("bad field type alias: "+type+" not visible from "+clazz);
+            if (VerifyAccess.isTypeVisible(type, refc))  return;
+            throw new LinkageError("bad field type alias: "+type+" not visible from "+refc);
         }
     }
 
@@ -1015,10 +1016,25 @@
             MemberName m = ref.clone();  // JVM will side-effect the ref
             assert(refKind == m.getReferenceKind());
             try {
+                // There are 4 entities in play here:
+                //   * LC: lookupClass
+                //   * REFC: symbolic reference class (MN.clazz before resolution);
+                //   * DEFC: resolved method holder (MN.clazz after resolution);
+                //   * PTYPES: parameter types (MN.type)
+                //
+                // What we care about when resolving a MemberName is consistency between DEFC and PTYPES.
+                // We do type alias (TA) checks on DEFC to ensure that. DEFC is not known until the JVM
+                // finishes the resolution, so do TA checks right after MHN.resolve() is over.
+                //
+                // All parameters passed by a caller are checked against MH type (PTYPES) on every invocation,
+                // so it is safe to call a MH from any context.
+                //
+                // REFC view on PTYPES doesn't matter, since it is used only as a starting point for resolution and doesn't
+                // participate in method selection.
                 m = MethodHandleNatives.resolve(m, lookupClass);
-                m.checkForTypeAlias();
+                m.checkForTypeAlias(m.getDeclaringClass());
                 m.resolution = null;
-            } catch (LinkageError ex) {
+            } catch (ClassNotFoundException | LinkageError ex) {
                 // JVM reports that the "bytecode behavior" would get an error
                 assert(!m.isResolved());
                 m.resolution = ex;
@@ -1132,6 +1148,10 @@
             public Object newMemberName() {
                 return new MemberName();
             }
+            public String getName(Object mname) {
+                MemberName memberName = (MemberName)mname;
+                return memberName.getName();
+            }
         });
     }
 }
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java	Wed Jul 05 21:37:42 2017 +0200
@@ -49,7 +49,7 @@
 
     static native void init(MemberName self, Object ref);
     static native void expand(MemberName self);
-    static native MemberName resolve(MemberName self, Class<?> caller) throws LinkageError;
+    static native MemberName resolve(MemberName self, Class<?> caller) throws LinkageError, ClassNotFoundException;
     static native int getMembers(Class<?> defc, String matchName, String matchSig,
             int matchFlags, Class<?> caller, int skip, MemberName[] results);
 
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleStatics.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleStatics.java	Wed Jul 05 21:37:42 2017 +0200
@@ -25,9 +25,9 @@
 
 package java.lang.invoke;
 
-import java.security.AccessController;
-import java.security.PrivilegedAction;
+import java.util.Properties;
 import jdk.internal.misc.Unsafe;
+import sun.security.action.GetPropertyAction;
 
 /**
  * This class consists exclusively of static names internal to the
@@ -53,32 +53,27 @@
     static final boolean VAR_HANDLE_GUARDS;
 
     static {
-        final Object[] values = new Object[10];
-        AccessController.doPrivileged(new PrivilegedAction<>() {
-                public Void run() {
-                    values[0] = Boolean.getBoolean("java.lang.invoke.MethodHandle.DEBUG_NAMES");
-                    values[1] = Boolean.getBoolean("java.lang.invoke.MethodHandle.DUMP_CLASS_FILES");
-                    values[2] = Boolean.getBoolean("java.lang.invoke.MethodHandle.TRACE_INTERPRETER");
-                    values[3] = Boolean.getBoolean("java.lang.invoke.MethodHandle.TRACE_METHOD_LINKAGE");
-                    values[4] = Integer.getInteger("java.lang.invoke.MethodHandle.COMPILE_THRESHOLD", 0);
-                    values[5] = Integer.getInteger("java.lang.invoke.MethodHandle.DONT_INLINE_THRESHOLD", 30);
-                    values[6] = Integer.getInteger("java.lang.invoke.MethodHandle.PROFILE_LEVEL", 0);
-                    values[7] = Boolean.parseBoolean(System.getProperty("java.lang.invoke.MethodHandle.PROFILE_GWT", "true"));
-                    values[8] = Integer.getInteger("java.lang.invoke.MethodHandle.CUSTOMIZE_THRESHOLD", 127);
-                    values[9] = Boolean.parseBoolean(System.getProperty("java.lang.invoke.VarHandle.VAR_HANDLE_GUARDS", "true"));
-                    return null;
-                }
-            });
-        DEBUG_METHOD_HANDLE_NAMES = (Boolean) values[0];
-        DUMP_CLASS_FILES          = (Boolean) values[1];
-        TRACE_INTERPRETER         = (Boolean) values[2];
-        TRACE_METHOD_LINKAGE      = (Boolean) values[3];
-        COMPILE_THRESHOLD         = (Integer) values[4];
-        DONT_INLINE_THRESHOLD     = (Integer) values[5];
-        PROFILE_LEVEL             = (Integer) values[6];
-        PROFILE_GWT               = (Boolean) values[7];
-        CUSTOMIZE_THRESHOLD       = (Integer) values[8];
-        VAR_HANDLE_GUARDS         = (Boolean) values[9];
+        Properties props = GetPropertyAction.getProperties();
+        DEBUG_METHOD_HANDLE_NAMES = Boolean.parseBoolean(
+                props.getProperty("java.lang.invoke.MethodHandle.DEBUG_NAMES"));
+        DUMP_CLASS_FILES = Boolean.parseBoolean(
+                props.getProperty("java.lang.invoke.MethodHandle.DUMP_CLASS_FILES"));
+        TRACE_INTERPRETER = Boolean.parseBoolean(
+                props.getProperty("java.lang.invoke.MethodHandle.TRACE_INTERPRETER"));
+        TRACE_METHOD_LINKAGE = Boolean.parseBoolean(
+                props.getProperty("java.lang.invoke.MethodHandle.TRACE_METHOD_LINKAGE"));
+        COMPILE_THRESHOLD = Integer.parseInt(
+                props.getProperty("java.lang.invoke.MethodHandle.COMPILE_THRESHOLD", "0"));
+        DONT_INLINE_THRESHOLD = Integer.parseInt(
+                props.getProperty("java.lang.invoke.MethodHandle.DONT_INLINE_THRESHOLD", "30"));
+        PROFILE_LEVEL = Integer.parseInt(
+                props.getProperty("java.lang.invoke.MethodHandle.PROFILE_LEVEL", "0"));
+        PROFILE_GWT = Boolean.parseBoolean(
+                props.getProperty("java.lang.invoke.MethodHandle.PROFILE_GWT", "true"));
+        CUSTOMIZE_THRESHOLD = Integer.parseInt(
+                props.getProperty("java.lang.invoke.MethodHandle.CUSTOMIZE_THRESHOLD", "127"));
+        VAR_HANDLE_GUARDS = Boolean.parseBoolean(
+                props.getProperty("java.lang.invoke.VarHandle.VAR_HANDLE_GUARDS", "true"));
 
         if (CUSTOMIZE_THRESHOLD < -1 || CUSTOMIZE_THRESHOLD > 127) {
             throw newInternalError("CUSTOMIZE_THRESHOLD should be in [-1...127] range");
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java	Wed Jul 05 21:37:42 2017 +0200
@@ -28,6 +28,7 @@
 import java.lang.reflect.*;
 import java.util.ArrayList;
 import java.util.BitSet;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Arrays;
 import java.util.Objects;
@@ -53,6 +54,7 @@
 import jdk.internal.org.objectweb.asm.Opcodes;
 
 import static java.lang.invoke.MethodHandleStatics.newIllegalArgumentException;
+import static java.lang.invoke.MethodType.methodType;
 
 /**
  * This class consists exclusively of static methods that operate on or return
@@ -3000,7 +3002,7 @@
 
     private static final MethodHandle[] IDENTITY_MHS = new MethodHandle[Wrapper.values().length];
     private static MethodHandle makeIdentity(Class<?> ptype) {
-        MethodType mtype = MethodType.methodType(ptype, ptype);
+        MethodType mtype = methodType(ptype, ptype);
         LambdaForm lform = LambdaForm.identityForm(BasicType.basicType(ptype));
         return MethodHandleImpl.makeIntrinsic(mtype, lform, Intrinsic.IDENTITY);
     }
@@ -3018,7 +3020,7 @@
     }
     private static final MethodHandle[] ZERO_MHS = new MethodHandle[Wrapper.values().length];
     private static MethodHandle makeZero(Class<?> rtype) {
-        MethodType mtype = MethodType.methodType(rtype);
+        MethodType mtype = methodType(rtype);
         LambdaForm lform = LambdaForm.zeroForm(BasicType.basicType(rtype));
         return MethodHandleImpl.makeIntrinsic(mtype, lform, Intrinsic.ZERO);
     }
@@ -3929,7 +3931,7 @@
     MethodHandle throwException(Class<?> returnType, Class<? extends Throwable> exType) {
         if (!Throwable.class.isAssignableFrom(exType))
             throw new ClassCastException(exType.getName());
-        return MethodHandleImpl.throwException(MethodType.methodType(returnType, exType));
+        return MethodHandleImpl.throwException(methodType(returnType, exType));
     }
 
     /**
@@ -4166,7 +4168,7 @@
         for (int i = 0; i < nclauses; ++i) {
             Class<?> t = iterationVariableTypes.get(i);
             if (init.get(i) == null) {
-                init.set(i, empty(MethodType.methodType(t, commonSuffix)));
+                init.set(i, empty(methodType(t, commonSuffix)));
             }
             if (step.get(i) == null) {
                 step.set(i, dropArgumentsToMatch(identityOrVoid(t), 0, commonParameterSequence, i));
@@ -4175,7 +4177,7 @@
                 pred.set(i, dropArguments(constant(boolean.class, true), 0, commonParameterSequence));
             }
             if (fini.get(i) == null) {
-                fini.set(i, empty(MethodType.methodType(t, commonParameterSequence)));
+                fini.set(i, empty(methodType(t, commonParameterSequence)));
             }
         }
 
@@ -4269,7 +4271,8 @@
      * @since 9
      */
     public static MethodHandle whileLoop(MethodHandle init, MethodHandle pred, MethodHandle body) {
-        MethodHandle fin = init == null ? zero(void.class) : identity(init.type().returnType());
+        MethodHandle fin = init == null || init.type().returnType() == void.class ? zero(void.class) :
+                identity(init.type().returnType());
         MethodHandle[] checkExit = {null, null, pred, fin};
         MethodHandle[] varBody = {init, body};
         return loop(checkExit, varBody);
@@ -4335,7 +4338,8 @@
      * @since 9
      */
     public static MethodHandle doWhileLoop(MethodHandle init, MethodHandle body, MethodHandle pred) {
-        MethodHandle fin = init == null ? zero(void.class) : identity(init.type().returnType());
+        MethodHandle fin = init == null || init.type().returnType() == void.class ? zero(void.class) :
+                identity(init.type().returnType());
         MethodHandle[] clause = {init, body, pred, fin};
         return loop(clause);
     }
@@ -4472,12 +4476,24 @@
      * @since 9
      */
     public static MethodHandle countedLoop(MethodHandle start, MethodHandle end, MethodHandle init, MethodHandle body) {
-        MethodHandle returnVar = dropArguments(init == null ? zero(void.class) : identity(init.type().returnType()),
-                0, int.class, int.class);
+        Class<?> resultType;
+        MethodHandle actualInit;
+        if (init == null) {
+            resultType = body == null ? void.class : body.type().returnType();
+            actualInit = empty(methodType(resultType));
+        } else {
+            resultType = init.type().returnType();
+            actualInit = init;
+        }
+        MethodHandle defaultResultHandle = resultType == void.class ? zero(void.class) : identity(resultType);
+        MethodHandle actualBody = body == null ? dropArguments(defaultResultHandle, 0, int.class) : body;
+        MethodHandle returnVar = dropArguments(defaultResultHandle, 0, int.class, int.class);
+        MethodHandle actualEnd = end == null ? constant(int.class, 0) : end;
         MethodHandle[] indexVar = {start, MethodHandleImpl.getConstantHandle(MethodHandleImpl.MH_countedLoopStep)};
-        MethodHandle[] loopLimit = {end, null, MethodHandleImpl.getConstantHandle(MethodHandleImpl.MH_countedLoopPred), returnVar};
-        MethodHandle[] bodyClause = {init,
-                filterArgument(dropArguments(body, 1, int.class), 0,
+        MethodHandle[] loopLimit = {actualEnd, null,
+                MethodHandleImpl.getConstantHandle(MethodHandleImpl.MH_countedLoopPred), returnVar};
+        MethodHandle[] bodyClause = {actualInit,
+                filterArgument(dropArguments(actualBody, 1, int.class), 0,
                         MethodHandleImpl.getConstantHandle(MethodHandleImpl.MH_decrementCounter))};
         return loop(indexVar, loopLimit, bodyClause);
     }
@@ -4485,6 +4501,7 @@
     /**
      * Constructs a loop that ranges over the elements produced by an {@code Iterator<T>}.
      * The iterator will be produced by the evaluation of the {@code iterator} handle.
+     * This handle must have {@link java.util.Iterator} as its return type.
      * If this handle is passed as {@code null} the method {@link Iterable#iterator} will be used instead,
      * and will be applied to a leading argument of the loop handle.
      * Each value produced by the iterator is passed to the {@code body}, which must accept an initial {@code T} parameter.
@@ -4534,7 +4551,7 @@
      * assertEquals(reversedList, (List<String>) loop.invoke(list));
      * }</pre></blockquote>
      * <p>
-     * @implSpec The implementation of this method is equivalent to:
+     * @implSpec The implementation of this method is equivalent to (excluding error handling):
      * <blockquote><pre>{@code
      * MethodHandle iteratedLoop(MethodHandle iterator, MethodHandle init, MethodHandle body) {
      *     // assume MH_next and MH_hasNext are handles to methods of Iterator
@@ -4550,6 +4567,7 @@
      * }</pre></blockquote>
      *
      * @param iterator a handle to return the iterator to start the loop.
+     *             The handle must have {@link java.util.Iterator} as its return type.
      *             Passing {@code null} will make the loop call {@link Iterable#iterator()} on the first
      *             incoming value.
      * @param init initializer for additional loop state. This determines the loop's result type.
@@ -4565,21 +4583,30 @@
      * @since 9
      */
     public static MethodHandle iteratedLoop(MethodHandle iterator, MethodHandle init, MethodHandle body) {
-        checkIteratedLoop(body);
+        checkIteratedLoop(iterator, body);
+        Class<?> resultType = init == null ?
+                body == null ? void.class : body.type().returnType() :
+                init.type().returnType();
+        boolean voidResult = resultType == void.class;
 
-        MethodHandle initit = MethodHandleImpl.getConstantHandle(MethodHandleImpl.MH_initIterator);
-        MethodHandle initIterator = iterator == null ?
-                initit.asType(initit.type().changeParameterType(0, body.type().parameterType(init == null ? 1 : 2))) :
-                iterator;
-        Class<?> itype = initIterator.type().returnType();
+        MethodHandle initIterator;
+        if (iterator == null) {
+            MethodHandle initit = MethodHandleImpl.getConstantHandle(MethodHandleImpl.MH_initIterator);
+            initIterator = initit.asType(initit.type().changeParameterType(0,
+                    body.type().parameterType(voidResult ? 1 : 2)));
+        } else {
+            initIterator = iterator.asType(iterator.type().changeReturnType(Iterator.class));
+        }
+
         Class<?> ttype = body.type().parameterType(0);
 
         MethodHandle returnVar =
-                dropArguments(init == null ? zero(void.class) : identity(init.type().returnType()), 0, itype);
+                dropArguments(voidResult ? zero(void.class) : identity(resultType), 0, Iterator.class);
         MethodHandle initnx = MethodHandleImpl.getConstantHandle(MethodHandleImpl.MH_iterateNext);
         MethodHandle nextVal = initnx.asType(initnx.type().changeReturnType(ttype));
 
-        MethodHandle[] iterVar = {initIterator, null, MethodHandleImpl.getConstantHandle(MethodHandleImpl.MH_iteratePred), returnVar};
+        MethodHandle[] iterVar = {initIterator, null, MethodHandleImpl.getConstantHandle(MethodHandleImpl.MH_iteratePred),
+                returnVar};
         MethodHandle[] bodyClause = {init, filterArgument(body, 0, nextVal)};
 
         return loop(iterVar, bodyClause);
@@ -4833,7 +4860,10 @@
         }
     }
 
-    private static void checkIteratedLoop(MethodHandle body) {
+    private static void checkIteratedLoop(MethodHandle iterator, MethodHandle body) {
+        if (null != iterator && !Iterator.class.isAssignableFrom(iterator.type().returnType())) {
+            throw newIllegalArgumentException("iteratedLoop first argument must have Iterator return type");
+        }
         if (null == body) {
             throw newIllegalArgumentException("iterated loop body must not be null");
         }
--- a/jdk/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java	Wed Jul 05 21:37:42 2017 +0200
@@ -33,7 +33,6 @@
 import jdk.internal.misc.Unsafe;
 
 import java.lang.invoke.MethodHandles.Lookup;
-import java.security.AccessController;
 import java.util.*;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
@@ -188,14 +187,15 @@
     private static final ProxyClassesDumper DUMPER;
 
     static {
-        final String strategy = AccessController.doPrivileged(
-                new GetPropertyAction("java.lang.invoke.stringConcat"));
-        CACHE_ENABLE = Boolean.parseBoolean(AccessController.doPrivileged(
-                new GetPropertyAction("java.lang.invoke.stringConcat.cache")));
-        DEBUG = Boolean.parseBoolean(AccessController.doPrivileged(
-                new GetPropertyAction("java.lang.invoke.stringConcat.debug")));
-        final String dumpPath = AccessController.doPrivileged(
-                new GetPropertyAction("java.lang.invoke.stringConcat.dumpClasses"));
+        Properties props = GetPropertyAction.getProperties();
+        final String strategy =
+                props.getProperty("java.lang.invoke.stringConcat");
+        CACHE_ENABLE = Boolean.parseBoolean(
+                props.getProperty("java.lang.invoke.stringConcat.cache"));
+        DEBUG = Boolean.parseBoolean(
+                props.getProperty("java.lang.invoke.stringConcat.debug"));
+        final String dumpPath =
+                props.getProperty("java.lang.invoke.stringConcat.dumpClasses");
 
         STRATEGY = (strategy == null) ? DEFAULT_STRATEGY : Strategy.valueOf(strategy);
         CACHE = CACHE_ENABLE ? new ConcurrentHashMap<>() : null;
--- a/jdk/src/java.base/share/classes/java/lang/module/ModuleFinder.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/module/ModuleFinder.java	Wed Jul 05 21:37:42 2017 +0200
@@ -39,6 +39,7 @@
 import java.util.Set;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
+import sun.security.action.GetPropertyAction;
 
 /**
  * A finder of modules. A {@code ModuleFinder} is used to find modules during
@@ -152,7 +153,7 @@
 
         SecurityManager sm = System.getSecurityManager();
         if (sm != null) {
-            PrivilegedAction<String> pa = () -> System.getProperty("java.home");
+            PrivilegedAction<String> pa = new GetPropertyAction("java.home");
             home = AccessController.doPrivileged(pa);
             Permission p = new FilePermission(home + File.separator + "-", "read");
             sm.checkPermission(p);
--- a/jdk/src/java.base/share/classes/java/lang/reflect/Proxy.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/Proxy.java	Wed Jul 05 21:37:42 2017 +0200
@@ -50,6 +50,7 @@
 import jdk.internal.reflect.CallerSensitive;
 import jdk.internal.reflect.Reflection;
 import sun.reflect.misc.ReflectUtil;
+import sun.security.action.GetPropertyAction;
 import sun.security.util.SecurityConstants;
 
 /**
@@ -581,11 +582,7 @@
         }
 
         private static final String DEBUG =
-            AccessController.doPrivileged(new PrivilegedAction<>() {
-                public String run() {
-                    return System.getProperty("jdk.proxy.debug", "");
-                }
-            });
+                GetPropertyAction.getProperty("jdk.proxy.debug", "");
 
         private static boolean isDebug() {
             return !DEBUG.isEmpty();
--- a/jdk/src/java.base/share/classes/java/lang/reflect/ProxyGenerator.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/ProxyGenerator.java	Wed Jul 05 21:37:42 2017 +0200
@@ -1750,7 +1750,7 @@
          * Get or assign the index for a CONSTANT_Float entry.
          */
         public short getFloat(float f) {
-            return getValue(new Float(f));
+            return getValue(f);
         }
 
         /**
--- a/jdk/src/java.base/share/classes/java/net/AbstractPlainDatagramSocketImpl.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/net/AbstractPlainDatagramSocketImpl.java	Wed Jul 05 21:37:42 2017 +0200
@@ -31,6 +31,7 @@
 import java.util.Set;
 import java.util.HashSet;
 import java.util.Collections;
+import sun.security.action.GetPropertyAction;
 
 /**
  * Abstract datagram and multicast socket implementation base class.
@@ -51,9 +52,7 @@
     protected InetAddress connectedAddress = null;
     private int connectedPort = -1;
 
-    private static final String os = AccessController.doPrivileged(
-        new sun.security.action.GetPropertyAction("os.name")
-    );
+    private static final String os = GetPropertyAction.getProperty("os.name");
 
     /**
      * flag set if the native connect() call not to be used
--- a/jdk/src/java.base/share/classes/java/net/InetAddress.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/net/InetAddress.java	Wed Jul 05 21:37:42 2017 +0200
@@ -1123,8 +1123,8 @@
      */
     private static NameService createNameService() {
 
-        String hostsFileName = AccessController
-                .doPrivileged(new GetPropertyAction("jdk.net.hosts.file"));
+        String hostsFileName =
+                GetPropertyAction.getProperty("jdk.net.hosts.file");
         NameService theNameService;
         if (hostsFileName != null) {
             theNameService = new HostsFileNameService(hostsFileName);
@@ -1643,8 +1643,7 @@
          * property can vary across implementations of the java.
          * classes.  The default is an empty String "".
          */
-        String prefix = AccessController.doPrivileged(
-                      new GetPropertyAction("impl.prefix", ""));
+        String prefix = GetPropertyAction.getProperty("impl.prefix", "");
         try {
             impl = Class.forName("java.net." + prefix + implName).newInstance();
         } catch (ClassNotFoundException e) {
--- a/jdk/src/java.base/share/classes/java/net/SocksSocketImpl.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/net/SocksSocketImpl.java	Wed Jul 05 21:37:42 2017 +0200
@@ -33,6 +33,7 @@
 import sun.net.SocksProxy;
 import sun.net.spi.DefaultProxySelector;
 import sun.net.www.ParseUtil;
+import sun.security.action.GetPropertyAction;
 /* import org.ietf.jgss.*; */
 
 /**
@@ -177,8 +178,7 @@
                 userName = pw.getUserName();
                 password = new String(pw.getPassword());
             } else {
-                userName = java.security.AccessController.doPrivileged(
-                        new sun.security.action.GetPropertyAction("user.name"));
+                userName = GetPropertyAction.getProperty("user.name");
             }
             if (userName == null)
                 return false;
@@ -1088,8 +1088,7 @@
                 userName = System.getProperty("user.name");
             } catch (SecurityException se) { /* swallow Exception */ }
         } else {
-            userName = java.security.AccessController.doPrivileged(
-                new sun.security.action.GetPropertyAction("user.name"));
+            userName = GetPropertyAction.getProperty("user.name");
         }
         return userName;
     }
--- a/jdk/src/java.base/share/classes/java/net/URL.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/net/URL.java	Wed Jul 05 21:37:42 2017 +0200
@@ -42,6 +42,7 @@
 import java.util.ServiceLoader;
 
 import sun.security.util.SecurityConstants;
+import sun.security.action.GetPropertyAction;
 
 /**
  * Class {@code URL} represents a Uniform Resource
@@ -1210,12 +1211,8 @@
     }
 
     private static URLStreamHandler lookupViaProperty(String protocol) {
-        String packagePrefixList = java.security.AccessController.doPrivileged(
-                new PrivilegedAction<>() {
-                    public String run() {
-                        return System.getProperty(protocolPathProp, null);
-                    }
-                });
+        String packagePrefixList =
+                GetPropertyAction.getProperty(protocolPathProp);
         if (packagePrefixList == null) {
             // not set
             return null;
--- a/jdk/src/java.base/share/classes/java/net/URLConnection.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/net/URLConnection.java	Wed Jul 05 21:37:42 2017 +0200
@@ -43,6 +43,7 @@
 import java.security.AccessController;
 import sun.security.util.SecurityConstants;
 import sun.net.www.MessageHeader;
+import sun.security.action.GetPropertyAction;
 
 /**
  * The abstract class {@code URLConnection} is the superclass
@@ -1395,8 +1396,8 @@
      * is always the last one on the returned package list.
      */
     private String getContentHandlerPkgPrefixes() {
-        String packagePrefixList = AccessController.doPrivileged(
-            new sun.security.action.GetPropertyAction(contentPathProp, ""));
+        String packagePrefixList =
+                GetPropertyAction.getProperty(contentPathProp, "");
 
         if (packagePrefixList != "") {
             packagePrefixList += "|";
--- a/jdk/src/java.base/share/classes/java/net/URLEncoder.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/net/URLEncoder.java	Wed Jul 05 21:37:42 2017 +0200
@@ -25,19 +25,12 @@
 
 package java.net;
 
-import java.io.ByteArrayOutputStream;
-import java.io.BufferedWriter;
-import java.io.OutputStreamWriter;
-import java.io.IOException;
 import java.io.UnsupportedEncodingException;
 import java.io.CharArrayWriter;
 import java.nio.charset.Charset;
 import java.nio.charset.IllegalCharsetNameException;
 import java.nio.charset.UnsupportedCharsetException ;
 import java.util.BitSet;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import sun.security.action.GetBooleanAction;
 import sun.security.action.GetPropertyAction;
 
 /**
@@ -140,9 +133,7 @@
         dontNeedEncoding.set('.');
         dontNeedEncoding.set('*');
 
-        dfltEncName = AccessController.doPrivileged(
-            new GetPropertyAction("file.encoding")
-        );
+        dfltEncName = GetPropertyAction.getProperty("file.encoding");
     }
 
     /**
--- a/jdk/src/java.base/share/classes/java/net/URLPermission.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/net/URLPermission.java	Wed Jul 05 21:37:42 2017 +0200
@@ -170,7 +170,8 @@
         parseURI(getName());
         int colon = actions.indexOf(':');
         if (actions.lastIndexOf(':') != colon) {
-            throw new IllegalArgumentException("invalid actions string");
+            throw new IllegalArgumentException(
+                "Invalid actions string: \"" + actions + "\"");
         }
 
         String methods, headers;
@@ -371,7 +372,8 @@
                     l.add(s);
                 b = new StringBuilder();
             } else if (c == ' ' || c == '\t') {
-                throw new IllegalArgumentException("white space not allowed");
+                throw new IllegalArgumentException(
+                    "White space not allowed in methods: \"" + methods + "\"");
             } else {
                 if (c >= 'a' && c <= 'z') {
                     c += 'A' - 'a';
@@ -398,7 +400,8 @@
                 }
                 b.append(c);
             } else if (c == ' ' || c == '\t') {
-                throw new IllegalArgumentException("white space not allowed");
+                throw new IllegalArgumentException(
+                    "White space not allowed in headers: \"" + headers + "\"");
             } else if (c == '-') {
                     capitalizeNext = true;
                 b.append(c);
@@ -423,14 +426,16 @@
         int len = url.length();
         int delim = url.indexOf(':');
         if (delim == -1 || delim + 1 == len) {
-            throw new IllegalArgumentException("invalid URL string");
+            throw new IllegalArgumentException(
+                "Invalid URL string: \"" + url + "\"");
         }
         scheme = url.substring(0, delim).toLowerCase();
         this.ssp = url.substring(delim + 1);
 
         if (!ssp.startsWith("//")) {
             if (!ssp.equals("*")) {
-                throw new IllegalArgumentException("invalid URL string");
+                throw new IllegalArgumentException(
+                    "Invalid URL string: \"" + url + "\"");
             }
             this.authority = new Authority(scheme, "*");
             return;
--- a/jdk/src/java.base/share/classes/java/nio/charset/Charset.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/nio/charset/Charset.java	Wed Jul 05 21:37:42 2017 +0200
@@ -283,8 +283,8 @@
         if (level == null) {
             if (!VM.isBooted())
                 return false;
-            bugLevel = level = AccessController.doPrivileged(
-                new GetPropertyAction("sun.nio.cs.bugLevel", ""));
+            bugLevel = level =
+                    GetPropertyAction.getProperty("sun.nio.cs.bugLevel", "");
         }
         return level.equals(bl);
     }
@@ -609,8 +609,7 @@
     public static Charset defaultCharset() {
         if (defaultCharset == null) {
             synchronized (Charset.class) {
-                String csn = AccessController.doPrivileged(
-                    new GetPropertyAction("file.encoding"));
+                String csn = GetPropertyAction.getProperty("file.encoding");
                 Charset cs = lookup(csn);
                 if (cs != null)
                     defaultCharset = cs;
--- a/jdk/src/java.base/share/classes/java/nio/file/TempFileHelper.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/nio/file/TempFileHelper.java	Wed Jul 05 21:37:42 2017 +0200
@@ -28,7 +28,6 @@
 import java.util.Set;
 import java.util.EnumSet;
 import java.security.SecureRandom;
-import static java.security.AccessController.*;
 import java.io.IOException;
 import java.nio.file.attribute.FileAttribute;
 import java.nio.file.attribute.PosixFilePermission;
@@ -47,7 +46,7 @@
 
     // temporary directory location
     private static final Path tmpdir =
-        Paths.get(doPrivileged(new GetPropertyAction("java.io.tmpdir")));
+        Paths.get(GetPropertyAction.getProperty("java.io.tmpdir"));
 
     private static final boolean isPosix =
         FileSystems.getDefault().supportedFileAttributeViews().contains("posix");
--- a/jdk/src/java.base/share/classes/java/text/ChoiceFormat.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/text/ChoiceFormat.java	Wed Jul 05 21:37:42 2017 +0200
@@ -437,7 +437,7 @@
         if (status.index == start) {
             status.errorIndex = furthest;
         }
-        return new Double(bestNumber);
+        return Double.valueOf(bestNumber);
     }
 
     /**
--- a/jdk/src/java.base/share/classes/java/text/DecimalFormat.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/text/DecimalFormat.java	Wed Jul 05 21:37:42 2017 +0200
@@ -1996,7 +1996,7 @@
         // special case NaN
         if (text.regionMatches(pos.index, symbols.getNaN(), 0, symbols.getNaN().length())) {
             pos.index = pos.index + symbols.getNaN().length();
-            return new Double(Double.NaN);
+            return Double.valueOf(Double.NaN);
         }
 
         boolean[] status = new boolean[STATUS_LENGTH];
@@ -2007,19 +2007,19 @@
         // special case INFINITY
         if (status[STATUS_INFINITE]) {
             if (status[STATUS_POSITIVE] == (multiplier >= 0)) {
-                return new Double(Double.POSITIVE_INFINITY);
+                return Double.valueOf(Double.POSITIVE_INFINITY);
             } else {
-                return new Double(Double.NEGATIVE_INFINITY);
+                return Double.valueOf(Double.NEGATIVE_INFINITY);
             }
         }
 
         if (multiplier == 0) {
             if (digitList.isZero()) {
-                return new Double(Double.NaN);
+                return Double.valueOf(Double.NaN);
             } else if (status[STATUS_POSITIVE]) {
-                return new Double(Double.POSITIVE_INFINITY);
+                return Double.valueOf(Double.POSITIVE_INFINITY);
             } else {
-                return new Double(Double.NEGATIVE_INFINITY);
+                return Double.valueOf(Double.NEGATIVE_INFINITY);
             }
         }
 
@@ -2093,8 +2093,8 @@
                             !isParseIntegerOnly();
             }
 
-            return gotDouble ?
-                (Number)new Double(doubleResult) : (Number)Long.valueOf(longResult);
+            // cast inside of ?: because of binary numeric promotion, JLS 15.25
+            return gotDouble ? (Number)doubleResult : (Number)longResult;
         }
     }
 
--- a/jdk/src/java.base/share/classes/java/time/format/DateTimeFormatter.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/time/format/DateTimeFormatter.java	Wed Jul 05 21:37:42 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -284,6 +284,7 @@
  *   D       day-of-year                 number            189
  *   M/L     month-of-year               number/text       7; 07; Jul; July; J
  *   d       day-of-month                number            10
+ *   g       modified-julian-day         number            2451334
  *
  *   Q/q     quarter-of-year             number/text       3; 03; Q3; 3rd quarter
  *   Y       week-based-year             year              1996; 96
@@ -308,10 +309,10 @@
  *
  *   V       time-zone ID                zone-id           America/Los_Angeles; Z; -08:30
  *   z       time-zone name              zone-name         Pacific Standard Time; PST
- *   O       localized zone-offset       offset-O          GMT+8; GMT+08:00; UTC-08:00;
- *   X       zone-offset 'Z' for zero    offset-X          Z; -08; -0830; -08:30; -083015; -08:30:15;
- *   x       zone-offset                 offset-x          +0000; -08; -0830; -08:30; -083015; -08:30:15;
- *   Z       zone-offset                 offset-Z          +0000; -0800; -08:00;
+ *   O       localized zone-offset       offset-O          GMT+8; GMT+08:00; UTC-08:00
+ *   X       zone-offset 'Z' for zero    offset-X          Z; -08; -0830; -08:30; -083015; -08:30:15
+ *   x       zone-offset                 offset-x          +0000; -08; -0830; -08:30; -083015; -08:30:15
+ *   Z       zone-offset                 offset-Z          +0000; -0800; -08:00
  *
  *   p       pad next                    pad modifier      1
  *
--- a/jdk/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java	Wed Jul 05 21:37:42 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -90,6 +90,7 @@
 import java.time.format.DateTimeTextProvider.LocaleStore;
 import java.time.temporal.ChronoField;
 import java.time.temporal.IsoFields;
+import java.time.temporal.JulianFields;
 import java.time.temporal.TemporalAccessor;
 import java.time.temporal.TemporalField;
 import java.time.temporal.TemporalQueries;
@@ -666,8 +667,11 @@
      * No rounding occurs due to the maximum width - digits are simply dropped.
      * <p>
      * When parsing in strict mode, the number of parsed digits must be between
-     * the minimum and maximum width. When parsing in lenient mode, the minimum
-     * width is considered to be zero and the maximum is nine.
+     * the minimum and maximum width. In strict mode, if the minimum and maximum widths
+     * are equal and there is no decimal point then the parser will
+     * participate in adjacent value parsing, see
+     * {@link appendValue(java.time.temporal.TemporalField, int)}. When parsing in lenient mode,
+     * the minimum width is considered to be zero and the maximum is nine.
      * <p>
      * If the value cannot be obtained then an exception will be thrown.
      * If the value is negative an exception will be thrown.
@@ -686,7 +690,12 @@
      */
     public DateTimeFormatterBuilder appendFraction(
             TemporalField field, int minWidth, int maxWidth, boolean decimalPoint) {
-        appendInternal(new FractionPrinterParser(field, minWidth, maxWidth, decimalPoint));
+        if (minWidth == maxWidth && decimalPoint == false) {
+            // adjacent parsing
+            appendValue(new FractionPrinterParser(field, minWidth, maxWidth, decimalPoint));
+        } else {
+            appendInternal(new FractionPrinterParser(field, minWidth, maxWidth, decimalPoint));
+        }
         return this;
     }
 
@@ -1383,6 +1392,7 @@
      *   D       day-of-year                 number            189
      *   M/L     month-of-year               number/text       7; 07; Jul; July; J
      *   d       day-of-month                number            10
+     *   g       modified-julian-day         number            2451334
      *
      *   Q/q     quarter-of-year             number/text       3; 03; Q3; 3rd quarter
      *   Y       week-based-year             year              1996; 96
@@ -1408,9 +1418,9 @@
      *   V       time-zone ID                zone-id           America/Los_Angeles; Z; -08:30
      *   z       time-zone name              zone-name         Pacific Standard Time; PST
      *   O       localized zone-offset       offset-O          GMT+8; GMT+08:00; UTC-08:00;
-     *   X       zone-offset 'Z' for zero    offset-X          Z; -08; -0830; -08:30; -083015; -08:30:15;
-     *   x       zone-offset                 offset-x          +0000; -08; -0830; -08:30; -083015; -08:30:15;
-     *   Z       zone-offset                 offset-Z          +0000; -0800; -08:00;
+     *   X       zone-offset 'Z' for zero    offset-X          Z; -08; -0830; -08:30; -083015; -08:30:15
+     *   x       zone-offset                 offset-x          +0000; -08; -0830; -08:30; -083015; -08:30:15
+     *   Z       zone-offset                 offset-Z          +0000; -0800; -08:00
      *
      *   p       pad next                    pad modifier      1
      *
@@ -1437,37 +1447,37 @@
      *    GGGG    4      appendText(ChronoField.ERA, TextStyle.FULL)
      *    GGGGG   5      appendText(ChronoField.ERA, TextStyle.NARROW)
      *
-     *    u       1      appendValue(ChronoField.YEAR, 1, 19, SignStyle.NORMAL);
-     *    uu      2      appendValueReduced(ChronoField.YEAR, 2, 2000);
-     *    uuu     3      appendValue(ChronoField.YEAR, 3, 19, SignStyle.NORMAL);
-     *    u..u    4..n   appendValue(ChronoField.YEAR, n, 19, SignStyle.EXCEEDS_PAD);
-     *    y       1      appendValue(ChronoField.YEAR_OF_ERA, 1, 19, SignStyle.NORMAL);
-     *    yy      2      appendValueReduced(ChronoField.YEAR_OF_ERA, 2, 2000);
-     *    yyy     3      appendValue(ChronoField.YEAR_OF_ERA, 3, 19, SignStyle.NORMAL);
-     *    y..y    4..n   appendValue(ChronoField.YEAR_OF_ERA, n, 19, SignStyle.EXCEEDS_PAD);
+     *    u       1      appendValue(ChronoField.YEAR, 1, 19, SignStyle.NORMAL)
+     *    uu      2      appendValueReduced(ChronoField.YEAR, 2, 2000)
+     *    uuu     3      appendValue(ChronoField.YEAR, 3, 19, SignStyle.NORMAL)
+     *    u..u    4..n   appendValue(ChronoField.YEAR, n, 19, SignStyle.EXCEEDS_PAD)
+     *    y       1      appendValue(ChronoField.YEAR_OF_ERA, 1, 19, SignStyle.NORMAL)
+     *    yy      2      appendValueReduced(ChronoField.YEAR_OF_ERA, 2, 2000)
+     *    yyy     3      appendValue(ChronoField.YEAR_OF_ERA, 3, 19, SignStyle.NORMAL)
+     *    y..y    4..n   appendValue(ChronoField.YEAR_OF_ERA, n, 19, SignStyle.EXCEEDS_PAD)
      *    Y       1      append special localized WeekFields element for numeric week-based-year
-     *    YY      2      append special localized WeekFields element for reduced numeric week-based-year 2 digits;
-     *    YYY     3      append special localized WeekFields element for numeric week-based-year (3, 19, SignStyle.NORMAL);
-     *    Y..Y    4..n   append special localized WeekFields element for numeric week-based-year (n, 19, SignStyle.EXCEEDS_PAD);
+     *    YY      2      append special localized WeekFields element for reduced numeric week-based-year 2 digits
+     *    YYY     3      append special localized WeekFields element for numeric week-based-year (3, 19, SignStyle.NORMAL)
+     *    Y..Y    4..n   append special localized WeekFields element for numeric week-based-year (n, 19, SignStyle.EXCEEDS_PAD)
      *
-     *    Q       1      appendValue(IsoFields.QUARTER_OF_YEAR);
-     *    QQ      2      appendValue(IsoFields.QUARTER_OF_YEAR, 2);
+     *    Q       1      appendValue(IsoFields.QUARTER_OF_YEAR)
+     *    QQ      2      appendValue(IsoFields.QUARTER_OF_YEAR, 2)
      *    QQQ     3      appendText(IsoFields.QUARTER_OF_YEAR, TextStyle.SHORT)
      *    QQQQ    4      appendText(IsoFields.QUARTER_OF_YEAR, TextStyle.FULL)
      *    QQQQQ   5      appendText(IsoFields.QUARTER_OF_YEAR, TextStyle.NARROW)
-     *    q       1      appendValue(IsoFields.QUARTER_OF_YEAR);
-     *    qq      2      appendValue(IsoFields.QUARTER_OF_YEAR, 2);
+     *    q       1      appendValue(IsoFields.QUARTER_OF_YEAR)
+     *    qq      2      appendValue(IsoFields.QUARTER_OF_YEAR, 2)
      *    qqq     3      appendText(IsoFields.QUARTER_OF_YEAR, TextStyle.SHORT_STANDALONE)
      *    qqqq    4      appendText(IsoFields.QUARTER_OF_YEAR, TextStyle.FULL_STANDALONE)
      *    qqqqq   5      appendText(IsoFields.QUARTER_OF_YEAR, TextStyle.NARROW_STANDALONE)
      *
-     *    M       1      appendValue(ChronoField.MONTH_OF_YEAR);
-     *    MM      2      appendValue(ChronoField.MONTH_OF_YEAR, 2);
+     *    M       1      appendValue(ChronoField.MONTH_OF_YEAR)
+     *    MM      2      appendValue(ChronoField.MONTH_OF_YEAR, 2)
      *    MMM     3      appendText(ChronoField.MONTH_OF_YEAR, TextStyle.SHORT)
      *    MMMM    4      appendText(ChronoField.MONTH_OF_YEAR, TextStyle.FULL)
      *    MMMMM   5      appendText(ChronoField.MONTH_OF_YEAR, TextStyle.NARROW)
-     *    L       1      appendValue(ChronoField.MONTH_OF_YEAR);
-     *    LL      2      appendValue(ChronoField.MONTH_OF_YEAR, 2);
+     *    L       1      appendValue(ChronoField.MONTH_OF_YEAR)
+     *    LL      2      appendValue(ChronoField.MONTH_OF_YEAR, 2)
      *    LLL     3      appendText(ChronoField.MONTH_OF_YEAR, TextStyle.SHORT_STANDALONE)
      *    LLLL    4      appendText(ChronoField.MONTH_OF_YEAR, TextStyle.FULL_STANDALONE)
      *    LLLLL   5      appendText(ChronoField.MONTH_OF_YEAR, TextStyle.NARROW_STANDALONE)
@@ -1481,6 +1491,7 @@
      *    DD      2      appendValue(ChronoField.DAY_OF_YEAR, 2)
      *    DDD     3      appendValue(ChronoField.DAY_OF_YEAR, 3)
      *    F       1      appendValue(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH)
+     *    g..g    1..n   appendValue(JulianFields.MODIFIED_JULIAN_DAY, n, 19, SignStyle.NORMAL)
      *    E       1      appendText(ChronoField.DAY_OF_WEEK, TextStyle.SHORT)
      *    EE      2      appendText(ChronoField.DAY_OF_WEEK, TextStyle.SHORT)
      *    EEE     3      appendText(ChronoField.DAY_OF_WEEK, TextStyle.SHORT)
@@ -1539,8 +1550,8 @@
      * <pre>
      *  Pattern  Count  Equivalent builder methods
      *  -------  -----  --------------------------
-     *    O       1      appendLocalizedOffsetPrefixed(TextStyle.SHORT);
-     *    OOOO    4      appendLocalizedOffsetPrefixed(TextStyle.FULL);
+     *    O       1      appendLocalizedOffset(TextStyle.SHORT)
+     *    OOOO    4      appendLocalizedOffset(TextStyle.FULL)
      *    X       1      appendOffset("+HHmm","Z")
      *    XX      2      appendOffset("+HHMM","Z")
      *    XXX     3      appendOffset("+HH:MM","Z")
@@ -1554,7 +1565,7 @@
      *    Z       1      appendOffset("+HHMM","+0000")
      *    ZZ      2      appendOffset("+HHMM","+0000")
      *    ZZZ     3      appendOffset("+HHMM","+0000")
-     *    ZZZZ    4      appendLocalizedOffset(TextStyle.FULL);
+     *    ZZZZ    4      appendLocalizedOffset(TextStyle.FULL)
      *    ZZZZZ   5      appendOffset("+HH:MM:ss","Z")
      * </pre>
      * <p>
@@ -1836,6 +1847,9 @@
                     throw new IllegalArgumentException("Too many pattern letters: " + cur);
                 }
                 break;
+            case 'g':
+                appendValue(field, count, 19, SignStyle.NORMAL);
+                break;
             default:
                 if (count == 1) {
                     appendValue(field);
@@ -1874,6 +1888,7 @@
         FIELD_MAP.put('A', ChronoField.MILLI_OF_DAY);              // LDML
         FIELD_MAP.put('n', ChronoField.NANO_OF_SECOND);            // 310 (proposed for LDML)
         FIELD_MAP.put('N', ChronoField.NANO_OF_DAY);               // 310 (proposed for LDML)
+        FIELD_MAP.put('g', JulianFields.MODIFIED_JULIAN_DAY);
         // 310 - z - time-zone names, matches LDML and SimpleDateFormat 1 to 4
         // 310 - Z - matches SimpleDateFormat and LDML
         // 310 - V - time-zone id, matches LDML
@@ -1884,7 +1899,6 @@
         // LDML - U - cycle year name, not supported by 310 yet
         // LDML - l - deprecated
         // LDML - j - not relevant
-        // LDML - g - modified-julian-day
         // LDML - v,V - extended time-zone names
     }
 
@@ -2919,11 +2933,8 @@
     /**
      * Prints and parses a numeric date-time field with optional padding.
      */
-    static final class FractionPrinterParser implements DateTimePrinterParser {
-        private final TemporalField field;
-        private final int minWidth;
-        private final int maxWidth;
-        private final boolean decimalPoint;
+    static final class FractionPrinterParser extends NumberPrinterParser {
+       private final boolean decimalPoint;
 
         /**
          * Constructor.
@@ -2934,6 +2945,7 @@
          * @param decimalPoint  whether to output the localized decimal point symbol
          */
         FractionPrinterParser(TemporalField field, int minWidth, int maxWidth, boolean decimalPoint) {
+            this(field, minWidth, maxWidth, decimalPoint, 0);
             Objects.requireNonNull(field, "field");
             if (field.range().isFixed() == false) {
                 throw new IllegalArgumentException("Field must have a fixed set of values: " + field);
@@ -2948,12 +2960,61 @@
                 throw new IllegalArgumentException("Maximum width must exceed or equal the minimum width but " +
                         maxWidth + " < " + minWidth);
             }
-            this.field = field;
-            this.minWidth = minWidth;
-            this.maxWidth = maxWidth;
+        }
+
+        /**
+         * Constructor.
+         *
+         * @param field  the field to output, not null
+         * @param minWidth  the minimum width to output, from 0 to 9
+         * @param maxWidth  the maximum width to output, from 0 to 9
+         * @param decimalPoint  whether to output the localized decimal point symbol
+         * @param subsequentWidth the subsequentWidth for this instance
+         */
+        FractionPrinterParser(TemporalField field, int minWidth, int maxWidth, boolean decimalPoint, int subsequentWidth) {
+            super(field, minWidth, maxWidth, SignStyle.NOT_NEGATIVE, subsequentWidth);
             this.decimalPoint = decimalPoint;
         }
 
+        /**
+         * Returns a new instance with fixed width flag set.
+         *
+         * @return a new updated printer-parser, not null
+         */
+        @Override
+        FractionPrinterParser withFixedWidth() {
+            if (subsequentWidth == -1) {
+                return this;
+            }
+            return new FractionPrinterParser(field, minWidth, maxWidth, decimalPoint, -1);
+        }
+
+        /**
+         * Returns a new instance with an updated subsequent width.
+         *
+         * @param subsequentWidth  the width of subsequent non-negative numbers, 0 or greater
+         * @return a new updated printer-parser, not null
+         */
+        @Override
+        FractionPrinterParser withSubsequentWidth(int subsequentWidth) {
+            return new FractionPrinterParser(field, minWidth, maxWidth, decimalPoint, this.subsequentWidth + subsequentWidth);
+        }
+
+        /**
+         * For FractionPrinterPrinterParser, the width is fixed if context is sttrict,
+         * minWidth equal to maxWidth and decimalpoint is absent.
+         * @param context the context
+         * @return if the field is fixed width
+         * @see DateTimeFormatterBuilder#appendValueFraction(java.time.temporal.TemporalField, int, int, boolean)
+         */
+        @Override
+        boolean isFixedWidth(DateTimeParseContext context) {
+            if (context.isStrict() && minWidth == maxWidth && decimalPoint == false) {
+                return true;
+            }
+            return false;
+        }
+
         @Override
         public boolean format(DateTimePrintContext context, StringBuilder buf) {
             Long value = context.getValue(field);
@@ -2986,8 +3047,8 @@
 
         @Override
         public int parse(DateTimeParseContext context, CharSequence text, int position) {
-            int effectiveMin = (context.isStrict() ? minWidth : 0);
-            int effectiveMax = (context.isStrict() ? maxWidth : 9);
+            int effectiveMin = (context.isStrict() || isFixedWidth(context) ? minWidth : 0);
+            int effectiveMax = (context.isStrict() || isFixedWidth(context) ? maxWidth : 9);
             int length = text.length();
             if (position == length) {
                 // valid if whole field is optional, invalid if minimum width
@@ -3519,9 +3580,7 @@
                 return false;
             }
             String gmtText = "GMT";  // TODO: get localized version of 'GMT'
-            if (gmtText != null) {
-                buf.append(gmtText);
-            }
+            buf.append(gmtText);
             int totalSecs = Math.toIntExact(offsetSecs);
             if (totalSecs != 0) {
                 int absHours = Math.abs((totalSecs / 3600) % 100);  // anything larger than 99 silently dropped
@@ -3565,14 +3624,12 @@
         @Override
         public int parse(DateTimeParseContext context, CharSequence text, int position) {
             int pos = position;
-            int end = pos + text.length();
+            int end = text.length();
             String gmtText = "GMT";  // TODO: get localized version of 'GMT'
-            if (gmtText != null) {
-                if (!context.subSequenceEquals(text, pos, gmtText, 0, gmtText.length())) {
+            if (!context.subSequenceEquals(text, pos, gmtText, 0, gmtText.length())) {
                     return ~position;
                 }
-                pos += gmtText.length();
-            }
+            pos += gmtText.length();
             // parse normal plus/minus offset
             int negative = 0;
             if (pos == end) {
--- a/jdk/src/java.base/share/classes/java/time/temporal/JulianFields.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/time/temporal/JulianFields.java	Wed Jul 05 21:37:42 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -117,7 +117,13 @@
      *
      * <h3>Astronomical and Scientific Notes</h3>
      * The standard astronomical definition uses a fraction to indicate the time-of-day,
-     * thus 3.25 would represent the time 18:00, since days start at midday.
+     * where each day is counted from midday to midday. For example,
+     * a fraction of 0 represents midday, a fraction of 0.25
+     * represents 18:00, a fraction of 0.5 represents midnight and a fraction
+     * of 0.75 represents 06:00.
+     * <p>
+     * By contrast, this implementation has no fractional part, and counts
+     * days from midnight to midnight.
      * This implementation uses an integer and days starting at midnight.
      * The integer value for the Julian Day Number is the astronomical Julian Day value at midday
      * of the date in question.
--- a/jdk/src/java.base/share/classes/java/util/Locale.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/util/Locale.java	Wed Jul 05 21:37:42 2017 +0200
@@ -45,7 +45,6 @@
 import java.io.ObjectOutputStream;
 import java.io.ObjectStreamField;
 import java.io.Serializable;
-import java.security.AccessController;
 import java.text.MessageFormat;
 import java.util.spi.LocaleNameProvider;
 
@@ -859,11 +858,10 @@
 
     private static Locale initDefault() {
         String language, region, script, country, variant;
-        language = AccessController.doPrivileged(
-            new GetPropertyAction("user.language", "en"));
+        Properties props = GetPropertyAction.getProperties();
+        language = props.getProperty("user.language", "en");
         // for compatibility, check for old user.region property
-        region = AccessController.doPrivileged(
-            new GetPropertyAction("user.region"));
+        region = props.getProperty("user.region");
         if (region != null) {
             // region can be of form country, country_variant, or _variant
             int i = region.indexOf('_');
@@ -876,27 +874,25 @@
             }
             script = "";
         } else {
-            script = AccessController.doPrivileged(
-                new GetPropertyAction("user.script", ""));
-            country = AccessController.doPrivileged(
-                new GetPropertyAction("user.country", ""));
-            variant = AccessController.doPrivileged(
-                new GetPropertyAction("user.variant", ""));
+            script = props.getProperty("user.script", "");
+            country = props.getProperty("user.country", "");
+            variant = props.getProperty("user.variant", "");
         }
 
         return getInstance(language, script, country, variant, null);
     }
 
     private static Locale initDefault(Locale.Category category) {
+        Properties props = GetPropertyAction.getProperties();
         return getInstance(
-            AccessController.doPrivileged(
-                new GetPropertyAction(category.languageKey, defaultLocale.getLanguage())),
-            AccessController.doPrivileged(
-                new GetPropertyAction(category.scriptKey, defaultLocale.getScript())),
-            AccessController.doPrivileged(
-                new GetPropertyAction(category.countryKey, defaultLocale.getCountry())),
-            AccessController.doPrivileged(
-                new GetPropertyAction(category.variantKey, defaultLocale.getVariant())),
+            props.getProperty(category.languageKey,
+                    defaultLocale.getLanguage()),
+            props.getProperty(category.scriptKey,
+                    defaultLocale.getScript()),
+            props.getProperty(category.countryKey,
+                    defaultLocale.getCountry()),
+            props.getProperty(category.variantKey,
+                    defaultLocale.getVariant()),
             null);
     }
 
--- a/jdk/src/java.base/share/classes/java/util/PropertyResourceBundle.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/util/PropertyResourceBundle.java	Wed Jul 05 21:37:42 2017 +0200
@@ -43,7 +43,6 @@
 import java.io.InputStreamReader;
 import java.io.Reader;
 import java.io.IOException;
-import java.nio.charset.Charset;
 import java.nio.charset.MalformedInputException;
 import java.nio.charset.StandardCharsets;
 import java.nio.charset.UnmappableCharacterException;
@@ -142,8 +141,8 @@
     // Check whether the strict encoding is specified.
     // The possible encoding is either "ISO-8859-1" or "UTF-8".
     private static final String encoding =
-        AccessController.doPrivileged(
-            new GetPropertyAction("java.util.PropertyResourceBundle.encoding", ""))
+        GetPropertyAction
+                .getProperty("java.util.PropertyResourceBundle.encoding", "")
         .toUpperCase(Locale.ROOT);
 
     /**
--- a/jdk/src/java.base/share/classes/java/util/TimeZone.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/util/TimeZone.java	Wed Jul 05 21:37:42 2017 +0200
@@ -660,14 +660,12 @@
     private static synchronized TimeZone setDefaultZone() {
         TimeZone tz;
         // get the time zone ID from the system properties
-        String zoneID = AccessController.doPrivileged(
-                new GetPropertyAction("user.timezone"));
+        String zoneID = GetPropertyAction.getProperty("user.timezone");
 
         // if the time zone ID is not set (yet), perform the
         // platform to Java time zone ID mapping.
         if (zoneID == null || zoneID.isEmpty()) {
-            String javaHome = AccessController.doPrivileged(
-                    new GetPropertyAction("java.home"));
+            String javaHome = GetPropertyAction.getProperty("java.home");
             try {
                 zoneID = getSystemTimeZoneID(javaHome);
                 if (zoneID == null) {
--- a/jdk/src/java.base/share/classes/java/util/concurrent/ThreadLocalRandom.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/ThreadLocalRandom.java	Wed Jul 05 21:37:42 2017 +0200
@@ -455,7 +455,7 @@
             s = v1 * v1 + v2 * v2;
         } while (s >= 1 || s == 0);
         double multiplier = StrictMath.sqrt(-2 * StrictMath.log(s)/s);
-        nextLocalGaussian.set(new Double(v2 * multiplier));
+        nextLocalGaussian.set(Double.valueOf(v2 * multiplier));
         return v1 * multiplier;
     }
 
--- a/jdk/src/java.base/share/classes/java/util/jar/JarFile.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/util/jar/JarFile.java	Wed Jul 05 21:37:42 2017 +0200
@@ -34,7 +34,6 @@
 import java.util.zip.*;
 import java.security.CodeSigner;
 import java.security.cert.Certificate;
-import java.security.AccessController;
 import java.security.CodeSource;
 import jdk.internal.misc.SharedSecrets;
 import sun.security.action.GetPropertyAction;
@@ -155,16 +154,16 @@
 
         BASE_VERSION = 8;  // one less than lowest version for versioned entries
         int runtimeVersion = jdk.Version.current().major();
-        String jarVersion = AccessController.doPrivileged(
-                new GetPropertyAction("jdk.util.jar.version"));
+        String jarVersion =
+                GetPropertyAction.getProperty("jdk.util.jar.version");
         if (jarVersion != null) {
             int jarVer = Integer.parseInt(jarVersion);
             runtimeVersion = (jarVer > runtimeVersion)
                     ? runtimeVersion : Math.max(jarVer, 0);
         }
         RUNTIME_VERSION = runtimeVersion;
-        String enableMultiRelease = AccessController.doPrivileged(
-                new GetPropertyAction("jdk.util.jar.enableMultiRelease", "true"));
+        String enableMultiRelease = GetPropertyAction
+                .getProperty("jdk.util.jar.enableMultiRelease", "true");
         switch (enableMultiRelease) {
             case "true":
             default:
--- a/jdk/src/java.base/share/classes/java/util/jar/Pack200.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/util/jar/Pack200.java	Wed Jul 05 21:37:42 2017 +0200
@@ -29,6 +29,7 @@
 import java.io.OutputStream;
 import java.io.File;
 import java.io.IOException;
+import sun.security.action.GetPropertyAction;
 
 
 /**
@@ -694,8 +695,7 @@
             Class<?> impl = (PACK_PROVIDER.equals(prop))? packerImpl: unpackerImpl;
             if (impl == null) {
                 // The first time, we must decide which class to use.
-                implName = java.security.AccessController.doPrivileged(
-                    new sun.security.action.GetPropertyAction(prop,""));
+                implName = GetPropertyAction.getProperty(prop,"");
                 if (implName != null && !implName.equals(""))
                     impl = Class.forName(implName);
                 else if (PACK_PROVIDER.equals(prop))
--- a/jdk/src/java.base/share/classes/java/util/regex/PatternSyntaxException.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/util/regex/PatternSyntaxException.java	Wed Jul 05 21:37:42 2017 +0200
@@ -94,8 +94,7 @@
     }
 
     private static final String nl =
-        java.security.AccessController
-            .doPrivileged(new GetPropertyAction("line.separator"));
+            GetPropertyAction.getProperty("line.separator");
 
     /**
      * Returns a multi-line string containing the description of the syntax
--- a/jdk/src/java.base/share/classes/java/util/zip/ZipOutputStream.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/util/zip/ZipOutputStream.java	Wed Jul 05 21:37:42 2017 +0200
@@ -33,6 +33,7 @@
 import java.util.HashSet;
 import static java.util.zip.ZipConstants64.*;
 import static java.util.zip.ZipUtils.*;
+import sun.security.action.GetPropertyAction;
 
 /**
  * This class implements an output stream filter for writing files in the
@@ -54,9 +55,7 @@
      */
     private static final boolean inhibitZip64 =
         Boolean.parseBoolean(
-            java.security.AccessController.doPrivileged(
-                new sun.security.action.GetPropertyAction(
-                    "jdk.util.zip.inhibitZip64", "false")));
+            GetPropertyAction.getProperty("jdk.util.zip.inhibitZip64"));
 
     private static class XEntry {
         final ZipEntry entry;
--- a/jdk/src/java.base/share/classes/javax/net/ssl/SSLSocketFactory.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/javax/net/ssl/SSLSocketFactory.java	Wed Jul 05 21:37:42 2017 +0200
@@ -51,9 +51,9 @@
     static final boolean DEBUG;
 
     static {
-        String s = java.security.AccessController.doPrivileged(
-            new GetPropertyAction("javax.net.debug", "")).toLowerCase(
-                                                            Locale.ENGLISH);
+        String s = GetPropertyAction.getProperty("javax.net.debug", "")
+                .toLowerCase(Locale.ENGLISH);
+
         DEBUG = s.contains("all") || s.contains("ssl");
     }
 
--- a/jdk/src/java.base/share/classes/jdk/Version.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/jdk/Version.java	Wed Jul 05 21:37:42 2017 +0200
@@ -26,8 +26,6 @@
 package jdk;
 
 import java.math.BigInteger;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
 import java.util.ArrayList;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -35,6 +33,7 @@
 import java.util.Collections;
 import java.util.List;
 import java.util.Optional;
+import sun.security.action.GetPropertyAction;
 
 /**
  * A representation of the JDK version-string which contains a version
@@ -274,12 +273,7 @@
      */
     public static Version current() {
         if (current == null) {
-            current = parse(AccessController.doPrivileged(
-                new PrivilegedAction<>() {
-                    public String run() {
-                        return System.getProperty("java.version");
-                    }
-                }));
+            current = parse(GetPropertyAction.getProperty("java.version"));
         }
         return current;
     }
--- a/jdk/src/java.base/share/classes/jdk/internal/jimage/BasicImageReader.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/jdk/internal/jimage/BasicImageReader.java	Wed Jul 05 21:37:42 2017 +0200
@@ -183,7 +183,9 @@
     }
 
     public static void releaseByteBuffer(ByteBuffer buffer) {
-        ImageBufferCache.releaseBuffer(buffer);
+        if (!MAP_ALL) {
+            ImageBufferCache.releaseBuffer(buffer);
+        }
     }
 
     public String getName() {
--- a/jdk/src/java.base/share/classes/jdk/internal/jimage/ImageReader.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/jdk/internal/jimage/ImageReader.java	Wed Jul 05 21:37:42 2017 +0200
@@ -25,6 +25,7 @@
 package jdk.internal.jimage;
 
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.UncheckedIOException;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
@@ -36,8 +37,11 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Objects;
+import java.util.Set;
 import java.util.function.Consumer;
 
 /**
@@ -47,80 +51,486 @@
  * but also compiled and delivered as part of the jrtfs.jar to support access
  * to the jimage file provided by the shipped JDK by tools running on JDK 8.
  */
-public class ImageReader extends BasicImageReader {
-
-    private static final int SIZE_OF_OFFSET = 4;
-
-    // Map of files opened as LITTLE_ENDIAN
-    private static final HashMap<Path, ImageReader> OPEN_LE_FILES
-            = new HashMap<>();
-
-    // Map of files opened as BIG_ENDIAN
-    private static final HashMap<Path, ImageReader> OPEN_BE_FILES
-            = new HashMap<>();
-
-    private int openCount;
+public final class ImageReader implements AutoCloseable {
+    private SharedImageReader reader;
 
-    // attributes of the .jimage file. jimage file does not contain
-    // attributes for the individual resources (yet). We use attributes
-    // of the jimage file itself (creation, modification, access times).
-    // Iniitalized lazily, see {@link #imageFileAttributes()}.
-    private BasicFileAttributes imageFileAttributes;
-
-    // directory management implementation
-    private final HashMap<String, Node> nodes;
-    private volatile Directory rootDir;
-
-    private Directory packagesDir;
-    private Directory modulesDir;
-
-    private ImageReader(Path imagePath, ByteOrder byteOrder) throws IOException {
-        super(imagePath, byteOrder);
-        this.nodes = new HashMap<>();
+    private ImageReader(SharedImageReader reader) {
+        this.reader = reader;
     }
 
     public static ImageReader open(Path imagePath, ByteOrder byteOrder) throws IOException {
-        HashMap<Path, ImageReader> openFiles = getOpenFilesMap(byteOrder);
-        ImageReader reader;
-        synchronized (openFiles) {
-            reader = openFiles.get(imagePath);
-            if (reader == null) {
-                reader = new ImageReader(imagePath, byteOrder);
-                ImageReader existingReader = openFiles.putIfAbsent(imagePath, reader);
-                assert (existingReader == null);
-            }
-            reader.openCount++;
-        }
-        return reader;
+        return SharedImageReader.open(imagePath, byteOrder);
     }
 
-    private static HashMap<Path, ImageReader> getOpenFilesMap(ByteOrder byteOrder) {
-        return (byteOrder == ByteOrder.BIG_ENDIAN) ? OPEN_BE_FILES : OPEN_LE_FILES;
-    }
-
-    /**
-     * Opens the given file path as an image file, returning an {@code ImageReader}.
-     */
     public static ImageReader open(Path imagePath) throws IOException {
         return open(imagePath, ByteOrder.nativeOrder());
     }
 
-    private boolean canClose() {
-        HashMap<Path, ImageReader> openFiles = getOpenFilesMap(this.getByteOrder());
-        synchronized (openFiles) {
-            if (--this.openCount == 0) {
-                return openFiles.remove(this.getName(), this);
+    @Override
+    public void close() throws IOException {
+        if (reader == null) {
+            throw new IOException("image file already closed");
+        }
+
+        reader.close(this);
+        reader = null;
+    }
+
+    // directory management interface
+    public Directory getRootDirectory() throws IOException {
+        if (reader == null) {
+            throw new IOException("image file closed");
+        }
+        return reader.getRootDirectory();
+    }
+
+    public Node findNode(String name) throws IOException {
+        if (reader == null) {
+            throw new IOException("image file closed");
+        }
+        return reader.findNode(name);
+    }
+
+    public byte[] getResource(Node node) throws IOException {
+        if (reader == null) {
+            throw new IOException("image file closed");
+        }
+        return reader.getResource(node);
+    }
+
+    public byte[] getResource(Resource rs) throws IOException {
+        if (reader == null) {
+            throw new IOException("image file closed");
+        }
+        return reader.getResource(rs);
+    }
+
+    public ImageHeader getHeader() {
+        Objects.requireNonNull(reader, "image file closed");
+        return reader.getHeader();
+    }
+
+    public static void releaseByteBuffer(ByteBuffer buffer) {
+        BasicImageReader.releaseByteBuffer(buffer);
+    }
+
+    public String getName() {
+        Objects.requireNonNull(reader, "image file closed");
+        return reader.getName() ;
+    }
+
+    public ByteOrder getByteOrder() {
+        Objects.requireNonNull(reader, "image file closed");
+        return reader.getByteOrder();
+    }
+
+    public Path getImagePath() {
+        Objects.requireNonNull(reader, "image file closed");
+        return reader.getImagePath();
+    }
+
+    public ImageStringsReader getStrings() {
+        Objects.requireNonNull(reader, "image file closed");
+        return reader.getStrings();
+    }
+
+    public ImageLocation findLocation(String mn, String rn) {
+        Objects.requireNonNull(reader, "image file closed");
+        return reader.findLocation(mn, rn);
+    }
+
+    public ImageLocation findLocation(String name) {
+        Objects.requireNonNull(reader, "image file closed");
+        return reader.findLocation(name);
+    }
+
+    public String[] getEntryNames() {
+        Objects.requireNonNull(reader, "image file closed");
+        return reader.getEntryNames();
+    }
+
+    public long[] getAttributes(int offset) {
+        Objects.requireNonNull(reader, "image file closed");
+        return reader.getAttributes(offset);
+    }
+
+    public String getString(int offset) {
+        Objects.requireNonNull(reader, "image file closed");
+        return reader.getString(offset);
+    }
+
+    public byte[] getResource(String name) {
+        Objects.requireNonNull(reader, "image file closed");
+        return reader.getResource(name);
+    }
+
+    public byte[] getResource(ImageLocation loc) {
+        Objects.requireNonNull(reader, "image file closed");
+        return reader.getResource(loc);
+    }
+
+    public ByteBuffer getResourceBuffer(ImageLocation loc) {
+        Objects.requireNonNull(reader, "image file closed");
+        return reader.getResourceBuffer(loc);
+    }
+
+    public InputStream getResourceStream(ImageLocation loc) {
+        Objects.requireNonNull(reader, "image file closed");
+        return reader.getResourceStream(loc);
+    }
+
+    private final static class SharedImageReader extends BasicImageReader {
+        static final int SIZE_OF_OFFSET = Integer.BYTES;
+
+        static final Map<Path, SharedImageReader> OPEN_FILES = new HashMap<>();
+
+        // List of openers for this shared image.
+        final Set<ImageReader> openers;
+
+        // attributes of the .jimage file. jimage file does not contain
+        // attributes for the individual resources (yet). We use attributes
+        // of the jimage file itself (creation, modification, access times).
+        // Iniitalized lazily, see {@link #imageFileAttributes()}.
+        BasicFileAttributes imageFileAttributes;
+
+        // directory management implementation
+        final HashMap<String, Node> nodes;
+        volatile Directory rootDir;
+
+        Directory packagesDir;
+        Directory modulesDir;
+
+        private SharedImageReader(Path imagePath, ByteOrder byteOrder) throws IOException {
+            super(imagePath, byteOrder);
+            this.openers = new HashSet<>();
+            this.nodes = new HashMap<>();
+        }
+
+        public static ImageReader open(Path imagePath, ByteOrder byteOrder) throws IOException {
+            synchronized (OPEN_FILES) {
+                SharedImageReader reader = OPEN_FILES.get(imagePath);
+
+                if (reader == null) {
+                    // Will fail with an IOException if wrong byteOrder.
+                    reader =  new SharedImageReader(imagePath, byteOrder);
+                    OPEN_FILES.put(imagePath, reader);
+                } else if (reader.getByteOrder() != byteOrder) {
+                    throw new IOException("\"" + reader.getName() + "\" is not an image file");
+                }
+
+                ImageReader image = new ImageReader(reader);
+                reader.openers.add(image);
+
+                return image;
+            }
+        }
+
+        public void close(ImageReader image) throws IOException {
+            synchronized (OPEN_FILES) {
+                if (!openers.remove(image)) {
+                    throw new IOException("image file already closed");
+                }
+
+                if (openers.isEmpty()) {
+                    close();
+                    nodes.clear();
+                    rootDir = null;
+
+                    if (!OPEN_FILES.remove(this.getImagePath(), this)) {
+                        throw new IOException("image file not found in open list");
+                    }
+                }
+            }
+        }
+
+        void addOpener(ImageReader reader) {
+            synchronized (OPEN_FILES) {
+                openers.add(reader);
+            }
+        }
+
+        boolean removeOpener(ImageReader reader) {
+            synchronized (OPEN_FILES) {
+                return openers.remove(reader);
             }
         }
-        return false;
-    }
+
+        // directory management interface
+        Directory getRootDirectory() {
+            return buildRootDirectory();
+        }
+
+        /**
+         * Lazily build a node from a name.
+        */
+        synchronized Node buildNode(String name) {
+            Node n;
+            boolean isPackages = name.startsWith("/packages");
+            boolean isModules = !isPackages && name.startsWith("/modules");
+
+            if (!(isModules || isPackages)) {
+                return null;
+            }
+
+            ImageLocation loc = findLocation(name);
+
+            if (loc != null) { // A sub tree node
+                if (isPackages) {
+                    n = handlePackages(name, loc);
+                } else { // modules sub tree
+                    n = handleModulesSubTree(name, loc);
+                }
+            } else { // Asking for a resource? /modules/java.base/java/lang/Object.class
+                if (isModules) {
+                    n = handleResource(name);
+                } else {
+                    // Possibly ask for /packages/java.lang/java.base
+                    // although /packages/java.base not created
+                    n = handleModuleLink(name);
+                }
+            }
+            return n;
+        }
+
+        synchronized Directory buildRootDirectory() {
+            Directory root = rootDir; // volatile read
+            if (root != null) {
+                return root;
+            }
+
+            root = newDirectory(null, "/");
+            root.setIsRootDir();
+
+            // /packages dir
+            packagesDir = newDirectory(root, "/packages");
+            packagesDir.setIsPackagesDir();
+
+            // /modules dir
+            modulesDir = newDirectory(root, "/modules");
+            modulesDir.setIsModulesDir();
+
+            root.setCompleted(true);
+            return rootDir = root;
+        }
+
+        /**
+         * To visit sub tree resources.
+         */
+        interface LocationVisitor {
+            void visit(ImageLocation loc);
+        }
+
+        void visitLocation(ImageLocation loc, LocationVisitor visitor) {
+            byte[] offsets = getResource(loc);
+            ByteBuffer buffer = ByteBuffer.wrap(offsets);
+            buffer.order(getByteOrder());
+            IntBuffer intBuffer = buffer.asIntBuffer();
+            for (int i = 0; i < offsets.length / SIZE_OF_OFFSET; i++) {
+                int offset = intBuffer.get(i);
+                ImageLocation pkgLoc = getLocation(offset);
+                visitor.visit(pkgLoc);
+            }
+        }
+
+        void visitPackageLocation(ImageLocation loc) {
+            // Retrieve package name
+            String pkgName = getBaseExt(loc);
+            // Content is array of offsets in Strings table
+            byte[] stringsOffsets = getResource(loc);
+            ByteBuffer buffer = ByteBuffer.wrap(stringsOffsets);
+            buffer.order(getByteOrder());
+            IntBuffer intBuffer = buffer.asIntBuffer();
+            // For each module, create a link node.
+            for (int i = 0; i < stringsOffsets.length / SIZE_OF_OFFSET; i++) {
+                // skip empty state, useless.
+                intBuffer.get(i);
+                i++;
+                int offset = intBuffer.get(i);
+                String moduleName = getString(offset);
+                Node targetNode = findNode("/modules/" + moduleName);
+                if (targetNode != null) {
+                    String pkgDirName = packagesDir.getName() + "/" + pkgName;
+                    Directory pkgDir = (Directory) nodes.get(pkgDirName);
+                    newLinkNode(pkgDir, pkgDir.getName() + "/" + moduleName, targetNode);
+                }
+            }
+        }
+
+        Node handlePackages(String name, ImageLocation loc) {
+            long size = loc.getUncompressedSize();
+            Node n = null;
+            // Only possiblities are /packages, /packages/package/module
+            if (name.equals("/packages")) {
+                visitLocation(loc, (childloc) -> {
+                    findNode(childloc.getFullName());
+                });
+                packagesDir.setCompleted(true);
+                n = packagesDir;
+            } else {
+                if (size != 0) { // children are offsets to module in StringsTable
+                    String pkgName = getBaseExt(loc);
+                    Directory pkgDir = newDirectory(packagesDir, packagesDir.getName() + "/" + pkgName);
+                    visitPackageLocation(loc);
+                    pkgDir.setCompleted(true);
+                    n = pkgDir;
+                } else { // Link to module
+                    String pkgName = loc.getParent();
+                    String modName = getBaseExt(loc);
+                    Node targetNode = findNode("/modules/" + modName);
+                    if (targetNode != null) {
+                        String pkgDirName = packagesDir.getName() + "/" + pkgName;
+                        Directory pkgDir = (Directory) nodes.get(pkgDirName);
+                        Node linkNode = newLinkNode(pkgDir, pkgDir.getName() + "/" + modName, targetNode);
+                        n = linkNode;
+                    }
+                }
+            }
+            return n;
+        }
 
-    @Override
-    public void close() throws IOException {
-        if (canClose()) {
-            super.close();
-            clearNodes();
-       }
+        // Asking for /packages/package/module although
+        // /packages/<pkg>/ not yet created, need to create it
+        // prior to return the link to module node.
+        Node handleModuleLink(String name) {
+            // eg: unresolved /packages/package/module
+            // Build /packages/package node
+            Node ret = null;
+            String radical = "/packages/";
+            String path = name;
+            if (path.startsWith(radical)) {
+                int start = radical.length();
+                int pkgEnd = path.indexOf('/', start);
+                if (pkgEnd != -1) {
+                    String pkg = path.substring(start, pkgEnd);
+                    String pkgPath = radical + pkg;
+                    Node n = findNode(pkgPath);
+                    // If not found means that this is a symbolic link such as:
+                    // /packages/java.util/java.base/java/util/Vector.class
+                    // and will be done by a retry of the filesystem
+                    for (Node child : n.getChildren()) {
+                        if (child.name.equals(name)) {
+                            ret = child;
+                            break;
+                        }
+                    }
+                }
+            }
+            return ret;
+        }
+
+        Node handleModulesSubTree(String name, ImageLocation loc) {
+            Node n;
+            assert (name.equals(loc.getFullName()));
+            Directory dir = makeDirectories(name);
+            visitLocation(loc, (childloc) -> {
+                String path = childloc.getFullName();
+                if (path.startsWith("/modules")) { // a package
+                    makeDirectories(path);
+                } else { // a resource
+                    makeDirectories(childloc.buildName(true, true, false));
+                    newResource(dir, childloc);
+                }
+            });
+            dir.setCompleted(true);
+            n = dir;
+            return n;
+        }
+
+        Node handleResource(String name) {
+            Node n = null;
+            String locationPath = name.substring("/modules".length());
+            ImageLocation resourceLoc = findLocation(locationPath);
+            if (resourceLoc != null) {
+                Directory dir = makeDirectories(resourceLoc.buildName(true, true, false));
+                Resource res = newResource(dir, resourceLoc);
+                n = res;
+            }
+            return n;
+        }
+
+        String getBaseExt(ImageLocation loc) {
+            String base = loc.getBase();
+            String ext = loc.getExtension();
+            if (ext != null && !ext.isEmpty()) {
+                base = base + "." + ext;
+            }
+            return base;
+        }
+
+        synchronized Node findNode(String name) {
+            buildRootDirectory();
+            Node n = nodes.get(name);
+            if (n == null || !n.isCompleted()) {
+                n = buildNode(name);
+            }
+            return n;
+        }
+
+        /**
+         * Returns the file attributes of the image file.
+         */
+        BasicFileAttributes imageFileAttributes() {
+            BasicFileAttributes attrs = imageFileAttributes;
+            if (attrs == null) {
+                try {
+                    Path file = getImagePath();
+                    attrs = Files.readAttributes(file, BasicFileAttributes.class);
+                } catch (IOException ioe) {
+                    throw new UncheckedIOException(ioe);
+                }
+                imageFileAttributes = attrs;
+            }
+            return attrs;
+        }
+
+        Directory newDirectory(Directory parent, String name) {
+            Directory dir = Directory.create(parent, name, imageFileAttributes());
+            nodes.put(dir.getName(), dir);
+            return dir;
+        }
+
+        Resource newResource(Directory parent, ImageLocation loc) {
+            Resource res = Resource.create(parent, loc, imageFileAttributes());
+            nodes.put(res.getName(), res);
+            return res;
+        }
+
+        LinkNode newLinkNode(Directory dir, String name, Node link) {
+            LinkNode linkNode = LinkNode.create(dir, name, link);
+            nodes.put(linkNode.getName(), linkNode);
+            return linkNode;
+        }
+
+        Directory makeDirectories(String parent) {
+            Directory last = rootDir;
+            for (int offset = parent.indexOf('/', 1);
+                    offset != -1;
+                    offset = parent.indexOf('/', offset + 1)) {
+                String dir = parent.substring(0, offset);
+                last = makeDirectory(dir, last);
+            }
+            return makeDirectory(parent, last);
+
+        }
+
+        Directory makeDirectory(String dir, Directory last) {
+            Directory nextDir = (Directory) nodes.get(dir);
+            if (nextDir == null) {
+                nextDir = newDirectory(last, dir);
+            }
+            return nextDir;
+        }
+
+        byte[] getResource(Node node) throws IOException {
+            if (node.isResource()) {
+                return super.getResource(node.getLocation());
+            }
+            throw new IOException("Not a resource: " + node);
+        }
+
+        byte[] getResource(Resource rs) throws IOException {
+            return super.getResource(rs.getLocation());
+        }
     }
 
     // jimage file does not store directory structure. We build nodes
@@ -389,7 +799,7 @@
 
         @Override
         public Node resolveLink(boolean recursive) {
-            return recursive && (link instanceof LinkNode)? ((LinkNode)link).resolveLink(true) : link;
+            return (recursive && link instanceof LinkNode) ? ((LinkNode)link).resolveLink(true) : link;
         }
 
         @Override
@@ -397,297 +807,4 @@
             return true;
         }
     }
-
-    // directory management interface
-    public Directory getRootDirectory() {
-        return buildRootDirectory();
-    }
-
-    /**
-     * To visit sub tree resources.
-     */
-    interface LocationVisitor {
-
-        void visit(ImageLocation loc);
-    }
-
-    /**
-     * Lazily build a node from a name.
-    */
-    private Node buildNode(String name) {
-        Node n;
-        boolean isPackages = name.startsWith("/packages");
-        boolean isModules = !isPackages && name.startsWith("/modules");
-
-        if (!(isModules || isPackages)) {
-            return null;
-        }
-
-        ImageLocation loc = findLocation(name);
-
-        if (loc != null) { // A sub tree node
-            if (isPackages) {
-                n = handlePackages(name, loc);
-            } else { // modules sub tree
-                n = handleModulesSubTree(name, loc);
-            }
-        } else { // Asking for a resource? /modules/java.base/java/lang/Object.class
-            if (isModules) {
-                n = handleResource(name);
-            } else {
-                // Possibly ask for /packages/java.lang/java.base
-                // although /packages/java.base not created
-                n = handleModuleLink(name);
-            }
-        }
-        return n;
-    }
-
-    private void visitLocation(ImageLocation loc, LocationVisitor visitor) {
-        byte[] offsets = getResource(loc);
-        ByteBuffer buffer = ByteBuffer.wrap(offsets);
-        buffer.order(getByteOrder());
-        IntBuffer intBuffer = buffer.asIntBuffer();
-        for (int i = 0; i < offsets.length / SIZE_OF_OFFSET; i++) {
-            int offset = intBuffer.get(i);
-            ImageLocation pkgLoc = getLocation(offset);
-            visitor.visit(pkgLoc);
-        }
-    }
-
-    private void visitPackageLocation(ImageLocation loc) {
-        // Retrieve package name
-        String pkgName = getBaseExt(loc);
-        // Content is array of offsets in Strings table
-        byte[] stringsOffsets = getResource(loc);
-        ByteBuffer buffer = ByteBuffer.wrap(stringsOffsets);
-        buffer.order(getByteOrder());
-        IntBuffer intBuffer = buffer.asIntBuffer();
-        // For each module, create a link node.
-        for (int i = 0; i < stringsOffsets.length / SIZE_OF_OFFSET; i++) {
-            // skip empty state, useless.
-            intBuffer.get(i);
-            i++;
-            int offset = intBuffer.get(i);
-            String moduleName = getString(offset);
-            Node targetNode = findNode("/modules/" + moduleName);
-            if (targetNode != null) {
-                String pkgDirName = packagesDir.getName() + "/" + pkgName;
-                Directory pkgDir = (Directory) nodes.get(pkgDirName);
-                newLinkNode(pkgDir, pkgDir.getName() + "/" + moduleName, targetNode);
-            }
-        }
-    }
-
-    private Node handlePackages(String name, ImageLocation loc) {
-        long size = loc.getUncompressedSize();
-        Node n = null;
-        // Only possiblities are /packages, /packages/package/module
-        if (name.equals("/packages")) {
-            visitLocation(loc, (childloc) -> {
-                findNode(childloc.getFullName());
-            });
-            packagesDir.setCompleted(true);
-            n = packagesDir;
-        } else {
-            if (size != 0) { // children are offsets to module in StringsTable
-                String pkgName = getBaseExt(loc);
-                Directory pkgDir = newDirectory(packagesDir, packagesDir.getName() + "/" + pkgName);
-                visitPackageLocation(loc);
-                pkgDir.setCompleted(true);
-                n = pkgDir;
-            } else { // Link to module
-                String pkgName = loc.getParent();
-                String modName = getBaseExt(loc);
-                Node targetNode = findNode("/modules/" + modName);
-                if (targetNode != null) {
-                    String pkgDirName = packagesDir.getName() + "/" + pkgName;
-                    Directory pkgDir = (Directory) nodes.get(pkgDirName);
-                    Node linkNode = newLinkNode(pkgDir, pkgDir.getName() + "/" + modName, targetNode);
-                    n = linkNode;
-                }
-            }
-        }
-        return n;
-    }
-
-    // Asking for /packages/package/module although
-    // /packages/<pkg>/ not yet created, need to create it
-    // prior to return the link to module node.
-    private Node handleModuleLink(String name) {
-        // eg: unresolved /packages/package/module
-        // Build /packages/package node
-        Node ret = null;
-        String radical = "/packages/";
-        String path = name;
-        if (path.startsWith(radical)) {
-            int start = radical.length();
-            int pkgEnd = path.indexOf('/', start);
-            if (pkgEnd != -1) {
-                String pkg = path.substring(start, pkgEnd);
-                String pkgPath = radical + pkg;
-                Node n = findNode(pkgPath);
-                // If not found means that this is a symbolic link such as:
-                // /packages/java.util/java.base/java/util/Vector.class
-                // and will be done by a retry of the filesystem
-                for (Node child : n.getChildren()) {
-                    if (child.name.equals(name)) {
-                        ret = child;
-                        break;
-                    }
-                }
-            }
-        }
-        return ret;
-    }
-
-    private Node handleModulesSubTree(String name, ImageLocation loc) {
-        Node n;
-        assert (name.equals(loc.getFullName()));
-        Directory dir = makeDirectories(name);
-        visitLocation(loc, (childloc) -> {
-            String path = childloc.getFullName();
-            if (path.startsWith("/modules")) { // a package
-                makeDirectories(path);
-            } else { // a resource
-                makeDirectories(childloc.buildName(true, true, false));
-                newResource(dir, childloc);
-            }
-        });
-        dir.setCompleted(true);
-        n = dir;
-        return n;
-    }
-
-    private Node handleResource(String name) {
-        Node n = null;
-        String locationPath = name.substring("/modules".length());
-        ImageLocation resourceLoc = findLocation(locationPath);
-        if (resourceLoc != null) {
-            Directory dir = makeDirectories(resourceLoc.buildName(true, true, false));
-            Resource res = newResource(dir, resourceLoc);
-            n = res;
-        }
-        return n;
-    }
-
-    private String getBaseExt(ImageLocation loc) {
-        String base = loc.getBase();
-        String ext = loc.getExtension();
-        if (ext != null && !ext.isEmpty()) {
-            base = base + "." + ext;
-        }
-        return base;
-    }
-
-    public synchronized Node findNode(String name) {
-        buildRootDirectory();
-        Node n = nodes.get(name);
-        if (n == null || !n.isCompleted()) {
-            n = buildNode(name);
-        }
-        return n;
-    }
-
-    private synchronized void clearNodes() {
-        nodes.clear();
-        rootDir = null;
-    }
-
-    /**
-     * Returns the file attributes of the image file.
-     */
-    private BasicFileAttributes imageFileAttributes() {
-        BasicFileAttributes attrs = imageFileAttributes;
-        if (attrs == null) {
-            try {
-                Path file = getImagePath();
-                attrs = Files.readAttributes(file, BasicFileAttributes.class);
-            } catch (IOException ioe) {
-                throw new UncheckedIOException(ioe);
-            }
-            imageFileAttributes = attrs;
-        }
-        return attrs;
-    }
-
-    private Directory buildRootDirectory() {
-        Directory root = rootDir; // volatile read
-        if (root != null) {
-            return root;
-        }
-
-        synchronized (this) {
-            root = rootDir;
-            if (root != null) {
-                return root;
-            }
-
-            // FIXME no time information per resource in jimage file (yet?)
-            // we use file attributes of jimage itself.
-            // root directory
-            root = newDirectory(null, "/");
-            root.setIsRootDir();
-
-            // /packages dir
-            packagesDir = newDirectory(root, "/packages");
-            packagesDir.setIsPackagesDir();
-
-            // /modules dir
-            modulesDir = newDirectory(root, "/modules");
-            modulesDir.setIsModulesDir();
-
-            root.setCompleted(true);
-            return rootDir = root;
-        }
-    }
-
-    private Directory newDirectory(Directory parent, String name) {
-        Directory dir = Directory.create(parent, name, imageFileAttributes());
-        nodes.put(dir.getName(), dir);
-        return dir;
-    }
-
-    private Resource newResource(Directory parent, ImageLocation loc) {
-        Resource res = Resource.create(parent, loc, imageFileAttributes());
-        nodes.put(res.getName(), res);
-        return res;
-    }
-
-    private LinkNode newLinkNode(Directory dir, String name, Node link) {
-        LinkNode linkNode = LinkNode.create(dir, name, link);
-        nodes.put(linkNode.getName(), linkNode);
-        return linkNode;
-    }
-
-    private Directory makeDirectories(String parent) {
-        Directory last = rootDir;
-        for (int offset = parent.indexOf('/', 1);
-                offset != -1;
-                offset = parent.indexOf('/', offset + 1)) {
-            String dir = parent.substring(0, offset);
-            last = makeDirectory(dir, last);
-        }
-        return makeDirectory(parent, last);
-
-    }
-
-    private Directory makeDirectory(String dir, Directory last) {
-        Directory nextDir = (Directory) nodes.get(dir);
-        if (nextDir == null) {
-            nextDir = newDirectory(last, dir);
-        }
-        return nextDir;
-    }
-
-    public byte[] getResource(Node node) throws IOException {
-        if (node.isResource()) {
-            return super.getResource(node.getLocation());
-        }
-        throw new IOException("Not a resource: " + node);
-    }
-
-    public byte[] getResource(Resource rs) throws IOException {
-        return super.getResource(rs.getLocation());
-    }
 }
--- a/jdk/src/java.base/share/classes/jdk/internal/jrtfs/JrtFileSystem.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/jdk/internal/jrtfs/JrtFileSystem.java	Wed Jul 05 21:37:42 2017 +0200
@@ -299,13 +299,9 @@
     }
 
     // clean up this file system - called from finalize and close
-    void cleanup() throws IOException {
-        if (!isOpen) {
-            return;
-        }
-        synchronized (this) {
+    synchronized void cleanup() throws IOException {
+        if (isOpen) {
             isOpen = false;
-            // close image reader and null out
             image.close();
             image = null;
         }
@@ -461,8 +457,8 @@
     private Node lookup(String path) {
         try {
             return image.findNode(path);
-        } catch (RuntimeException re) {
-            throw new InvalidPathException(path, re.toString());
+        } catch (RuntimeException | IOException ex) {
+            throw new InvalidPathException(path, ex.toString());
         }
     }
 
--- a/jdk/src/java.base/share/classes/jdk/internal/jrtfs/JrtFileSystemProvider.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/jdk/internal/jrtfs/JrtFileSystemProvider.java	Wed Jul 05 21:37:42 2017 +0200
@@ -101,10 +101,10 @@
     @Override
     public FileSystem newFileSystem(URI uri, Map<String, ?> env)
             throws IOException {
+        Objects.requireNonNull(env);
         checkPermission();
         checkUri(uri);
-
-        if (env != null && env.containsKey("java.home")) {
+        if (env.containsKey("java.home")) {
             return newFileSystem((String)env.get("java.home"), uri, env);
         } else {
             return new JrtFileSystem(this, env);
--- a/jdk/src/java.base/share/classes/jdk/internal/jrtfs/SystemImage.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/jdk/internal/jrtfs/SystemImage.java	Wed Jul 05 21:37:42 2017 +0200
@@ -49,7 +49,7 @@
  */
 abstract class SystemImage {
 
-    abstract Node findNode(String path);
+    abstract Node findNode(String path) throws IOException;
     abstract byte[] getResource(Node node) throws IOException;
     abstract void close() throws IOException;
 
@@ -60,7 +60,7 @@
             image.getRootDirectory();
             return new SystemImage() {
                 @Override
-                Node findNode(String path) {
+                Node findNode(String path) throws IOException {
                     return image.findNode(path);
                 }
                 @Override
--- a/jdk/src/java.base/share/classes/jdk/internal/loader/BootLoader.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/jdk/internal/loader/BootLoader.java	Wed Jul 05 21:37:42 2017 +0200
@@ -30,6 +30,7 @@
 import java.lang.reflect.Layer;
 import java.lang.reflect.Module;
 import java.net.MalformedURLException;
+import java.net.URI;
 import java.net.URL;
 import java.nio.file.Files;
 import java.nio.file.Path;
@@ -184,9 +185,9 @@
 
         /**
          * Define the {@code Package} with the given name. The specified
-         * location is a jrt URL to a named module in the run-time image, a
-         * file path to a module in an exploded run-time image, or the file
-         * path to an enty on the boot class path (java agent Boot-Class-Path
+         * location is a jrt URL to a named module in the run-time image,
+         * a file URL to a module in an exploded run-time image, or a file
+         * path to an entry on the boot class path (java agent Boot-Class-Path
          * or -Xbootclasspath/a.
          *
          * <p> If the given location is a JAR file containing a manifest,
@@ -194,7 +195,9 @@
          * the manifest, if present.
          *
          * @param name     package name
-         * @param location location where the package is (jrt URL or file path)
+         * @param location location where the package is (jrt URL or file URL
+         *                 for a named module in the run-time or exploded image;
+         *                 a file path for a package from -Xbootclasspath/a)
          */
         static Package definePackage(String name, String location) {
             Module module = findModule(location);
@@ -222,9 +225,9 @@
             if (location.startsWith("jrt:/")) {
                 // named module in runtime image ("jrt:/".length() == 5)
                 mn = location.substring(5, location.length());
-            } else {
+            } else if (location.startsWith("file:/")) {
                 // named module in exploded image
-                Path path = Paths.get(location);
+                Path path = Paths.get(URI.create(location));
                 Path modulesDir = Paths.get(JAVA_HOME, "modules");
                 if (path.startsWith(modulesDir)) {
                     mn = path.getFileName().toString();
--- a/jdk/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java	Wed Jul 05 21:37:42 2017 +0200
@@ -52,6 +52,7 @@
 import java.util.LinkedList;
 import java.util.List;
 import java.util.NoSuchElementException;
+import java.util.Properties;
 import java.util.Set;
 import java.util.Stack;
 import java.util.StringTokenizer;
@@ -69,6 +70,7 @@
 import jdk.internal.util.jar.JarIndex;
 import sun.net.util.URLUtil;
 import sun.net.www.ParseUtil;
+import sun.security.action.GetPropertyAction;
 
 /**
  * This class is used to maintain a search path of URLs for loading classes
@@ -78,20 +80,15 @@
  */
 public class URLClassPath {
     private static final String USER_AGENT_JAVA_VERSION = "UA-Java-Version";
-    private static final String JAVA_HOME;
     private static final String JAVA_VERSION;
     private static final boolean DEBUG;
     private static final boolean DISABLE_JAR_CHECKING;
 
     static {
-        JAVA_HOME = java.security.AccessController.doPrivileged(
-            new sun.security.action.GetPropertyAction("java.home"));
-        JAVA_VERSION = java.security.AccessController.doPrivileged(
-            new sun.security.action.GetPropertyAction("java.version"));
-        DEBUG        = (java.security.AccessController.doPrivileged(
-            new sun.security.action.GetPropertyAction("sun.misc.URLClassPath.debug")) != null);
-        String p = java.security.AccessController.doPrivileged(
-            new sun.security.action.GetPropertyAction("sun.misc.URLClassPath.disableJarChecking"));
+        Properties props = GetPropertyAction.getProperties();
+        JAVA_VERSION = props.getProperty("java.version");
+        DEBUG = (props.getProperty("sun.misc.URLClassPath.debug") != null);
+        String p = props.getProperty("sun.misc.URLClassPath.disableJarChecking");
         DISABLE_JAR_CHECKING = p != null ? p.equals("true") || p.equals("") : false;
     }
 
--- a/jdk/src/java.base/share/classes/jdk/internal/logger/LoggerFinderLoader.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/jdk/internal/logger/LoggerFinderLoader.java	Wed Jul 05 21:37:42 2017 +0200
@@ -33,6 +33,7 @@
 import java.util.ServiceConfigurationError;
 import java.util.ServiceLoader;
 import sun.security.util.SecurityConstants;
+import sun.security.action.GetPropertyAction;
 
 /**
  * Helper class used to load the {@link java.lang.System.LoggerFinder}.
@@ -79,9 +80,8 @@
 
     // Get configuration error policy
     private static ErrorPolicy configurationErrorPolicy() {
-        final PrivilegedAction<String> getConfigurationErrorPolicy =
-                () -> System.getProperty("jdk.logger.finder.error");
-        String errorPolicy = AccessController.doPrivileged(getConfigurationErrorPolicy);
+        String errorPolicy =
+                GetPropertyAction.getProperty("jdk.logger.finder.error");
         if (errorPolicy == null || errorPolicy.isEmpty()) {
             return ErrorPolicy.WARNING;
         }
@@ -95,9 +95,8 @@
     // Whether multiple provider should be considered as an error.
     // This is further submitted to the configuration error policy.
     private static boolean ensureSingletonProvider() {
-        final PrivilegedAction<Boolean> ensureSingletonProvider =
-                () -> Boolean.getBoolean("jdk.logger.finder.singleton");
-        return AccessController.doPrivileged(ensureSingletonProvider);
+        return Boolean.parseBoolean(
+                GetPropertyAction.getProperty("jdk.logger.finder.singleton"));
     }
 
     private static Iterator<System.LoggerFinder> findLoggerFinderProviders() {
--- a/jdk/src/java.base/share/classes/jdk/internal/logger/SimpleConsoleLogger.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/jdk/internal/logger/SimpleConsoleLogger.java	Wed Jul 05 21:37:42 2017 +0200
@@ -55,8 +55,8 @@
             PlatformLogger.toPlatformLevel(DEFAULT_LEVEL);
 
     static Level getDefaultLevel() {
-        String levelName = AccessController.doPrivileged(
-                new GetPropertyAction("jdk.system.logger.level", "INFO"));
+        String levelName = GetPropertyAction
+                .getProperty("jdk.system.logger.level", "INFO");
         try {
             return Level.valueOf(levelName);
         } catch (IllegalArgumentException iae) {
@@ -425,8 +425,8 @@
         // Make it easier to wrap Logger...
         static private final String[] skips;
         static {
-            String additionalPkgs = AccessController.doPrivileged(
-                new GetPropertyAction("jdk.logger.packages"));
+            String additionalPkgs =
+                    GetPropertyAction.getProperty("jdk.logger.packages");
             skips = additionalPkgs == null ? new String[0] : additionalPkgs.split(",");
         }
 
@@ -485,7 +485,7 @@
             //    jdk/test/java/lang/invoke/lambda/LogGeneratedClassesTest.java
             // to fail - because that test has a testcase which somehow references
             // PlatformLogger and counts the number of generated lambda classes.
-            String format = AccessController.doPrivileged(new GetPropertyAction(key));
+            String format = GetPropertyAction.getProperty(key);
 
             if (format == null && defaultPropertyGetter != null) {
                 format = defaultPropertyGetter.apply(key);
--- a/jdk/src/java.base/share/classes/jdk/internal/misc/JavaLangInvokeAccess.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/JavaLangInvokeAccess.java	Wed Jul 05 21:37:42 2017 +0200
@@ -30,4 +30,9 @@
      * Create a new MemberName instance
      */
     Object newMemberName();
+
+    /**
+     * Returns the name for the given MemberName
+     */
+    String getName(Object mname);
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/JavaObjectInputStreamAccess.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,41 @@
+/*
+ * 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.internal.misc;
+
+import java.io.ObjectInputStream;
+
+/**
+ * The interface to specify methods for accessing {@code ObjectInputStream}
+ * @author sjiang
+ */
+public interface JavaObjectInputStreamAccess {
+    /**
+     * Sets a descriptor validating.
+     * @param ois stream to have the descriptors validated
+     * @param validator validator used to validate a descriptor.
+     */
+    public void setValidator(ObjectInputStream ois, ObjectStreamClassValidator validator);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/ObjectStreamClassValidator.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,42 @@
+/*
+ * 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.internal.misc;
+
+import java.io.ObjectStreamClass;
+
+/**
+ * A callback used by {@code ObjectInputStream} to do descriptor validation.
+ *
+ * @author sjiang
+ */
+public interface ObjectStreamClassValidator {
+    /**
+     * This method will be called by ObjectInputStream to
+     * check a descriptor just before creating an object described by this descriptor.
+     * The object will not be created if this method throws a {@code RuntimeException}.
+     * @param descriptor descriptor to be checked.
+     */
+    public void validateDescriptor(ObjectStreamClass descriptor);
+}
--- a/jdk/src/java.base/share/classes/jdk/internal/misc/SharedSecrets.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/SharedSecrets.java	Wed Jul 05 21:37:42 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.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,9 +29,9 @@
 import java.util.jar.JarFile;
 import java.io.Console;
 import java.io.FileDescriptor;
+import java.io.ObjectInputStream;
 import java.security.ProtectionDomain;
 import java.security.AccessController;
-import jdk.internal.misc.Unsafe;
 
 /** A repository of "shared secrets", which are a mechanism for
     calling implementation-private methods in another package without
@@ -63,6 +63,7 @@
     private static JavaAWTAccess javaAWTAccess;
     private static JavaAWTFontAccess javaAWTFontAccess;
     private static JavaBeansAccess javaBeansAccess;
+    private static JavaObjectInputStreamAccess javaObjectInputStreamAccess;
 
     public static JavaUtilJarAccess javaUtilJarAccess() {
         if (javaUtilJarAccess == null) {
@@ -262,4 +263,15 @@
     public static void setJavaUtilResourceBundleAccess(JavaUtilResourceBundleAccess access) {
         javaUtilResourceBundleAccess = access;
     }
+
+    public static JavaObjectInputStreamAccess getJavaObjectInputStreamAccess() {
+        if (javaObjectInputStreamAccess == null) {
+            unsafe.ensureClassInitialized(ObjectInputStream.class);
+        }
+        return javaObjectInputStreamAccess;
+    }
+
+    public static void setJavaObjectInputStreamAccess(JavaObjectInputStreamAccess access) {
+        javaObjectInputStreamAccess = access;
+    }
 }
--- a/jdk/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Opcodes.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Opcodes.java	Wed Jul 05 21:37:42 2017 +0200
@@ -70,6 +70,7 @@
  * @author Eric Bruneton
  * @author Eugene Kuleshov
  */
+@SuppressWarnings("deprecation") // for Integer(int) constructor
 public interface Opcodes {
 
     // ASM API versions
@@ -176,6 +177,8 @@
      */
     int F_SAME1 = 4;
 
+    // For reference comparison purposes, construct new instances
+    // instead of using valueOf() or autoboxing.
     Integer TOP = new Integer(0);
     Integer INTEGER = new Integer(1);
     Integer FLOAT = new Integer(2);
--- a/jdk/src/java.base/share/classes/jdk/internal/reflect/Reflection.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/jdk/internal/reflect/Reflection.java	Wed Jul 05 21:37:42 2017 +0200
@@ -27,13 +27,12 @@
 
 
 import java.lang.reflect.*;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Objects;
 import jdk.internal.HotSpotIntrinsicCandidate;
 import jdk.internal.misc.VM;
+import sun.security.action.GetPropertyAction;
 
 /** Common utility routines used by both java.lang and
     java.lang.reflect */
@@ -344,15 +343,10 @@
 
     private static void printStackTraceIfNeeded(Throwable e) {
         if (!printStackWhenAccessFailsSet && VM.initLevel() >= 1) {
-            // can't use method reference here, might be too early in startup
-            PrivilegedAction<Boolean> pa = new PrivilegedAction<Boolean>() {
-                public Boolean run() {
-                    String s;
-                    s = System.getProperty("sun.reflect.debugModuleAccessChecks");
-                    return (s != null && !s.equalsIgnoreCase("false"));
-                }
-            };
-            printStackWhenAccessFails = AccessController.doPrivileged(pa);
+            String s = GetPropertyAction
+                    .getProperty("sun.reflect.debugModuleAccessChecks");
+            printStackWhenAccessFails =
+                    (s != null && !s.equalsIgnoreCase("false"));
             printStackWhenAccessFailsSet = true;
         }
         if (printStackWhenAccessFails) {
--- a/jdk/src/java.base/share/classes/jdk/internal/reflect/ReflectionFactory.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/jdk/internal/reflect/ReflectionFactory.java	Wed Jul 05 21:37:42 2017 +0200
@@ -30,10 +30,11 @@
 import java.lang.reflect.Method;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Modifier;
-import java.security.AccessController;
 import java.security.Permission;
 import java.security.PrivilegedAction;
+import java.util.Properties;
 import sun.reflect.misc.ReflectUtil;
+import sun.security.action.GetPropertyAction;
 
 /** <P> The master factory for all reflective objects, both those in
     java.lang.reflect (Fields, Methods, Constructors) as well as their
@@ -382,41 +383,37 @@
         run, before the system properties are set up. */
     private static void checkInitted() {
         if (initted) return;
-        AccessController.doPrivileged(
-            new PrivilegedAction<>() {
-                public Void run() {
-                    // Tests to ensure the system properties table is fully
-                    // initialized. This is needed because reflection code is
-                    // called very early in the initialization process (before
-                    // command-line arguments have been parsed and therefore
-                    // these user-settable properties installed.) We assume that
-                    // if System.out is non-null then the System class has been
-                    // fully initialized and that the bulk of the startup code
-                    // has been run.
 
-                    if (System.out == null) {
-                        // java.lang.System not yet fully initialized
-                        return null;
-                    }
+        // Tests to ensure the system properties table is fully
+        // initialized. This is needed because reflection code is
+        // called very early in the initialization process (before
+        // command-line arguments have been parsed and therefore
+        // these user-settable properties installed.) We assume that
+        // if System.out is non-null then the System class has been
+        // fully initialized and that the bulk of the startup code
+        // has been run.
+
+        if (System.out == null) {
+            // java.lang.System not yet fully initialized
+            return;
+        }
 
-                    String val = System.getProperty("sun.reflect.noInflation");
-                    if (val != null && val.equals("true")) {
-                        noInflation = true;
-                    }
+        Properties props = GetPropertyAction.getProperties();
+        String val = props.getProperty("sun.reflect.noInflation");
+        if (val != null && val.equals("true")) {
+            noInflation = true;
+        }
 
-                    val = System.getProperty("sun.reflect.inflationThreshold");
-                    if (val != null) {
-                        try {
-                            inflationThreshold = Integer.parseInt(val);
-                        } catch (NumberFormatException e) {
-                            throw new RuntimeException("Unable to parse property sun.reflect.inflationThreshold", e);
-                        }
-                    }
+        val = props.getProperty("sun.reflect.inflationThreshold");
+        if (val != null) {
+            try {
+                inflationThreshold = Integer.parseInt(val);
+            } catch (NumberFormatException e) {
+                throw new RuntimeException("Unable to parse property sun.reflect.inflationThreshold", e);
+            }
+        }
 
-                    initted = true;
-                    return null;
-                }
-            });
+        initted = true;
     }
 
     private static LangReflectAccess langReflectAccess() {
--- a/jdk/src/java.base/share/classes/module-info.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/module-info.java	Wed Jul 05 21:37:42 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
@@ -300,9 +300,5 @@
 
     provides java.nio.file.spi.FileSystemProvider with
         jdk.internal.jrtfs.JrtFileSystemProvider;
-    provides java.security.Provider with sun.security.provider.Sun;
-    provides java.security.Provider with sun.security.rsa.SunRsaSign;
-    provides java.security.Provider with com.sun.crypto.provider.SunJCE;
-    provides java.security.Provider with com.sun.net.ssl.internal.ssl.Provider;
 }
 
--- a/jdk/src/java.base/share/classes/sun/invoke/util/VerifyAccess.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/invoke/util/VerifyAccess.java	Wed Jul 05 21:37:42 2017 +0200
@@ -231,22 +231,66 @@
      * @param refc the class attempting to make the reference
      */
     public static boolean isTypeVisible(Class<?> type, Class<?> refc) {
-        if (type == refc)  return true;  // easy check
+        if (type == refc) {
+            return true;  // easy check
+        }
         while (type.isArray())  type = type.getComponentType();
-        if (type.isPrimitive() || type == Object.class)  return true;
-        ClassLoader parent = type.getClassLoader();
-        if (parent == null)  return true;
-        ClassLoader child  = refc.getClassLoader();
-        if (child == null)  return false;
-        if (parent == child || loadersAreRelated(parent, child, true))
+        if (type.isPrimitive() || type == Object.class) {
             return true;
-        // Do it the hard way:  Look up the type name from the refc loader.
-        try {
-            Class<?> res = child.loadClass(type.getName());
-            return (type == res);
-        } catch (ClassNotFoundException ex) {
+        }
+        ClassLoader typeLoader = type.getClassLoader();
+        ClassLoader refcLoader = refc.getClassLoader();
+        if (typeLoader == refcLoader) {
+            return true;
+        }
+        if (refcLoader == null && typeLoader != null) {
             return false;
         }
+        if (typeLoader == null && type.getName().startsWith("java.")) {
+            // Note:  The API for actually loading classes, ClassLoader.defineClass,
+            // guarantees that classes with names beginning "java." cannot be aliased,
+            // because class loaders cannot load them directly.
+            return true;
+        }
+
+        // Do it the hard way:  Look up the type name from the refc loader.
+        //
+        // Force the refc loader to report and commit to a particular binding for this type name (type.getName()).
+        //
+        // In principle, this query might force the loader to load some unrelated class,
+        // which would cause this query to fail (and the original caller to give up).
+        // This would be wasted effort, but it is expected to be very rare, occurring
+        // only when an attacker is attempting to create a type alias.
+        // In the normal case, one class loader will simply delegate to the other,
+        // and the same type will be visible through both, with no extra loading.
+        //
+        // It is important to go through Class.forName instead of ClassLoader.loadClass
+        // because Class.forName goes through the JVM system dictionary, which records
+        // the class lookup once for all. This means that even if a not-well-behaved class loader
+        // would "change its mind" about the meaning of the name, the Class.forName request
+        // will use the result cached in the JVM system dictionary. Note that the JVM system dictionary
+        // will record the first successful result. Unsuccessful results are not stored.
+        //
+        // We use doPrivileged in order to allow an unprivileged caller to ask an arbitrary
+        // class loader about the binding of the proposed name (type.getName()).
+        // The looked up type ("res") is compared for equality against the proposed
+        // type ("type") and then is discarded.  Thus, the worst that can happen to
+        // the "child" class loader is that it is bothered to load and report a class
+        // that differs from "type"; this happens once due to JVM system dictionary
+        // memoization.  And the caller never gets to look at the alternate type binding
+        // ("res"), whether it exists or not.
+        final String name = type.getName();
+        Class<?> res = java.security.AccessController.doPrivileged(
+                new java.security.PrivilegedAction<>() {
+                    public Class<?> run() {
+                        try {
+                            return Class.forName(name, false, refcLoader);
+                        } catch (ClassNotFoundException | LinkageError e) {
+                            return null; // Assume the class is not found
+                        }
+                    }
+            });
+        return (type == res);
     }
 
     /**
--- a/jdk/src/java.base/share/classes/sun/net/ResourceManager.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/net/ResourceManager.java	Wed Jul 05 21:37:42 2017 +0200
@@ -53,9 +53,8 @@
     private static final AtomicInteger numSockets;
 
     static {
-        String prop = java.security.AccessController.doPrivileged(
-            new GetPropertyAction("sun.net.maxDatagramSockets")
-        );
+        String prop =
+                GetPropertyAction.getProperty("sun.net.maxDatagramSockets");
         int defmax = DEFAULT_MAX_SOCKETS;
         try {
             if (prop != null) {
--- a/jdk/src/java.base/share/classes/sun/net/sdp/SdpSupport.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/net/sdp/SdpSupport.java	Wed Jul 05 21:37:42 2017 +0200
@@ -31,6 +31,7 @@
 
 import jdk.internal.misc.SharedSecrets;
 import jdk.internal.misc.JavaIOFileDescriptorAccess;
+import sun.security.action.GetPropertyAction;
 
 
 /**
@@ -39,8 +40,7 @@
  */
 
 public final class SdpSupport {
-    private static final String os = AccessController
-        .doPrivileged(new sun.security.action.GetPropertyAction("os.name"));
+    private static final String os = GetPropertyAction.getProperty("os.name");
     private static final boolean isSupported = (os.equals("SunOS") || (os.equals("Linux")));
     private static final JavaIOFileDescriptorAccess fdAccess =
         SharedSecrets.getJavaIOFileDescriptorAccess();
--- a/jdk/src/java.base/share/classes/sun/net/smtp/SmtpClient.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/net/smtp/SmtpClient.java	Wed Jul 05 21:37:42 2017 +0200
@@ -25,10 +25,10 @@
 
 package sun.net.smtp;
 
-import java.util.StringTokenizer;
 import java.io.*;
 import java.net.*;
 import sun.net.TransferProtocolClient;
+import sun.security.action.GetPropertyAction;
 
 /**
  * This class implements the SMTP client.
@@ -157,8 +157,7 @@
         }
         try {
             String s;
-            mailhost = java.security.AccessController.doPrivileged(
-                    new sun.security.action.GetPropertyAction("mail.host"));
+            mailhost = GetPropertyAction.getProperty("mail.host");
             if (mailhost != null) {
                 openServer(mailhost);
                 return;
@@ -184,8 +183,7 @@
         setConnectTimeout(to);
         try {
             String s;
-            mailhost = java.security.AccessController.doPrivileged(
-                    new sun.security.action.GetPropertyAction("mail.host"));
+            mailhost = GetPropertyAction.getProperty("mail.host");
             if (mailhost != null) {
                 openServer(mailhost);
                 return;
--- a/jdk/src/java.base/share/classes/sun/net/www/MimeLauncher.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/net/www/MimeLauncher.java	Wed Jul 05 21:37:42 2017 +0200
@@ -27,6 +27,7 @@
 import java.net.URL;
 import java.io.*;
 import java.util.StringTokenizer;
+import sun.security.action.GetPropertyAction;
 
 class MimeLauncher extends Thread {
     java.net.URLConnection uc;
@@ -182,8 +183,7 @@
         }
 
         String execPathList;
-        execPathList = java.security.AccessController.doPrivileged(
-                new sun.security.action.GetPropertyAction("exec.path"));
+        execPathList = GetPropertyAction.getProperty("exec.path");
         if (execPathList == null) {
             // exec.path property not set
             return false;
--- a/jdk/src/java.base/share/classes/sun/net/www/http/HttpClient.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/net/www/http/HttpClient.java	Wed Jul 05 21:37:42 2017 +0200
@@ -28,6 +28,7 @@
 import java.io.*;
 import java.net.*;
 import java.util.Locale;
+import java.util.Properties;
 import sun.net.NetworkClient;
 import sun.net.ProgressSource;
 import sun.net.www.MessageHeader;
@@ -37,6 +38,7 @@
 import sun.net.www.protocol.http.HttpURLConnection;
 import sun.util.logging.PlatformLogger;
 import static sun.net.www.protocol.http.HttpURLConnection.TunnelState.*;
+import sun.security.action.GetPropertyAction;
 
 /**
  * @author Herb Jellinek
@@ -143,20 +145,18 @@
     }
 
     static {
-        String keepAlive = java.security.AccessController.doPrivileged(
-            new sun.security.action.GetPropertyAction("http.keepAlive"));
-
-        String retryPost = java.security.AccessController.doPrivileged(
-            new sun.security.action.GetPropertyAction("sun.net.http.retryPost"));
+        Properties props = GetPropertyAction.getProperties();
+        String keepAlive = props.getProperty("http.keepAlive");
+        String retryPost = props.getProperty("sun.net.http.retryPost");
 
         if (keepAlive != null) {
-            keepAliveProp = Boolean.valueOf(keepAlive).booleanValue();
+            keepAliveProp = Boolean.parseBoolean(keepAlive);
         } else {
             keepAliveProp = true;
         }
 
         if (retryPost != null) {
-            retryPostProp = Boolean.valueOf(retryPost).booleanValue();
+            retryPostProp = Boolean.parseBoolean(retryPost);
         } else
             retryPostProp = true;
 
--- a/jdk/src/java.base/share/classes/sun/net/www/protocol/ftp/FtpURLConnection.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/net/www/protocol/ftp/FtpURLConnection.java	Wed Jul 05 21:37:42 2017 +0200
@@ -46,6 +46,7 @@
 import java.util.StringTokenizer;
 import java.util.Iterator;
 import java.security.Permission;
+import java.util.Properties;
 import sun.net.NetworkClient;
 import sun.net.www.MessageHeader;
 import sun.net.www.MeteredStream;
@@ -277,11 +278,10 @@
 
         if (user == null) {
             user = "anonymous";
-            String vers = java.security.AccessController.doPrivileged(
-                    new GetPropertyAction("java.version"));
-            password = java.security.AccessController.doPrivileged(
-                    new GetPropertyAction("ftp.protocol.user",
-                                          "Java" + vers + "@"));
+            Properties props = GetPropertyAction.getProperties();
+            String vers = props.getProperty("java.version");
+            password = props.getProperty("ftp.protocol.user",
+                    "Java" + vers + "@");
         }
         try {
             ftp = FtpClient.create();
--- a/jdk/src/java.base/share/classes/sun/net/www/protocol/http/AuthenticationHeader.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/net/www/protocol/http/AuthenticationHeader.java	Wed Jul 05 21:37:42 2017 +0200
@@ -25,9 +25,10 @@
 
 package sun.net.www.protocol.http;
 
-import sun.net.www.*;
 import java.util.Iterator;
 import java.util.HashMap;
+import sun.net.www.*;
+import sun.security.action.GetPropertyAction;
 
 /**
  * This class is used to parse the information in WWW-Authenticate: and Proxy-Authenticate:
@@ -93,8 +94,7 @@
     }
 
     static {
-        authPref = java.security.AccessController.doPrivileged(
-            new sun.security.action.GetPropertyAction("http.auth.preference"));
+        authPref = GetPropertyAction.getProperty("http.auth.preference");
 
         // http.auth.preference can be set to SPNEGO or Kerberos.
         // In fact they means "Negotiate with SPNEGO" and "Negotiate with
--- a/jdk/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java	Wed Jul 05 21:37:42 2017 +0200
@@ -52,7 +52,6 @@
 import java.security.PrivilegedExceptionAction;
 import java.security.PrivilegedActionException;
 import java.io.*;
-import java.net.*;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Date;
@@ -78,12 +77,15 @@
 import java.util.TimeZone;
 import java.net.MalformedURLException;
 import java.nio.ByteBuffer;
+import java.util.Properties;
 import static sun.net.www.protocol.http.AuthScheme.BASIC;
 import static sun.net.www.protocol.http.AuthScheme.DIGEST;
 import static sun.net.www.protocol.http.AuthScheme.NTLM;
 import static sun.net.www.protocol.http.AuthScheme.NEGOTIATE;
 import static sun.net.www.protocol.http.AuthScheme.KERBEROS;
 import static sun.net.www.protocol.http.AuthScheme.UNKNOWN;
+import sun.security.action.GetIntegerAction;
+import sun.security.action.GetPropertyAction;
 
 /**
  * A class to represent an HTTP connection to a remote object.
@@ -205,46 +207,38 @@
     };
 
     static {
-        maxRedirects = java.security.AccessController.doPrivileged(
-            new sun.security.action.GetIntegerAction(
-                "http.maxRedirects", defaultmaxRedirects)).intValue();
-        version = java.security.AccessController.doPrivileged(
-                    new sun.security.action.GetPropertyAction("java.version"));
-        String agent = java.security.AccessController.doPrivileged(
-                    new sun.security.action.GetPropertyAction("http.agent"));
+        Properties props = GetPropertyAction.getProperties();
+        maxRedirects = GetIntegerAction.getProperty("http.maxRedirects",
+                        defaultmaxRedirects);
+        version = props.getProperty("java.version");
+        String agent = props.getProperty("http.agent");
         if (agent == null) {
             agent = "Java/"+version;
         } else {
             agent = agent + " Java/"+version;
         }
         userAgent = agent;
-        validateProxy = java.security.AccessController.doPrivileged(
-                new sun.security.action.GetBooleanAction(
-                    "http.auth.digest.validateProxy")).booleanValue();
-        validateServer = java.security.AccessController.doPrivileged(
-                new sun.security.action.GetBooleanAction(
-                    "http.auth.digest.validateServer")).booleanValue();
-
-        enableESBuffer = java.security.AccessController.doPrivileged(
-                new sun.security.action.GetBooleanAction(
-                    "sun.net.http.errorstream.enableBuffering")).booleanValue();
-        timeout4ESBuffer = java.security.AccessController.doPrivileged(
-                new sun.security.action.GetIntegerAction(
-                    "sun.net.http.errorstream.timeout", 300)).intValue();
+        validateProxy = Boolean.parseBoolean(
+                props.getProperty("http.auth.digest.validateProxy"));
+        validateServer = Boolean.parseBoolean(
+                props.getProperty("http.auth.digest.validateServer"));
+
+        enableESBuffer = Boolean.parseBoolean(
+                props.getProperty("sun.net.http.errorstream.enableBuffering"));
+        timeout4ESBuffer = GetIntegerAction
+                .getProperty("sun.net.http.errorstream.timeout", 300);
         if (timeout4ESBuffer <= 0) {
             timeout4ESBuffer = 300; // use the default
         }
 
-        bufSize4ES = java.security.AccessController.doPrivileged(
-                new sun.security.action.GetIntegerAction(
-                    "sun.net.http.errorstream.bufferSize", 4096)).intValue();
+        bufSize4ES = GetIntegerAction
+                .getProperty("sun.net.http.errorstream.bufferSize", 4096);
         if (bufSize4ES <= 0) {
             bufSize4ES = 4096; // use the default
         }
 
-        allowRestrictedHeaders = java.security.AccessController.doPrivileged(
-                new sun.security.action.GetBooleanAction(
-                    "sun.net.http.allowRestrictedHeaders")).booleanValue();
+        allowRestrictedHeaders = Boolean.parseBoolean(
+                props.getProperty("sun.net.http.allowRestrictedHeaders"));
         if (!allowRestrictedHeaders) {
             restrictedHeaderSet = new HashSet<>(restrictedHeaders.length);
             for (int i=0; i < restrictedHeaders.length; i++) {
--- a/jdk/src/java.base/share/classes/sun/net/www/protocol/https/HttpsClient.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/net/www/protocol/https/HttpsClient.java	Wed Jul 05 21:37:42 2017 +0200
@@ -41,7 +41,6 @@
 import java.security.cert.*;
 import java.util.StringTokenizer;
 import java.util.Vector;
-import java.security.AccessController;
 
 import javax.security.auth.x500.X500Principal;
 
@@ -139,8 +138,8 @@
         // If ciphers are assigned, sort them into an array.
         //
         String ciphers [];
-        String cipherString = AccessController.doPrivileged(
-                new GetPropertyAction("https.cipherSuites"));
+        String cipherString =
+                GetPropertyAction.getProperty("https.cipherSuites");
 
         if (cipherString == null || "".equals(cipherString)) {
             ciphers = null;
@@ -163,8 +162,8 @@
         // If protocols are assigned, sort them into an array.
         //
         String protocols [];
-        String protocolString = AccessController.doPrivileged(
-                new GetPropertyAction("https.protocols"));
+        String protocolString =
+                GetPropertyAction.getProperty("https.protocols");
 
         if (protocolString == null || "".equals(protocolString)) {
             protocols = null;
@@ -184,8 +183,7 @@
     }
 
     private String getUserAgent() {
-        String userAgent = java.security.AccessController.doPrivileged(
-                new sun.security.action.GetPropertyAction("https.agent"));
+        String userAgent = GetPropertyAction.getProperty("https.agent");
         if (userAgent == null || userAgent.length() == 0) {
             userAgent = "JSSE";
         }
--- a/jdk/src/java.base/share/classes/sun/net/www/protocol/jrt/JavaRuntimeURLConnection.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/net/www/protocol/jrt/JavaRuntimeURLConnection.java	Wed Jul 05 21:37:42 2017 +0200
@@ -32,10 +32,7 @@
 import java.io.InputStream;
 import java.net.MalformedURLException;
 import java.net.URL;
-import java.security.AccessController;
 import java.security.Permission;
-import java.security.PrivilegedAction;
-import java.util.List;
 
 import jdk.internal.jimage.ImageLocation;
 import jdk.internal.jimage.ImageReader;
@@ -45,6 +42,7 @@
 import jdk.internal.loader.Resource;
 import sun.net.www.ParseUtil;
 import sun.net.www.URLConnection;
+import sun.security.action.GetPropertyAction;
 
 /**
  * URLConnection implementation that can be used to connect to resources
@@ -163,11 +161,7 @@
     public Permission getPermission() throws IOException {
         Permission p = permission;
         if (p == null) {
-            // using lambda expression here leads to recursive initialization
-            PrivilegedAction<String> pa = new PrivilegedAction<String>() {
-                public String run() { return System.getProperty("java.home"); }
-            };
-            String home = AccessController.doPrivileged(pa);
+            String home = GetPropertyAction.getProperty("java.home");
             p = new FilePermission(home + File.separator + "-", "read");
             permission = p;
         }
--- a/jdk/src/java.base/share/classes/sun/net/www/protocol/netdoc/Handler.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/net/www/protocol/netdoc/Handler.java	Wed Jul 05 21:37:42 2017 +0200
@@ -40,6 +40,7 @@
 import java.net.URLStreamHandler;
 import java.io.InputStream;
 import java.io.IOException;
+import sun.security.action.GetPropertyAction;
 
 public class Handler extends URLStreamHandler {
     static URL base;
@@ -54,12 +55,10 @@
         URLConnection uc = null;
         URL ru;
 
-        Boolean tmp = java.security.AccessController.doPrivileged(
-            new sun.security.action.GetBooleanAction("newdoc.localonly"));
-        boolean localonly = tmp.booleanValue();
+        boolean localonly = Boolean.parseBoolean(
+                GetPropertyAction.getProperty("newdoc.localonly"));
 
-        String docurl = java.security.AccessController.doPrivileged(
-            new sun.security.action.GetPropertyAction("doc.url"));
+        String docurl = GetPropertyAction.getProperty("doc.url");
 
         String file = u.getFile();
         if (!localonly) {
--- a/jdk/src/java.base/share/classes/sun/nio/ch/FileChannelImpl.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/FileChannelImpl.java	Wed Jul 05 21:37:42 2017 +0200
@@ -1019,9 +1019,8 @@
         if (!propertyChecked) {
             synchronized (FileChannelImpl.class) {
                 if (!propertyChecked) {
-                    String value = AccessController.doPrivileged(
-                        new GetPropertyAction(
-                            "sun.nio.ch.disableSystemWideOverlappingFileLockCheck"));
+                    String value = GetPropertyAction.getProperty(
+                            "sun.nio.ch.disableSystemWideOverlappingFileLockCheck");
                     isSharedFileLockTable = ((value == null) || value.equals("false"));
                     propertyChecked = true;
                 }
--- a/jdk/src/java.base/share/classes/sun/nio/ch/Net.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/Net.java	Wed Jul 05 21:37:42 2017 +0200
@@ -33,6 +33,7 @@
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import sun.net.ExtendedOptionsImpl;
+import sun.security.action.GetPropertyAction;
 
 
 public class Net {
@@ -382,13 +383,8 @@
     }
 
     public static boolean isFastTcpLoopbackRequested() {
-        String loopbackProp = java.security.AccessController.doPrivileged(
-            new PrivilegedAction<String>() {
-                @Override
-                public String run() {
-                    return System.getProperty("jdk.net.useFastTcpLoopback");
-                }
-            });
+        String loopbackProp =
+                GetPropertyAction.getProperty("jdk.net.useFastTcpLoopback");
         boolean enable;
         if ("".equals(loopbackProp)) {
             enable = true;
@@ -647,16 +643,9 @@
         int availLevel = isExclusiveBindAvailable();
         if (availLevel >= 0) {
             String exclBindProp =
-                java.security.AccessController.doPrivileged(
-                    new PrivilegedAction<String>() {
-                        @Override
-                        public String run() {
-                            return System.getProperty(
-                                    "sun.net.useExclusiveBind");
-                        }
-                    });
+                    GetPropertyAction.getProperty("sun.net.useExclusiveBind");
             if (exclBindProp != null) {
-                exclusiveBind = exclBindProp.length() == 0 ?
+                exclusiveBind = exclBindProp.isEmpty() ?
                         true : Boolean.parseBoolean(exclBindProp);
             } else if (availLevel == 1) {
                 exclusiveBind = true;
--- a/jdk/src/java.base/share/classes/sun/nio/ch/Util.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/Util.java	Wed Jul 05 21:37:42 2017 +0200
@@ -64,13 +64,7 @@
      * for potential future-proofing.
      */
     private static long getMaxCachedBufferSize() {
-        String s = java.security.AccessController.doPrivileged(
-            new PrivilegedAction<String>() {
-                @Override
-                public String run() {
-                    return System.getProperty("jdk.nio.maxCachedBufferSize");
-                }
-            });
+        String s = GetPropertyAction.getProperty("jdk.nio.maxCachedBufferSize");
         if (s != null) {
             try {
                 long m = Long.parseLong(s);
@@ -471,8 +465,7 @@
         if (bugLevel == null) {
             if (!jdk.internal.misc.VM.isBooted())
                 return false;
-            String value = AccessController.doPrivileged(
-                new GetPropertyAction("sun.nio.ch.bugLevel"));
+            String value = GetPropertyAction.getProperty("sun.nio.ch.bugLevel");
             bugLevel = (value != null) ? value : "";
         }
         return bugLevel.equals(bl);
--- a/jdk/src/java.base/share/classes/sun/nio/cs/StandardCharsets.java.template	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/nio/cs/StandardCharsets.java.template	Wed Jul 05 21:37:42 2017 +0200
@@ -34,8 +34,7 @@
 import java.util.Iterator;
 import java.util.Locale;
 import java.util.Map;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
+import sun.security.action.GetPropertyAction;
 
 public class StandardCharsets extends CharsetProvider {
 
@@ -201,15 +200,7 @@
     }
 
     private static String getProperty(String key) {
-        // this method may be called during initialization of
-        // system class loader and thus not using lambda
-        return AccessController.doPrivileged(
-            new PrivilegedAction<String>() {
-                @Override
-                public String run() {
-                    return System.getProperty(key);
-                }
-            });
+        return GetPropertyAction.getProperty(key);
     }
 
 
--- a/jdk/src/java.base/share/classes/sun/nio/fs/Util.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/nio/fs/Util.java	Wed Jul 05 21:37:42 2017 +0200
@@ -28,8 +28,7 @@
 import java.util.*;
 import java.nio.file.*;
 import java.nio.charset.Charset;
-import java.security.*;
-import sun.security.action.*;
+import sun.security.action.GetPropertyAction;
 
 /**
  * Utility methods
@@ -39,7 +38,7 @@
     private Util() { }
 
     private static final Charset jnuEncoding = Charset.forName(
-        AccessController.doPrivileged(new GetPropertyAction("sun.jnu.encoding")));
+        GetPropertyAction.getProperty("sun.jnu.encoding"));
 
     /**
      * Returns {@code Charset} corresponding to the sun.jnu.encoding property
--- a/jdk/src/java.base/share/classes/sun/security/action/GetIntegerAction.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/security/action/GetIntegerAction.java	Wed Jul 05 21:37:42 2017 +0200
@@ -25,6 +25,8 @@
 
 package sun.security.action;
 
+import java.security.AccessController;
+
 /**
  * A convenience class for retrieving the integer value of a system property
  * as a privileged action.
@@ -67,7 +69,7 @@
         implements java.security.PrivilegedAction<Integer> {
     private String theProp;
     private int defaultVal;
-    private boolean defaultSet = false;
+    private boolean defaultSet;
 
     /**
      * Constructor that takes the name of the system property whose integer
@@ -110,4 +112,39 @@
             return defaultVal;
         return value;
     }
+
+    /**
+     * Convenience method to get a property without going through doPrivileged
+     * if no security manager is present. This is unsafe for inclusion in a
+     * public API but allowable here since this class is now encapsulated.
+     *
+     * @param theProp the name of the system property.
+     */
+    public static Integer getProperty(String theProp) {
+        if (System.getSecurityManager() == null) {
+            return Integer.getInteger(theProp);
+        } else {
+            return AccessController.doPrivileged(
+                    new GetIntegerAction(theProp));
+        }
+    }
+
+    /**
+     * Convenience method to get a property without going through doPrivileged
+     * if no security manager is present. This is unsafe for inclusion in a
+     * public API but allowable here since this class is now encapsulated.
+     *
+     * @param theProp the name of the system property.
+     * @param defaultVal the default value.
+     */
+    public static Integer getProperty(String theProp, int defaultVal) {
+        Integer value;
+        if (System.getSecurityManager() == null) {
+            value = Integer.getInteger(theProp);
+        } else {
+            value = AccessController.doPrivileged(
+                    new GetIntegerAction(theProp));
+        }
+        return (value != null) ? value : defaultVal;
+    }
 }
--- a/jdk/src/java.base/share/classes/sun/security/action/GetPropertyAction.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/security/action/GetPropertyAction.java	Wed Jul 05 21:37:42 2017 +0200
@@ -25,6 +25,10 @@
 
 package sun.security.action;
 
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Properties;
+
 /**
  * A convenience class for retrieving the string value of a system
  * property as a privileged action.
@@ -46,8 +50,7 @@
  * @since 1.2
  */
 
-public class GetPropertyAction
-        implements java.security.PrivilegedAction<String> {
+public class GetPropertyAction implements PrivilegedAction<String> {
     private String theProp;
     private String defaultVal;
 
@@ -84,4 +87,57 @@
         String value = System.getProperty(theProp);
         return (value == null) ? defaultVal : value;
     }
+
+    /**
+     * Convenience method to get a property without going through doPrivileged
+     * if no security manager is present. This is unsafe for inclusion in a
+     * public API but allowable here since this class is now encapsulated.
+     *
+     * @param theProp the name of the system property.
+     */
+    public static String getProperty(String theProp) {
+        if (System.getSecurityManager() == null) {
+            return System.getProperty(theProp);
+        } else {
+            return AccessController.doPrivileged(
+                    new GetPropertyAction(theProp));
+        }
+    }
+
+    /**
+     * Convenience method to get a property without going through doPrivileged
+     * if no security manager is present. This is unsafe for inclusion in a
+     * public API but allowable here since this class is now encapsulated.
+     *
+     * @param theProp the name of the system property.
+     * @param defaultVal the default value.
+     */
+    public static String getProperty(String theProp, String defaultVal) {
+        if (System.getSecurityManager() == null) {
+            return System.getProperty(theProp, defaultVal);
+        } else {
+            return AccessController.doPrivileged(
+                    new GetPropertyAction(theProp, defaultVal));
+        }
+    }
+
+    /**
+     * Convenience method to call <code>System.getProperties</code> without
+     * having to go through doPrivileged if no security manager is present.
+     * This is unsafe for inclusion in a public API but allowable here since
+     * this class is now encapsulated.
+     */
+    public static Properties getProperties() {
+        if (System.getSecurityManager() == null) {
+            return System.getProperties();
+        } else {
+            return AccessController.doPrivileged(
+                    new PrivilegedAction<Properties>() {
+                        public Properties run() {
+                            return System.getProperties();
+                        }
+                    }
+            );
+        }
+    }
 }
--- a/jdk/src/java.base/share/classes/sun/security/jca/ProviderConfig.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/security/jca/ProviderConfig.java	Wed Jul 05 21:37:42 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
@@ -236,9 +236,8 @@
                 if (debug != null) {
                     debug.println("Loading provider " + ProviderConfig.this);
                 }
-                ProviderLoader pl = new ProviderLoader();
                 try {
-                    Provider p = pl.load(provName);
+                    Provider p = ProviderLoader.INSTANCE.load(provName);
                     if (p != null) {
                         if (hasArgument()) {
                             p = p.configure(argument);
@@ -303,9 +302,11 @@
 
     // Inner class for loading security providers listed in java.security file
     private static final class ProviderLoader {
+        static final ProviderLoader INSTANCE = new ProviderLoader();
+
         private final ServiceLoader<Provider> services;
 
-        ProviderLoader() {
+        private ProviderLoader() {
             // VM should already been booted at this point, if not
             // - Only providers in java.base should be loaded, don't use
             //   ServiceLoader
--- a/jdk/src/java.base/share/classes/sun/security/provider/DSA.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/security/provider/DSA.java	Wed Jul 05 21:37:42 2017 +0200
@@ -106,6 +106,18 @@
         this.p1363Format = p1363Format;
     }
 
+    private static void checkKey(DSAParams params, int digestLen, String mdAlgo)
+        throws InvalidKeyException {
+        // FIPS186-3 states in sec4.2 that a hash function which provides
+        // a lower security strength than the (L, N) pair ordinarily should
+        // not be used.
+        int valueN = params.getQ().bitLength();
+        if (valueN > digestLen) {
+            throw new InvalidKeyException("The security strength of " +
+                mdAlgo + " digest algorithm is not sufficient for this key size");
+        }
+    }
+
     /**
      * Initialize the DSA object with a DSA private key.
      *
@@ -130,6 +142,12 @@
             throw new InvalidKeyException("DSA private key lacks parameters");
         }
 
+        // check key size against hash output size for signing
+        // skip this check for verification to minimize impact on existing apps
+        if (md.getAlgorithm() != "NullDigest20") {
+            checkKey(params, md.getDigestLength()*8, md.getAlgorithm());
+        }
+
         this.params = params;
         this.presetX = priv.getX();
         this.presetY = null;
@@ -160,7 +178,6 @@
         if (params == null) {
             throw new InvalidKeyException("DSA public key lacks parameters");
         }
-
         this.params = params;
         this.presetY = pub.getY();
         this.presetX = null;
@@ -406,20 +423,13 @@
         return t5.mod(q);
     }
 
-    // NOTE: This following impl is defined in FIPS 186-3 AppendixB.2.2.
-    // Original DSS algos such as SHA1withDSA and RawDSA uses a different
-    // algorithm defined in FIPS 186-1 Sec3.2, and thus need to override this.
+    // NOTE: This following impl is defined in FIPS 186-4 AppendixB.2.1.
     protected BigInteger generateK(BigInteger q) {
         SecureRandom random = getSigningRandom();
-        byte[] kValue = new byte[q.bitLength()/8];
+        byte[] kValue = new byte[(q.bitLength() + 7)/8 + 8];
 
-        while (true) {
-            random.nextBytes(kValue);
-            BigInteger k = new BigInteger(1, kValue).mod(q);
-            if (k.signum() > 0 && k.compareTo(q) < 0) {
-                return k;
-            }
-        }
+        random.nextBytes(kValue);
+        return new BigInteger(1, kValue).mod(q.subtract(BigInteger.ONE)).add(BigInteger.ONE);
     }
 
     // Use the application-specified SecureRandom Object if provided.
@@ -504,222 +514,10 @@
         }
     }
 
-    static class LegacyDSA extends DSA {
-        /* The random seed used to generate k */
-        private int[] kSeed;
-        /* The random seed used to generate k (specified by application) */
-        private byte[] kSeedAsByteArray;
-        /*
-         * The random seed used to generate k
-         * (prevent the same Kseed from being used twice in a row
-         */
-        private int[] kSeedLast;
-
-        public LegacyDSA(MessageDigest md) throws NoSuchAlgorithmException {
-            this(md, false);
-        }
-
-        private LegacyDSA(MessageDigest md, boolean p1363Format)
-                throws NoSuchAlgorithmException {
-            super(md, p1363Format);
-        }
-
-        @Deprecated
-        protected void engineSetParameter(String key, Object param) {
-            if (key.equals("KSEED")) {
-                if (param instanceof byte[]) {
-                    kSeed = byteArray2IntArray((byte[])param);
-                    kSeedAsByteArray = (byte[])param;
-                } else {
-                    debug("unrecognized param: " + key);
-                    throw new InvalidParameterException("kSeed not a byte array");
-                }
-            } else {
-                throw new InvalidParameterException("Unsupported parameter");
-            }
-        }
-
-        @Deprecated
-        protected Object engineGetParameter(String key) {
-           if (key.equals("KSEED")) {
-               return kSeedAsByteArray;
-           } else {
-               return null;
-           }
-        }
-
-        /*
-         * Please read bug report 4044247 for an alternative, faster,
-         * NON-FIPS approved method to generate K
-         */
-        @Override
-        protected BigInteger generateK(BigInteger q) {
-            BigInteger k = null;
-
-            // The application specified a kSeed for us to use.
-            // Note: we dis-allow usage of the same Kseed twice in a row
-            if (kSeed != null && !Arrays.equals(kSeed, kSeedLast)) {
-                k = generateKUsingKSeed(kSeed, q);
-                if (k.signum() > 0 && k.compareTo(q) < 0) {
-                    kSeedLast = kSeed.clone();
-                    return k;
-                }
-            }
-
-            // The application did not specify a Kseed for us to use.
-            // We'll generate a new Kseed by getting random bytes from
-            // a SecureRandom object.
-            SecureRandom random = getSigningRandom();
-
-            while (true) {
-                int[] seed = new int[5];
-
-                for (int i = 0; i < 5; i++) seed[i] = random.nextInt();
-
-                k = generateKUsingKSeed(seed, q);
-                if (k.signum() > 0 && k.compareTo(q) < 0) {
-                    kSeedLast = seed;
-                    return k;
-                }
-            }
-        }
-
-        /**
-         * Compute k for the DSA signature as defined in the original DSS,
-         * i.e. FIPS186.
-         *
-         * @param seed the seed for generating k. This seed should be
-         * secure. This is what is referred to as the KSEED in the DSA
-         * specification.
-         *
-         * @param g the g parameter from the DSA key pair.
-         */
-        private BigInteger generateKUsingKSeed(int[] seed, BigInteger q) {
-
-            // check out t in the spec.
-            int[] t = { 0xEFCDAB89, 0x98BADCFE, 0x10325476,
-                        0xC3D2E1F0, 0x67452301 };
-            //
-            int[] tmp = SHA_7(seed, t);
-            byte[] tmpBytes = new byte[tmp.length * 4];
-            for (int i = 0; i < tmp.length; i++) {
-                int k = tmp[i];
-                for (int j = 0; j < 4; j++) {
-                    tmpBytes[(i * 4) + j] = (byte) (k >>> (24 - (j * 8)));
-                }
-            }
-            BigInteger k = new BigInteger(1, tmpBytes).mod(q);
-            return k;
-        }
-
-        // Constants for each round
-        private static final int round1_kt = 0x5a827999;
-        private static final int round2_kt = 0x6ed9eba1;
-        private static final int round3_kt = 0x8f1bbcdc;
-        private static final int round4_kt = 0xca62c1d6;
-
-        /**
-         * Computes set 1 thru 7 of SHA-1 on m1. */
-        static int[] SHA_7(int[] m1, int[] h) {
-
-            int[] W = new int[80];
-            System.arraycopy(m1,0,W,0,m1.length);
-            int temp = 0;
-
-            for (int t = 16; t <= 79; t++){
-                temp = W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16];
-                W[t] = ((temp << 1) | (temp >>>(32 - 1)));
-            }
-
-            int a = h[0],b = h[1],c = h[2], d = h[3], e = h[4];
-            for (int i = 0; i < 20; i++) {
-                temp = ((a<<5) | (a>>>(32-5))) +
-                    ((b&c)|((~b)&d))+ e + W[i] + round1_kt;
-                e = d;
-                d = c;
-                c = ((b<<30) | (b>>>(32-30)));
-                b = a;
-                a = temp;
-            }
-
-            // Round 2
-            for (int i = 20; i < 40; i++) {
-                temp = ((a<<5) | (a>>>(32-5))) +
-                    (b ^ c ^ d) + e + W[i] + round2_kt;
-                e = d;
-                d = c;
-                c = ((b<<30) | (b>>>(32-30)));
-                b = a;
-                a = temp;
-            }
-
-            // Round 3
-            for (int i = 40; i < 60; i++) {
-                temp = ((a<<5) | (a>>>(32-5))) +
-                    ((b&c)|(b&d)|(c&d)) + e + W[i] + round3_kt;
-                e = d;
-                d = c;
-                c = ((b<<30) | (b>>>(32-30)));
-                b = a;
-                a = temp;
-            }
-
-            // Round 4
-            for (int i = 60; i < 80; i++) {
-                temp = ((a<<5) | (a>>>(32-5))) +
-                    (b ^ c ^ d) + e + W[i] + round4_kt;
-                e = d;
-                d = c;
-                c = ((b<<30) | (b>>>(32-30)));
-                b = a;
-                a = temp;
-            }
-            int[] md = new int[5];
-            md[0] = h[0] + a;
-            md[1] = h[1] + b;
-            md[2] = h[2] + c;
-            md[3] = h[3] + d;
-            md[4] = h[4] + e;
-            return md;
-        }
-
-        /*
-         * Utility routine for converting a byte array into an int array
-         */
-        private int[] byteArray2IntArray(byte[] byteArray) {
-
-            int j = 0;
-            byte[] newBA;
-            int mod = byteArray.length % 4;
-
-            // guarantee that the incoming byteArray is a multiple of 4
-            // (pad with 0's)
-            switch (mod) {
-            case 3:     newBA = new byte[byteArray.length + 1]; break;
-            case 2:     newBA = new byte[byteArray.length + 2]; break;
-            case 1:     newBA = new byte[byteArray.length + 3]; break;
-            default:    newBA = new byte[byteArray.length + 0]; break;
-            }
-            System.arraycopy(byteArray, 0, newBA, 0, byteArray.length);
-
-            // copy each set of 4 bytes in the byte array into an integer
-            int[] newSeed = new int[newBA.length / 4];
-            for (int i = 0; i < newBA.length; i += 4) {
-                newSeed[j] = newBA[i + 3] & 0xFF;
-                newSeed[j] |= (newBA[i + 2] << 8) & 0xFF00;
-                newSeed[j] |= (newBA[i + 1] << 16) & 0xFF0000;
-                newSeed[j] |= (newBA[i + 0] << 24) & 0xFF000000;
-                j++;
-            }
-
-            return newSeed;
-        }
-    }
-
     /**
      * Standard SHA1withDSA implementation.
      */
-    public static final class SHA1withDSA extends LegacyDSA {
+    public static final class SHA1withDSA extends DSA {
         public SHA1withDSA() throws NoSuchAlgorithmException {
             super(MessageDigest.getInstance("SHA-1"));
         }
@@ -728,7 +526,7 @@
     /**
      * SHA1withDSA implementation that uses the IEEE P1363 format.
      */
-    public static final class SHA1withDSAinP1363Format extends LegacyDSA {
+    public static final class SHA1withDSAinP1363Format extends DSA {
         public SHA1withDSAinP1363Format() throws NoSuchAlgorithmException {
             super(MessageDigest.getInstance("SHA-1"), true);
         }
@@ -741,7 +539,7 @@
      * not, a SignatureException is thrown when sign()/verify() is called
      * per JCA spec.
      */
-    static class Raw extends LegacyDSA {
+    static class Raw extends DSA {
         // Internal special-purpose MessageDigest impl for RawDSA
         // Only override whatever methods used
         // NOTE: no clone support
--- a/jdk/src/java.base/share/classes/sun/security/provider/DSAKeyFactory.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/security/provider/DSAKeyFactory.java	Wed Jul 05 21:37:42 2017 +0200
@@ -70,8 +70,7 @@
          * By default this is false.
          * This incompatibility was introduced by 4532506.
          */
-        String prop = AccessController.doPrivileged
-                (new GetPropertyAction(SERIAL_PROP, null));
+        String prop = GetPropertyAction.getProperty(SERIAL_PROP);
         SERIAL_INTEROP = "true".equalsIgnoreCase(prop);
     }
 
--- a/jdk/src/java.base/share/classes/sun/security/rsa/RSAKeyFactory.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/security/rsa/RSAKeyFactory.java	Wed Jul 05 21:37:42 2017 +0200
@@ -84,9 +84,8 @@
     public static final int MAX_RESTRICTED_EXPLEN = 64;
 
     private static final boolean restrictExpLen =
-        "true".equalsIgnoreCase(AccessController.doPrivileged(
-            new GetPropertyAction(
-                "sun.security.rsa.restrictRSAExponent", "true")));
+        "true".equalsIgnoreCase(GetPropertyAction.getProperty(
+                "sun.security.rsa.restrictRSAExponent", "true"));
 
     // instance used for static translateKey();
     private static final RSAKeyFactory INSTANCE = new RSAKeyFactory();
--- a/jdk/src/java.base/share/classes/sun/security/ssl/ClientKeyExchangeService.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/ClientKeyExchangeService.java	Wed Jul 05 21:37:42 2017 +0200
@@ -50,10 +50,7 @@
                 providers = new HashMap<>();
 
         static {
-            final String key = "java.home";
-            String path = AccessController.doPrivileged(
-                    new GetPropertyAction(key), null,
-                    new PropertyPermission(key, "read"));
+            String path = GetPropertyAction.getProperty("java.home");
             ServiceLoader<ClientKeyExchangeService> sc =
                     AccessController.doPrivileged(
                             (PrivilegedAction<ServiceLoader<ClientKeyExchangeService>>)
--- a/jdk/src/java.base/share/classes/sun/security/ssl/Debug.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/Debug.java	Wed Jul 05 21:37:42 2017 +0200
@@ -26,7 +26,6 @@
 package sun.security.ssl;
 
 import java.io.PrintStream;
-import java.security.AccessController;
 import java.util.Locale;
 
 import sun.security.util.HexDumpEncoder;
@@ -46,8 +45,7 @@
     private static String args;
 
     static {
-        args = java.security.AccessController.doPrivileged(
-            new GetPropertyAction("javax.net.debug", ""));
+        args = GetPropertyAction.getProperty("javax.net.debug", "");
         args = args.toLowerCase(Locale.ENGLISH);
         if (args.equals("help")) {
             Help();
@@ -184,8 +182,7 @@
      */
     static boolean getBooleanProperty(String propName, boolean defaultValue) {
         // if set, require value of either true or false
-        String b = AccessController.doPrivileged(
-                new GetPropertyAction(propName));
+        String b = GetPropertyAction.getProperty(propName);
         if (b == null) {
             return defaultValue;
         } else if (b.equalsIgnoreCase("false")) {
--- a/jdk/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java	Wed Jul 05 21:37:42 2017 +0200
@@ -656,8 +656,7 @@
         // the provider service. Instead, please handle the initialization
         // exception in the caller's constructor.
         static {
-            String property = AccessController.doPrivileged(
-                    new GetPropertyAction(PROPERTY_NAME));
+            String property = GetPropertyAction.getProperty(PROPERTY_NAME);
             if (property != null && property.length() != 0) {
                 // remove double quote marks from beginning/end of the property
                 if (property.length() > 1 && property.charAt(0) == '"' &&
--- a/jdk/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java	Wed Jul 05 21:37:42 2017 +0200
@@ -209,6 +209,12 @@
     Collection<SNIMatcher>      sniMatchers =
                                     Collections.<SNIMatcher>emptyList();
 
+    // Is the serverNames set to empty with SSLParameters.setServerNames()?
+    private boolean             noSniExtension = false;
+
+    // Is the sniMatchers set to empty with SSLParameters.setSNIMatchers()?
+    private boolean             noSniMatcher = false;
+
     // Configured application protocol values
     String[] applicationProtocols = new String[0];
 
@@ -642,6 +648,11 @@
         }
 
         super.connect(endpoint, timeout);
+
+        if (host == null || host.length() == 0) {
+            useImplicitHost(false);
+        }
+
         doneConnect();
     }
 
@@ -2098,41 +2109,62 @@
         outputRecord.setVersion(protocolVersion);
     }
 
+    //
+    // ONLY used by ClientHandshaker for the server hostname during handshaking
+    //
     synchronized String getHost() {
         // Note that the host may be null or empty for localhost.
         if (host == null || host.length() == 0) {
-            if (!trustNameService) {
-                // If the local name service is not trustworthy, reverse host
-                // name resolution should not be performed for endpoint
-                // identification.  Use the application original specified
-                // hostname or IP address instead.
-                host = getOriginalHostname(getInetAddress());
-            } else {
-                host = getInetAddress().getHostName();
-            }
+            useImplicitHost(true);
         }
 
         return host;
     }
 
     /*
-     * Get the original application specified hostname.
+     * Try to set and use the implicit specified hostname
      */
-    private static String getOriginalHostname(InetAddress inetAddress) {
-        /*
-         * Get the original hostname via jdk.internal.misc.SharedSecrets.
-         */
-        JavaNetInetAddressAccess jna = SharedSecrets.getJavaNetInetAddressAccess();
-        String originalHostname = jna.getOriginalHostName(inetAddress);
+    private synchronized void useImplicitHost(boolean noSniUpdate) {
 
-        /*
-         * If no application specified hostname, use the IP address.
-         */
-        if (originalHostname == null || originalHostname.length() == 0) {
-            originalHostname = inetAddress.getHostAddress();
+        // Note: If the local name service is not trustworthy, reverse
+        // host name resolution should not be performed for endpoint
+        // identification.  Use the application original specified
+        // hostname or IP address instead.
+
+        // Get the original hostname via jdk.internal.misc.SharedSecrets
+        InetAddress inetAddress = getInetAddress();
+        if (inetAddress == null) {      // not connected
+            return;
         }
 
-        return originalHostname;
+        JavaNetInetAddressAccess jna =
+                SharedSecrets.getJavaNetInetAddressAccess();
+        String originalHostname = jna.getOriginalHostName(inetAddress);
+        if ((originalHostname != null) &&
+                (originalHostname.length() != 0)) {
+
+            host = originalHostname;
+            if (!noSniUpdate && serverNames.isEmpty() && !noSniExtension) {
+                serverNames =
+                        Utilities.addToSNIServerNameList(serverNames, host);
+
+                if (!roleIsServer &&
+                        (handshaker != null) && !handshaker.started()) {
+                    handshaker.setSNIServerNames(serverNames);
+                }
+            }
+
+            return;
+        }
+
+        // No explicitly specified hostname, no server name indication.
+        if (!trustNameService) {
+            // The local name service is not trustworthy, use IP address.
+            host = inetAddress.getHostAddress();
+        } else {
+            // Use the underlying reverse host name resolution service.
+            host = getInetAddress().getHostName();
+        }
     }
 
     // ONLY used by HttpsClient to setup the URI specified hostname
@@ -2144,6 +2176,10 @@
         this.host = host;
         this.serverNames =
             Utilities.addToSNIServerNameList(this.serverNames, this.host);
+
+        if (!roleIsServer && (handshaker != null) && !handshaker.started()) {
+            handshaker.setSNIServerNames(serverNames);
+        }
     }
 
     /**
@@ -2533,8 +2569,21 @@
         // the super implementation does not handle the following parameters
         params.setEndpointIdentificationAlgorithm(identificationProtocol);
         params.setAlgorithmConstraints(algorithmConstraints);
-        params.setSNIMatchers(sniMatchers);
-        params.setServerNames(serverNames);
+
+        if (sniMatchers.isEmpty() && !noSniMatcher) {
+            // 'null' indicates none has been set
+            params.setSNIMatchers(null);
+        } else {
+            params.setSNIMatchers(sniMatchers);
+        }
+
+        if (serverNames.isEmpty() && !noSniExtension) {
+            // 'null' indicates none has been set
+            params.setServerNames(null);
+        } else {
+            params.setServerNames(serverNames);
+        }
+
         params.setUseCipherSuitesOrder(preferLocalCipherSuites);
         params.setMaximumPacketSize(maximumPacketSize);
         params.setApplicationProtocols(applicationProtocols);
@@ -2568,11 +2617,13 @@
 
         List<SNIServerName> sniNames = params.getServerNames();
         if (sniNames != null) {
+            noSniExtension = sniNames.isEmpty();
             serverNames = sniNames;
         }
 
         Collection<SNIMatcher> matchers = params.getSNIMatchers();
         if (matchers != null) {
+            noSniMatcher = matchers.isEmpty();
             sniMatchers = matchers;
         }
 
--- a/jdk/src/java.base/share/classes/sun/security/ssl/ServerHandshaker.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/ServerHandshaker.java	Wed Jul 05 21:37:42 2017 +0200
@@ -119,8 +119,8 @@
     private long statusRespTimeout;
 
     static {
-        String property = AccessController.doPrivileged(
-                    new GetPropertyAction("jdk.tls.ephemeralDHKeySize"));
+        String property =
+                GetPropertyAction.getProperty("jdk.tls.ephemeralDHKeySize");
         if (property == null || property.length() == 0) {
             useLegacyEphemeralDHKeys = false;
             useSmartEphemeralDHKeys = false;
--- a/jdk/src/java.base/share/classes/sun/security/ssl/StatusResponseManager.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/StatusResponseManager.java	Wed Jul 05 21:37:42 2017 +0200
@@ -73,8 +73,8 @@
                     DEFAULT_CACHE_LIFETIME));
         cacheLifetime = life > 0 ? life : 0;
 
-        String uriStr = AccessController.doPrivileged(
-                new GetPropertyAction("jdk.tls.stapling.responderURI"));
+        String uriStr =
+                GetPropertyAction.getProperty("jdk.tls.stapling.responderURI");
         URI tmpURI;
         try {
             tmpURI = ((uriStr != null && !uriStr.isEmpty()) ?
--- a/jdk/src/java.base/share/classes/sun/security/util/Debug.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/security/util/Debug.java	Wed Jul 05 21:37:42 2017 +0200
@@ -29,6 +29,7 @@
 import java.util.regex.Pattern;
 import java.util.regex.Matcher;
 import java.util.Locale;
+import sun.security.action.GetPropertyAction;
 
 /**
  * A utility class for debuging.
@@ -42,13 +43,10 @@
     private static String args;
 
     static {
-        args = java.security.AccessController.doPrivileged
-                (new sun.security.action.GetPropertyAction
-                ("java.security.debug"));
+        args = GetPropertyAction.getProperty("java.security.debug");
 
-        String args2 = java.security.AccessController.doPrivileged
-                (new sun.security.action.GetPropertyAction
-                ("java.security.auth.debug"));
+        String args2 =
+                GetPropertyAction.getProperty("java.security.auth.debug");
 
         if (args == null) {
             args = args2;
--- a/jdk/src/java.base/share/classes/sun/util/calendar/LocalGregorianCalendar.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/util/calendar/LocalGregorianCalendar.java	Wed Jul 05 21:37:42 2017 +0200
@@ -27,6 +27,7 @@
 
 import java.security.AccessController;
 import java.util.TimeZone;
+import sun.security.action.GetPropertyAction;
 
 /**
  *
@@ -142,8 +143,8 @@
         }
 
         // Append an era to the predefined eras if it's given by the property.
-        String prop = AccessController.doPrivileged(
-                new sun.security.action.GetPropertyAction("jdk.calendar.japanese.supplemental.era"));
+        String prop = GetPropertyAction
+                .getProperty("jdk.calendar.japanese.supplemental.era");
         if (prop != null) {
             Era era = parseEraEntry(prop);
             if (era != null) {
--- a/jdk/src/java.base/share/classes/sun/util/calendar/ZoneInfoFile.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/util/calendar/ZoneInfoFile.java	Wed Jul 05 21:37:42 2017 +0200
@@ -245,11 +245,12 @@
     };
 
     static {
-        String oldmapping = AccessController.doPrivileged(
-            new GetPropertyAction("sun.timezone.ids.oldmapping", "false")).toLowerCase(Locale.ROOT);
+        String oldmapping = GetPropertyAction
+                .getProperty("sun.timezone.ids.oldmapping", "false")
+                .toLowerCase(Locale.ROOT);
         USE_OLDMAPPING = (oldmapping.equals("yes") || oldmapping.equals("true"));
-        AccessController.doPrivileged(new PrivilegedAction<Object>() {
-            public Object run() {
+        AccessController.doPrivileged(new PrivilegedAction<Void>() {
+            public Void run() {
                 try {
                     String libDir = System.getProperty("java.home") + File.separator + "lib";
                     try (DataInputStream dis = new DataInputStream(
--- a/jdk/src/java.base/share/classes/sun/util/locale/provider/LocaleProviderAdapter.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/util/locale/provider/LocaleProviderAdapter.java	Wed Jul 05 21:37:42 2017 +0200
@@ -25,7 +25,6 @@
 
 package sun.util.locale.provider;
 
-import java.security.AccessController;
 import java.text.spi.BreakIteratorProvider;
 import java.text.spi.CollatorProvider;
 import java.text.spi.DateFormatProvider;
@@ -47,6 +46,7 @@
 import java.util.spi.LocaleNameProvider;
 import java.util.spi.LocaleServiceProvider;
 import java.util.spi.TimeZoneNameProvider;
+import sun.security.action.GetPropertyAction;
 import sun.util.spi.CalendarProvider;
 
 /**
@@ -116,8 +116,7 @@
         adapterCache = new ConcurrentHashMap<>();
 
     static {
-        String order = AccessController.doPrivileged(
-                           new sun.security.action.GetPropertyAction("java.locale.providers"));
+        String order = GetPropertyAction.getProperty("java.locale.providers");
         List<Type> typeList = new ArrayList<>();
 
         // Check user specified adapter preference
--- a/jdk/src/java.base/share/native/include/jvm.h	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/native/include/jvm.h	Wed Jul 05 21:37:42 2017 +0200
@@ -179,7 +179,6 @@
  */
 enum {
   JVM_STACKWALK_FILL_CLASS_REFS_ONLY       = 0x2,
-  JVM_STACKWALK_FILTER_FILL_IN_STACK_TRACE = 0x10,
   JVM_STACKWALK_SHOW_HIDDEN_FRAMES         = 0x20,
   JVM_STACKWALK_FILL_LIVE_STACK_FRAMES     = 0x100
 };
@@ -187,23 +186,15 @@
 JNIEXPORT jobject JNICALL
 JVM_CallStackWalk(JNIEnv *env, jobject stackStream, jlong mode,
                   jint skip_frames, jint frame_count, jint start_index,
-                  jobjectArray classes,
                   jobjectArray frames);
 
 JNIEXPORT jint JNICALL
 JVM_MoreStackWalk(JNIEnv *env, jobject stackStream, jlong mode, jlong anchor,
                   jint frame_count, jint start_index,
-                  jobjectArray classes,
                   jobjectArray frames);
 
 JNIEXPORT void JNICALL
-JVM_FillStackFrames(JNIEnv* env, jclass cls,
-                    jint start_index,
-                    jobjectArray stackFrames,
-                    jint from_index, jint toIndex);
-
-JNIEXPORT void JNICALL
-JVM_SetMethodInfo(JNIEnv* env, jobject frame);
+JVM_ToStackTraceElement(JNIEnv* env, jobject frame, jobject stackElement);
 
 JNIEXPORT jobjectArray JNICALL
 JVM_GetVmArguments(JNIEnv *env);
--- a/jdk/src/java.base/share/native/launcher/defines.h	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/native/launcher/defines.h	Wed Jul 05 21:37:42 2017 +0200
@@ -45,7 +45,11 @@
 
 #ifdef JAVA_ARGS
 #define HAS_JAVA_ARGS JNI_TRUE
-static const char* const_progname = "java";
+#ifdef PROGNAME
+static const char* const_progname = PROGNAME;
+#else
+static char* const_progname = NULL;
+#endif
 static const char* const_jargs[] = JAVA_ARGS;
 /*
  * ApplicationHome is prepended to each of these entries; the resulting
@@ -59,11 +63,7 @@
 #endif /* APP_CLASSPATH */
 #else  /* !JAVA_ARGS */
 #define HAS_JAVA_ARGS JNI_FALSE
-#ifdef PROGNAME
-static const char* const_progname = PROGNAME;
-#else
-static char* const_progname = NULL;
-#endif
+static const char* const_progname = "java";
 static const char** const_jargs = NULL;
 static const char* const_appclasspath[] = { NULL };
 #endif /* JAVA_ARGS */
--- a/jdk/src/java.base/share/native/libjava/StackFrameInfo.c	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/native/libjava/StackFrameInfo.c	Wed Jul 05 21:37:42 2017 +0200
@@ -38,22 +38,10 @@
 
 /*
  * Class:     java_lang_StackFrameInfo
- * Method:    fillInStackFrames
- * Signature: (I[Ljava/lang/Object;[Ljava/lang/Object;II)V
+ * Method:    toStackTraceElement0
+ * Signature: (Ljava/lang/StackTraceElement;)V
  */
-JNIEXPORT void JNICALL Java_java_lang_StackFrameInfo_fillInStackFrames
-  (JNIEnv *env, jclass dummy, jint startIndex,
-   jobjectArray stackFrames, jint fromIndex, jint toIndex) {
-    JVM_FillStackFrames(env, dummy, startIndex,
-                        stackFrames, fromIndex, toIndex);
+JNIEXPORT void JNICALL Java_java_lang_StackFrameInfo_toStackTraceElement0
+  (JNIEnv *env, jobject stackframeinfo, jobject stacktraceinfo) {
+     JVM_ToStackTraceElement(env, stackframeinfo, stacktraceinfo);
 }
-
-/*
- * Class:     java_lang_StackFrameInfo
- * Method:    setMethodInfo
- * Signature: (Ljava/lang/Class;)V
- */
-JNIEXPORT void JNICALL Java_java_lang_StackFrameInfo_setMethodInfo
-  (JNIEnv *env, jobject stackframeinfo) {
-     JVM_SetMethodInfo(env, stackframeinfo);
-}
--- a/jdk/src/java.base/share/native/libjava/StackStreamFactory.c	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/native/libjava/StackStreamFactory.c	Wed Jul 05 21:37:42 2017 +0200
@@ -45,7 +45,6 @@
   (JNIEnv *env, jclass dummy)
 {
    return JVM_STACKWALK_FILL_CLASS_REFS_ONLY == java_lang_StackStreamFactory_FILL_CLASS_REFS_ONLY &&
-          JVM_STACKWALK_FILTER_FILL_IN_STACK_TRACE == java_lang_StackStreamFactory_FILTER_FILL_IN_STACKTRACE &&
           JVM_STACKWALK_SHOW_HIDDEN_FRAMES == java_lang_StackStreamFactory_SHOW_HIDDEN_FRAMES &&
           JVM_STACKWALK_FILL_LIVE_STACK_FRAMES == java_lang_StackStreamFactory_FILL_LIVE_STACK_FRAMES;
 }
@@ -53,26 +52,26 @@
 /*
  * Class:     java_lang_StackStreamFactory_AbstractStackWalker
  * Method:    callStackWalk
- * Signature: (JIII[Ljava/lang/Class;[Ljava/lang/StackWalker/StackFrame;)Ljava/lang/Object;
+ * Signature: (JIII[Ljava/lang/Object;)Ljava/lang/Object;
  */
 JNIEXPORT jobject JNICALL Java_java_lang_StackStreamFactory_00024AbstractStackWalker_callStackWalk
   (JNIEnv *env, jobject stackstream, jlong mode, jint skipFrames, jint batchSize, jint startIndex,
-   jobjectArray classes, jobjectArray frames)
+   jobjectArray frames)
 {
     return JVM_CallStackWalk(env, stackstream, mode, skipFrames, batchSize,
-                             startIndex, classes, frames);
+                             startIndex, frames);
 }
 
 /*
  * Class:     java_lang_StackStreamFactory_AbstractStackWalker
  * Method:    fetchStackFrames
- * Signature: (JJII[Ljava/lang/Class;[Ljava/lang/StackWalker/StackFrame;)I
+ * Signature: (JJII[Ljava/lang/Object;)I
  */
 JNIEXPORT jint JNICALL Java_java_lang_StackStreamFactory_00024AbstractStackWalker_fetchStackFrames
   (JNIEnv *env, jobject stackstream, jlong mode, jlong anchor,
    jint batchSize, jint startIndex,
-   jobjectArray classes, jobjectArray frames)
+   jobjectArray frames)
 {
     return JVM_MoreStackWalk(env, stackstream, mode, anchor, batchSize,
-                             startIndex, classes, frames);
+                             startIndex, frames);
 }
--- a/jdk/src/java.base/share/native/libjimage/jimage.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/native/libjimage/jimage.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -207,7 +207,30 @@
         if (!(*visitor)(image, module, "9", parent, base, extension, arg)) {
             break;
         }
-
     }
 }
 
+/*
+ * JIMAGE_ResourcePath- Given an open image file, a location reference, a buffer
+ * and a maximum buffer size, copy the path of the resource into the buffer.
+ * Returns false if not a valid location reference.
+ *
+ * Ex.
+ *   JImageLocationRef location = ...
+ *   char path[JIMAGE_MAX_PATH];
+ *    (*JImageResourcePath)(image, location, path, JIMAGE_MAX_PATH);
+ */
+extern "C" bool JIMAGE_ResourcePath(JImageFile* image, JImageLocationRef locationRef,
+                                    char* path, size_t max) {
+    ImageFileReader* imageFile = (ImageFileReader*) image;
+
+    u4 offset = (u4) locationRef;
+    if (offset >= imageFile->locations_size()) {
+        return false;
+    }
+
+    ImageLocation location(imageFile->get_location_offset_data(offset));
+    imageFile->location_path(location, path, max);
+
+    return true;
+}
--- a/jdk/src/java.base/share/native/libjimage/jimage.hpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/share/native/libjimage/jimage.hpp	Wed Jul 05 21:37:42 2017 +0200
@@ -37,11 +37,13 @@
 typedef jlong JImageLocationRef;
 
 // Max path length limit independent of platform.  Windows max path is 1024,
-// other platforms use 4096.  The JCK fails several tests when 1024 is used.
+// other platforms use 4096.
 #define JIMAGE_MAX_PATH 4096
 
 // JImage Error Codes
 
+// Resource was not found
+#define JIMAGE_NOT_FOUND (0)
 // The image file is not prefixed with 0xCAFEDADA
 #define JIMAGE_BAD_MAGIC (-1)
 // The image file does not have a compatible (translatable) version
@@ -184,3 +186,20 @@
 
 typedef void (*JImageResourceIterator_t)(JImageFile* jimage,
         JImageResourceVisitor_t visitor, void* arg);
+
+/*
+ * JIMAGE_ResourcePath- Given an open image file, a location reference, a buffer
+ * and a maximum buffer size, copy the path of the resource into the buffer.
+ * Returns false if not a valid location reference.
+ *
+ * Ex.
+ *   JImageLocationRef location = ...
+ *   char path[JIMAGE_MAX_PATH];
+ *    (*JImageResourcePath)(image, location, path, JIMAGE_MAX_PATH);
+ */
+extern "C" bool JIMAGE_ResourcePath(JImageFile* image, JImageLocationRef locationRef,
+                                    char* path, size_t max);
+
+typedef bool (*JImage_ResourcePath_t)(JImageFile* jimage, JImageLocationRef location,
+        char* buffer, jlong size);
+
--- a/jdk/src/java.base/solaris/classes/sun/nio/fs/SolarisFileSystem.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/solaris/classes/sun/nio/fs/SolarisFileSystem.java	Wed Jul 05 21:37:42 2017 +0200
@@ -28,7 +28,6 @@
 import java.nio.file.*;
 import java.io.IOException;
 import java.util.*;
-import java.security.AccessController;
 import sun.security.action.GetPropertyAction;
 import static sun.nio.fs.SolarisNativeDispatcher.*;
 
@@ -43,8 +42,7 @@
         super(provider, dir);
 
         // check os.version
-        String osversion = AccessController
-            .doPrivileged(new GetPropertyAction("os.version"));
+        String osversion = GetPropertyAction.getProperty("os.version");
         String[] vers = Util.split(osversion, '.');
         assert vers.length >= 2;
         int majorVersion = Integer.parseInt(vers[0]);
--- a/jdk/src/java.base/solaris/classes/sun/nio/fs/SolarisFileSystemProvider.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/solaris/classes/sun/nio/fs/SolarisFileSystemProvider.java	Wed Jul 05 21:37:42 2017 +0200
@@ -29,7 +29,6 @@
 import java.nio.file.attribute.*;
 import java.nio.file.spi.FileTypeDetector;
 import java.io.IOException;
-import java.security.AccessController;
 import sun.security.action.GetPropertyAction;
 
 /**
@@ -85,8 +84,8 @@
 
     @Override
     FileTypeDetector getFileTypeDetector() {
-        Path userMimeTypes = Paths.get(AccessController.doPrivileged(
-            new GetPropertyAction("user.home")), ".mime.types");
+        Path userMimeTypes = Paths.get(
+            GetPropertyAction.getProperty("user.home"), ".mime.types");
         Path etcMimeTypes = Paths.get("/etc/mime.types");
 
         return chain(new GioFileTypeDetector(),
--- a/jdk/src/java.base/unix/classes/java/io/UnixFileSystem.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/unix/classes/java/io/UnixFileSystem.java	Wed Jul 05 21:37:42 2017 +0200
@@ -25,7 +25,7 @@
 
 package java.io;
 
-import java.security.AccessController;
+import java.util.Properties;
 import sun.security.action.GetPropertyAction;
 
 
@@ -36,12 +36,10 @@
     private final String javaHome;
 
     public UnixFileSystem() {
-        slash = AccessController.doPrivileged(
-            new GetPropertyAction("file.separator")).charAt(0);
-        colon = AccessController.doPrivileged(
-            new GetPropertyAction("path.separator")).charAt(0);
-        javaHome = AccessController.doPrivileged(
-            new GetPropertyAction("java.home"));
+        Properties props = GetPropertyAction.getProperties();
+        slash = props.getProperty("file.separator").charAt(0);
+        colon = props.getProperty("path.separator").charAt(0);
+        javaHome = props.getProperty("java.home");
     }
 
 
--- a/jdk/src/java.base/unix/classes/java/lang/ProcessImpl.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/unix/classes/java/lang/ProcessImpl.java	Wed Jul 05 21:37:42 2017 +0200
@@ -46,8 +46,10 @@
 import java.security.PrivilegedAction;
 import java.security.PrivilegedActionException;
 import java.security.PrivilegedExceptionAction;
+import java.util.Properties;
 import jdk.internal.misc.JavaIOFileDescriptorAccess;
 import jdk.internal.misc.SharedSecrets;
+import sun.security.action.GetPropertyAction;
 
 /**
  * java.lang.Process subclass in the UNIX environment.
@@ -123,11 +125,9 @@
         }
 
         String helperPath() {
-            return AccessController.doPrivileged(
-                (PrivilegedAction<String>) () ->
-                    helperPath(System.getProperty("java.home"),
-                               System.getProperty("os.arch"))
-            );
+            Properties props = GetPropertyAction.getProperties();
+            return helperPath(props.getProperty("java.home"),
+                              props.getProperty("os.arch"));
         }
 
         LaunchMechanism launchMechanism() {
@@ -159,9 +159,7 @@
         }
 
         static Platform get() {
-            String osName = AccessController.doPrivileged(
-                (PrivilegedAction<String>) () -> System.getProperty("os.name")
-            );
+            String osName = GetPropertyAction.getProperty("os.name");
 
             if (osName.equals("Linux")) { return LINUX; }
             if (osName.contains("OS X")) { return BSD; }
--- a/jdk/src/java.base/unix/classes/java/net/DefaultDatagramSocketImplFactory.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/unix/classes/java/net/DefaultDatagramSocketImplFactory.java	Wed Jul 05 21:37:42 2017 +0200
@@ -24,7 +24,7 @@
  */
 package java.net;
 
-import java.security.AccessController;
+import sun.security.action.GetPropertyAction;
 
 /**
  * This class defines a factory for creating DatagramSocketImpls. It defaults
@@ -40,8 +40,7 @@
     static {
         String prefix = null;
         try {
-            prefix = AccessController.doPrivileged(
-                new sun.security.action.GetPropertyAction("impl.prefix", null));
+            prefix = GetPropertyAction.getProperty("impl.prefix", null);
             if (prefix != null)
                 prefixImplClass = Class.forName("java.net."+prefix+"DatagramSocketImpl");
         } catch (Exception e) {
--- a/jdk/src/java.base/unix/classes/sun/net/sdp/SdpProvider.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/unix/classes/sun/net/sdp/SdpProvider.java	Wed Jul 05 21:37:42 2017 +0200
@@ -34,7 +34,6 @@
 import java.io.FileDescriptor;
 import java.io.IOException;
 import java.io.PrintStream;
-import java.security.AccessController;
 
 import sun.net.sdp.SdpSupport;
 import sun.security.action.GetPropertyAction;
@@ -57,8 +56,7 @@
 
     public SdpProvider() {
         // if this property is not defined then there is nothing to do.
-        String file = AccessController.doPrivileged(
-            new GetPropertyAction("com.sun.sdp.conf"));
+        String file = GetPropertyAction.getProperty("com.sun.sdp.conf");
         if (file == null) {
             this.enabled = false;
             this.rules = null;
@@ -77,8 +75,7 @@
 
         // check if debugging is enabled
         PrintStream out = null;
-        String logfile = AccessController.doPrivileged(
-            new GetPropertyAction("com.sun.sdp.debug"));
+        String logfile = GetPropertyAction.getProperty("com.sun.sdp.debug");
         if (logfile != null) {
             out = System.out;
             if (logfile.length() > 0) {
--- a/jdk/src/java.base/unix/classes/sun/net/www/protocol/http/ntlm/NTLMAuthentication.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/unix/classes/sun/net/www/protocol/http/ntlm/NTLMAuthentication.java	Wed Jul 05 21:37:42 2017 +0200
@@ -39,6 +39,7 @@
 import sun.net.www.protocol.http.AuthenticationInfo;
 import sun.net.www.protocol.http.AuthScheme;
 import sun.net.www.protocol.http.HttpURLConnection;
+import sun.security.action.GetPropertyAction;
 
 /**
  * NTLMAuthentication:
@@ -73,12 +74,9 @@
         NTLMAuthenticationCallback.getNTLMAuthenticationCallback();
 
     private String hostname;
-    private static String defaultDomain; /* Domain to use if not specified by user */
-
-    static {
-        defaultDomain = java.security.AccessController.doPrivileged(
-            new sun.security.action.GetPropertyAction("http.auth.ntlm.domain", ""));
-    };
+    /* Domain to use if not specified by user */
+    private static String defaultDomain =
+            GetPropertyAction.getProperty("http.auth.ntlm.domain", "");
 
     public static boolean supportsTransparentAuth () {
         return false;
@@ -143,8 +141,7 @@
         password = pw.getPassword();
         init0();
         try {
-            String version = java.security.AccessController.doPrivileged(
-                    new sun.security.action.GetPropertyAction("ntlm.version"));
+            String version = GetPropertyAction.getProperty("ntlm.version");
             client = new Client(version, hostname, username, ntdomain, password);
         } catch (NTLMException ne) {
             try {
--- a/jdk/src/java.base/unix/classes/sun/nio/ch/DefaultAsynchronousChannelProvider.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/unix/classes/sun/nio/ch/DefaultAsynchronousChannelProvider.java	Wed Jul 05 21:37:42 2017 +0200
@@ -26,7 +26,6 @@
 package sun.nio.ch;
 
 import java.nio.channels.spi.AsynchronousChannelProvider;
-import java.security.AccessController;
 import sun.security.action.GetPropertyAction;
 
 /**
@@ -60,8 +59,7 @@
      * Returns the default AsynchronousChannelProvider.
      */
     public static AsynchronousChannelProvider create() {
-        String osname = AccessController
-            .doPrivileged(new GetPropertyAction("os.name"));
+        String osname = GetPropertyAction.getProperty("os.name");
         if (osname.equals("SunOS"))
             return createProvider("sun.nio.ch.SolarisAsynchronousChannelProvider");
         if (osname.equals("Linux"))
--- a/jdk/src/java.base/unix/classes/sun/nio/ch/InheritedChannel.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/unix/classes/sun/nio/ch/InheritedChannel.java	Wed Jul 05 21:37:42 2017 +0200
@@ -168,7 +168,7 @@
         Class<?> paramTypes[] = { int.class };
         Constructor<?> ctr = Reflect.lookupConstructor("java.io.FileDescriptor",
                                                        paramTypes);
-        Object args[] = { new Integer(fdVal) };
+        Object args[] = { Integer.valueOf(fdVal) };
         FileDescriptor fd = (FileDescriptor)Reflect.invoke(ctr, args);
 
 
--- a/jdk/src/java.base/unix/classes/sun/nio/ch/UnixAsynchronousSocketChannelImpl.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/unix/classes/sun/nio/ch/UnixAsynchronousSocketChannelImpl.java	Wed Jul 05 21:37:42 2017 +0200
@@ -31,7 +31,6 @@
 import java.util.concurrent.*;
 import java.io.IOException;
 import java.io.FileDescriptor;
-import java.security.AccessController;
 import sun.net.NetHooks;
 import sun.security.action.GetPropertyAction;
 
@@ -47,8 +46,8 @@
 
     private static final boolean disableSynchronousRead;
     static {
-        String propValue = AccessController.doPrivileged(
-            new GetPropertyAction("sun.nio.ch.disableSynchronousRead", "false"));
+        String propValue = GetPropertyAction
+                .getProperty("sun.nio.ch.disableSynchronousRead", "false");
         disableSynchronousRead = (propValue.length() == 0) ?
             true : Boolean.valueOf(propValue);
     }
--- a/jdk/src/java.base/unix/classes/sun/nio/fs/DefaultFileSystemProvider.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/unix/classes/sun/nio/fs/DefaultFileSystemProvider.java	Wed Jul 05 21:37:42 2017 +0200
@@ -26,7 +26,6 @@
 package sun.nio.fs;
 
 import java.nio.file.spi.FileSystemProvider;
-import java.security.AccessController;
 import sun.security.action.GetPropertyAction;
 
 /**
@@ -55,8 +54,7 @@
      * Returns the default FileSystemProvider.
      */
     public static FileSystemProvider create() {
-        String osname = AccessController
-            .doPrivileged(new GetPropertyAction("os.name"));
+        String osname = GetPropertyAction.getProperty("os.name");
         if (osname.equals("SunOS"))
             return createProvider("sun.nio.fs.SolarisFileSystemProvider");
         if (osname.equals("Linux"))
--- a/jdk/src/java.base/unix/classes/sun/nio/fs/UnixFileSystem.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/unix/classes/sun/nio/fs/UnixFileSystem.java	Wed Jul 05 21:37:42 2017 +0200
@@ -31,7 +31,6 @@
 import java.io.IOException;
 import java.util.*;
 import java.util.regex.Pattern;
-import java.security.AccessController;
 import sun.security.action.GetPropertyAction;
 
 /**
@@ -57,8 +56,8 @@
         // if process-wide chdir is allowed or default directory is not the
         // process working directory then paths must be resolved against the
         // default directory.
-        String propValue = AccessController.doPrivileged(
-            new GetPropertyAction("sun.nio.fs.chdirAllowed", "false"));
+        String propValue = GetPropertyAction
+                .getProperty("sun.nio.fs.chdirAllowed", "false");
         boolean chdirAllowed = (propValue.length() == 0) ?
             true : Boolean.valueOf(propValue);
         if (chdirAllowed) {
--- a/jdk/src/java.base/windows/classes/java/io/WinNTFileSystem.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/windows/classes/java/io/WinNTFileSystem.java	Wed Jul 05 21:37:42 2017 +0200
@@ -25,8 +25,8 @@
 
 package java.io;
 
-import java.security.AccessController;
 import java.util.Locale;
+import java.util.Properties;
 import sun.security.action.GetPropertyAction;
 
 /**
@@ -42,10 +42,9 @@
     private final char semicolon;
 
     public WinNTFileSystem() {
-        slash = AccessController.doPrivileged(
-            new GetPropertyAction("file.separator")).charAt(0);
-        semicolon = AccessController.doPrivileged(
-            new GetPropertyAction("path.separator")).charAt(0);
+        Properties props = GetPropertyAction.getProperties();
+        slash = props.getProperty("file.separator").charAt(0);
+        semicolon = props.getProperty("path.separator").charAt(0);
         altSlash = (this.slash == '\\') ? '/' : '\\';
     }
 
--- a/jdk/src/java.base/windows/classes/java/net/DefaultDatagramSocketImplFactory.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/windows/classes/java/net/DefaultDatagramSocketImplFactory.java	Wed Jul 05 21:37:42 2017 +0200
@@ -24,8 +24,7 @@
  */
 package java.net;
 
-import java.security.AccessController;
-import java.security.PrivilegedAction;
+import java.util.Properties;
 import sun.security.action.GetPropertyAction;
 
 /**
@@ -57,12 +56,11 @@
     static {
         Class<?> prefixImplClassLocal = null;
 
+        Properties props = GetPropertyAction.getProperties();
         preferIPv4Stack = Boolean.parseBoolean(
-                AccessController.doPrivileged(
-                        new GetPropertyAction("java.net.preferIPv4Stack")));
+                props.getProperty("java.net.preferIPv4Stack"));
 
-        String exclBindProp = AccessController.doPrivileged(
-                new GetPropertyAction("sun.net.useExclusiveBind", ""));
+        String exclBindProp = props.getProperty("sun.net.useExclusiveBind", "");
         exclusiveBind = (exclBindProp.isEmpty())
                 ? true
                 : Boolean.parseBoolean(exclBindProp);
@@ -70,8 +68,7 @@
         // impl.prefix
         String prefix = null;
         try {
-            prefix = AccessController.doPrivileged(
-                new GetPropertyAction("impl.prefix", null));
+            prefix = props.getProperty("impl.prefix");
             if (prefix != null)
                 prefixImplClassLocal = Class.forName("java.net."+prefix+"DatagramSocketImpl");
         } catch (Exception e) {
--- a/jdk/src/java.base/windows/classes/java/net/DualStackPlainDatagramSocketImpl.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/windows/classes/java/net/DualStackPlainDatagramSocketImpl.java	Wed Jul 05 21:37:42 2017 +0200
@@ -220,7 +220,7 @@
             case IP_TOS :
             case SO_RCVBUF :
             case SO_SNDBUF :
-                returnValue = new Integer(value);
+                returnValue = Integer.valueOf(value);
                 break;
             default: /* shouldn't get here */
                 throw new SocketException("Option not supported");
--- a/jdk/src/java.base/windows/classes/sun/net/www/protocol/http/ntlm/NTLMAuthentication.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/windows/classes/sun/net/www/protocol/http/ntlm/NTLMAuthentication.java	Wed Jul 05 21:37:42 2017 +0200
@@ -34,6 +34,7 @@
 import sun.net.www.protocol.http.AuthenticationInfo;
 import sun.net.www.protocol.http.AuthScheme;
 import sun.net.www.protocol.http.HttpURLConnection;
+import sun.security.action.GetPropertyAction;
 
 /**
  * NTLMAuthentication:
@@ -52,9 +53,8 @@
     private static String defaultDomain; /* Domain to use if not specified by user */
 
     static {
-        defaultDomain = java.security.AccessController.doPrivileged(
-            new sun.security.action.GetPropertyAction("http.auth.ntlm.domain",
-                                                      "domain"));
+        defaultDomain = GetPropertyAction.getProperty("http.auth.ntlm.domain",
+                                                      "domain");
     };
 
     private void init0() {
--- a/jdk/src/java.base/windows/classes/sun/nio/ch/FileDispatcherImpl.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/windows/classes/sun/nio/ch/FileDispatcherImpl.java	Wed Jul 05 21:37:42 2017 +0200
@@ -27,9 +27,9 @@
 
 import java.io.FileDescriptor;
 import java.io.IOException;
-import java.security.PrivilegedAction;
 import jdk.internal.misc.SharedSecrets;
 import jdk.internal.misc.JavaIOFileDescriptorAccess;
+import sun.security.action.GetPropertyAction;
 
 class FileDispatcherImpl extends FileDispatcher {
 
@@ -119,13 +119,8 @@
     }
 
     static boolean isFastFileTransferRequested() {
-        String fileTransferProp = java.security.AccessController.doPrivileged(
-            new PrivilegedAction<String>() {
-                @Override
-                public String run() {
-                    return System.getProperty("jdk.nio.enableFastFileTransfer");
-                }
-            });
+        String fileTransferProp = GetPropertyAction
+                .getProperty("jdk.nio.enableFastFileTransfer");
         boolean enable;
         if ("".equals(fileTransferProp)) {
             enable = true;
--- a/jdk/src/java.base/windows/classes/sun/nio/ch/WindowsSelectorImpl.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/windows/classes/sun/nio/ch/WindowsSelectorImpl.java	Wed Jul 05 21:37:42 2017 +0200
@@ -87,13 +87,13 @@
     private static final class FdMap extends HashMap<Integer, MapEntry> {
         static final long serialVersionUID = 0L;
         private MapEntry get(int desc) {
-            return get(new Integer(desc));
+            return get(Integer.valueOf(desc));
         }
         private MapEntry put(SelectionKeyImpl ski) {
-            return put(new Integer(ski.channel.getFDVal()), new MapEntry(ski));
+            return put(Integer.valueOf(ski.channel.getFDVal()), new MapEntry(ski));
         }
         private MapEntry remove(SelectionKeyImpl ski) {
-            Integer fd = new Integer(ski.channel.getFDVal());
+            Integer fd = Integer.valueOf(ski.channel.getFDVal());
             MapEntry x = get(fd);
             if ((x != null) && (x.ski.channel == ski.channel))
                 return remove(fd);
--- a/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsFileAttributes.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsFileAttributes.java	Wed Jul 05 21:37:42 2017 +0200
@@ -27,7 +27,6 @@
 
 import java.nio.file.attribute.*;
 import java.util.concurrent.TimeUnit;
-import java.security.AccessController;
 import jdk.internal.misc.Unsafe;
 import sun.security.action.GetPropertyAction;
 
@@ -115,8 +114,8 @@
     // indicates if accurate metadata is required (interesting on NTFS only)
     private static final boolean ensureAccurateMetadata;
     static {
-        String propValue = AccessController.doPrivileged(
-            new GetPropertyAction("sun.nio.fs.ensureAccurateMetadata", "false"));
+        String propValue = GetPropertyAction
+                .getProperty("sun.nio.fs.ensureAccurateMetadata", "false");
         ensureAccurateMetadata = (propValue.length() == 0) ?
             true : Boolean.valueOf(propValue);
     }
--- a/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaFileSystemModel.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaFileSystemModel.java	Wed Jul 05 21:37:42 2017 +0200
@@ -35,7 +35,6 @@
 import javax.swing.filechooser.FileSystemView;
 import javax.swing.table.AbstractTableModel;
 
-import sun.misc.ManagedLocalsThread;
 /**
  * NavServices-like implementation of a file Table
  *
@@ -393,7 +392,7 @@
             this.currentDirectory = currentDirectory;
             this.fid = fid;
             String name = "Aqua L&F File Loading Thread";
-            this.loadThread = new ManagedLocalsThread(this, name);
+            this.loadThread = new Thread(null, this, name, 0, false);
             this.loadThread.start();
         }
 
--- a/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaInternalFrameDockIconUI.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaInternalFrameDockIconUI.java	Wed Jul 05 21:37:42 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
@@ -40,28 +40,28 @@
  * From MacDockIconUI
  *
  * A JRSUI L&F implementation of JInternalFrame.JDesktopIcon
- * @author
- * @version
  */
-public class AquaInternalFrameDockIconUI extends DesktopIconUI implements MouseListener, MouseMotionListener, ComponentListener {
-    private static final String CACHED_FRAME_ICON_KEY = "apple.laf.internal.frameIcon";
+public final class AquaInternalFrameDockIconUI extends DesktopIconUI
+        implements MouseListener, MouseMotionListener {
 
-    protected JInternalFrame.JDesktopIcon fDesktopIcon;
-    protected JInternalFrame fFrame;
-    protected ScaledImageLabel fIconPane;
-    protected DockLabel fDockLabel;
-    protected boolean fTrackingIcon = false;
+    private JInternalFrame.JDesktopIcon fDesktopIcon;
+    private JInternalFrame fFrame;
+    private ScaledImageLabel fIconPane;
+    private DockLabel fDockLabel;
+    private boolean fTrackingIcon;
 
     public static ComponentUI createUI(final JComponent c) {
         return new AquaInternalFrameDockIconUI();
     }
 
+    @Override
     public void installUI(final JComponent c) {
         fDesktopIcon = (JInternalFrame.JDesktopIcon)c;
         installComponents();
         installListeners();
     }
 
+    @Override
     public void uninstallUI(final JComponent c) {
         uninstallComponents();
         uninstallListeners();
@@ -69,55 +69,54 @@
         fFrame = null;
     }
 
-    protected void installComponents() {
+    private void installComponents() {
         fFrame = fDesktopIcon.getInternalFrame();
         fIconPane = new ScaledImageLabel();
         fDesktopIcon.setLayout(new BorderLayout());
         fDesktopIcon.add(fIconPane, BorderLayout.CENTER);
     }
 
-    protected void uninstallComponents() {
+    private void uninstallComponents() {
         fDesktopIcon.setLayout(null);
         fDesktopIcon.remove(fIconPane);
     }
 
-    protected void installListeners() {
+    private void installListeners() {
         fDesktopIcon.addMouseListener(this);
         fDesktopIcon.addMouseMotionListener(this);
-        fFrame.addComponentListener(this);
     }
 
-    protected void uninstallListeners() {
-        fFrame.removeComponentListener(this);
+    private void uninstallListeners() {
         fDesktopIcon.removeMouseMotionListener(this);
         fDesktopIcon.removeMouseListener(this);
     }
 
+    @Override
     public Dimension getMinimumSize(final JComponent c) {
         return new Dimension(32, 32);
     }
 
+    @Override
     public Dimension getMaximumSize(final JComponent c) {
         return new Dimension(128, 128);
     }
 
+    @Override
     public Dimension getPreferredSize(final JComponent c) {
         return new Dimension(64, 64); //$ Dock preferred size
     }
 
-    public Insets getInsets(final JComponent c) {
-        return new Insets(0, 0, 0, 0);
-    }
-
     void updateIcon() {
         fIconPane.updateIcon();
     }
 
+    @Override
     public void mousePressed(final MouseEvent e) {
         fTrackingIcon = fIconPane.mouseInIcon(e);
         if (fTrackingIcon) fIconPane.repaint();
     }
 
+    @Override
     public void mouseReleased(final MouseEvent e) {// only when it's actually in the image
         if (fFrame.isIconifiable() && fFrame.isIcon()) {
             if (fTrackingIcon) {
@@ -137,6 +136,7 @@
         if (fDockLabel != null && !fIconPane.getBounds().contains(e.getX(), e.getY())) fDockLabel.hide();
     }
 
+    @Override
     public void mouseEntered(final MouseEvent e) {
         if ((e.getModifiers() & InputEvent.BUTTON1_MASK) != 0) return;
         String title = fFrame.getTitle();
@@ -145,41 +145,27 @@
         fDockLabel.show(fDesktopIcon);
     }
 
+    @Override
     public void mouseExited(final MouseEvent e) {
         if (fDockLabel != null && (e.getModifiers() & InputEvent.BUTTON1_MASK) == 0) fDockLabel.hide();
     }
 
+    @Override
     public void mouseClicked(final MouseEvent e) { }
 
+    @Override
     public void mouseDragged(final MouseEvent e) { }
 
+    @Override
     public void mouseMoved(final MouseEvent e) { }
 
-    public void componentHidden(final ComponentEvent e) { }
-
-    public void componentMoved(final ComponentEvent e) { }
-
-    public void componentResized(final ComponentEvent e) {
-        fFrame.putClientProperty(CACHED_FRAME_ICON_KEY, null);
-    }
-
-    public void componentShown(final ComponentEvent e) {
-        fFrame.putClientProperty(CACHED_FRAME_ICON_KEY, null);
-    }
-
     @SuppressWarnings("serial") // Superclass is not serializable across versions
-    class ScaledImageLabel extends JLabel {
+    private final class ScaledImageLabel extends JLabel {
         ScaledImageLabel() {
             super(null, null, CENTER);
         }
 
         void updateIcon() {
-            final Object priorIcon = fFrame.getClientProperty(CACHED_FRAME_ICON_KEY);
-            if (priorIcon instanceof ImageIcon) {
-                setIcon((ImageIcon)priorIcon);
-                return;
-            }
-
             int width = fFrame.getWidth();
             int height = fFrame.getHeight();
 
@@ -196,11 +182,10 @@
 
             final float scale = (float)fDesktopIcon.getWidth() / (float)Math.max(width, height) * 0.89f;
             // Sending in -1 for width xor height causes it to maintain aspect ratio
-            final ImageIcon icon = new ImageIcon(fImage.getScaledInstance((int)(width * scale), -1, Image.SCALE_SMOOTH));
-            fFrame.putClientProperty(CACHED_FRAME_ICON_KEY, icon);
-            setIcon(icon);
+            setIcon(new ImageIcon(fImage.getScaledInstance((int)(width * scale), -1, Image.SCALE_SMOOTH)));
         }
 
+        @Override
         public void paint(final Graphics g) {
             if (getIcon() == null) updateIcon();
 
@@ -222,13 +207,14 @@
             return getBounds().contains(e.getX(), e.getY());
         }
 
+        @Override
         public Dimension getPreferredSize() {
             return new Dimension(64, 64); //$ Dock preferred size
         }
     }
 
     @SuppressWarnings("serial") // Superclass is not serializable across versions
-    class DockLabel extends JLabel {
+    private static final class DockLabel extends JLabel {
         static final int NUB_HEIGHT = 7;
         static final int ROUND_ADDITIONAL_HEIGHT = 8;
         static final int ROUND_ADDITIONAL_WIDTH = 12;
@@ -243,6 +229,7 @@
             setSize(SwingUtilities.computeStringWidth(metrics, getText()) + ROUND_ADDITIONAL_WIDTH * 2, metrics.getAscent() + NUB_HEIGHT + ROUND_ADDITIONAL_HEIGHT);
         }
 
+        @Override
         public void paint(final Graphics g) {
             final int width = getWidth();
             final int height = getHeight();
@@ -303,6 +290,7 @@
             }
         }
 
+        @Override
         @Deprecated
         public void hide() {
             final Container parent = getParent();
--- a/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaTabbedPaneCopyFromBasicUI.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaTabbedPaneCopyFromBasicUI.java	Wed Jul 05 21:37:42 2017 +0200
@@ -2183,50 +2183,21 @@
         }
 
         protected int preferredTabAreaHeight(final int tabPlacement, final int width) {
-            final FontMetrics metrics = getFontMetrics();
             final int tabCount = tabPane.getTabCount();
             int total = 0;
             if (tabCount > 0) {
-                int rows = 1;
-                int x = 0;
-
                 final int maxTabHeight = calculateMaxTabHeight(tabPlacement);
-
-                for (int i = 0; i < tabCount; i++) {
-                    final int tabWidth = calculateTabWidth(tabPlacement, i, metrics);
-
-                    if (x != 0 && x + tabWidth > width) {
-                        rows++;
-                        x = 0;
-                    }
-                    x += tabWidth;
-                }
-                total = calculateTabAreaHeight(tabPlacement, rows, maxTabHeight);
+                total = calculateTabAreaHeight(tabPlacement, 1, maxTabHeight);
             }
             return total;
         }
 
         protected int preferredTabAreaWidth(final int tabPlacement, final int height) {
-            final FontMetrics metrics = getFontMetrics();
             final int tabCount = tabPane.getTabCount();
             int total = 0;
             if (tabCount > 0) {
-                int columns = 1;
-                int y = 0;
-                final int fontHeight = metrics.getHeight();
-
                 maxTabWidth = calculateMaxTabWidth(tabPlacement);
-
-                for (int i = 0; i < tabCount; i++) {
-                    final int tabHeight = calculateTabHeight(tabPlacement, i, fontHeight);
-
-                    if (y != 0 && y + tabHeight > height) {
-                        columns++;
-                        y = 0;
-                    }
-                    y += tabHeight;
-                }
-                total = calculateTabAreaWidth(tabPlacement, columns, maxTabWidth);
+                total = calculateTabAreaWidth(tabPlacement, 1, maxTabWidth);
             }
             return total;
         }
--- a/jdk/src/java.desktop/macosx/classes/sun/font/CFontManager.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/macosx/classes/sun/font/CFontManager.java	Wed Jul 05 21:37:42 2017 +0200
@@ -42,7 +42,6 @@
 import sun.awt.HeadlessToolkit;
 import sun.awt.util.ThreadGroupUtils;
 import sun.lwawt.macosx.*;
-import sun.misc.ManagedLocalsThread;
 
 public final class CFontManager extends SunFontManager {
     private static Hashtable<String, Font2D> genericFonts = new Hashtable<String, Font2D>();
--- a/jdk/src/java.desktop/macosx/classes/sun/java2d/IntegerNIORaster.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/macosx/classes/sun/java2d/IntegerNIORaster.java	Wed Jul 05 21:37:42 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2012, 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
@@ -40,7 +40,7 @@
                                                ") cannot be <= 0");
         }
         // This is cribbed from java.awt.image.Raster.
-        DataBuffer db = new DataBufferNIOInt(w * h);
+        DataBufferNIOInt db = new DataBufferNIOInt(w * h);
         if (location == null) {
             location = new Point(0, 0);
         }
@@ -48,13 +48,11 @@
         return new IntegerNIORaster(sppsm, db, location);
     }
 
-    public IntegerNIORaster(SampleModel sampleModel, DataBuffer dataBuffer, Point origin) {
+    public IntegerNIORaster(SampleModel sampleModel, DataBufferNIOInt dataBuffer, Point origin) {
         // This is all cribbed from sun.awt.image.IntegerInterleavedRaster & sun.awt.image.IntegerComponentRaster
         super(sampleModel, dataBuffer, new Rectangle(origin.x, origin.y, sampleModel.getWidth(), sampleModel.getHeight()), origin, null);
-        if (!(dataBuffer instanceof DataBufferNIOInt)) {
-           throw new RasterFormatException("IntegerNIORasters must have DataBufferNIOInt DataBuffers");
-        }
-        this.data = ((DataBufferNIOInt)dataBuffer).getBuffer();
+
+        this.data = dataBuffer.getBuffer();
     }
 
     public WritableRaster createCompatibleWritableRaster() {
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/LWToolkit.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/LWToolkit.java	Wed Jul 05 21:37:42 2017 +0200
@@ -35,7 +35,6 @@
 import java.util.*;
 
 import sun.awt.*;
-import sun.misc.ManagedLocalsThread;
 import sun.print.*;
 import sun.awt.util.ThreadGroupUtils;
 
@@ -77,13 +76,14 @@
                 shutdown();
                 waitForRunState(STATE_CLEANUP);
             };
-            Thread shutdown = new ManagedLocalsThread(
-                    ThreadGroupUtils.getRootThreadGroup(), shutdownRunnable);
+            Thread shutdown = new Thread(
+                    ThreadGroupUtils.getRootThreadGroup(), shutdownRunnable,
+                    "AWT-Shutdown", 0, false);
             shutdown.setContextClassLoader(null);
             Runtime.getRuntime().addShutdownHook(shutdown);
             String name = "AWT-LW";
-            Thread toolkitThread = new ManagedLocalsThread(
-                    ThreadGroupUtils.getRootThreadGroup(), this, name);
+            Thread toolkitThread = new Thread(
+                   ThreadGroupUtils.getRootThreadGroup(), this, name, 0, false);
             toolkitThread.setDaemon(true);
             toolkitThread.setPriority(Thread.NORM_PRIORITY + 1);
             toolkitThread.start();
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CDragSourceContextPeer.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CDragSourceContextPeer.java	Wed Jul 05 21:37:42 2017 +0200
@@ -44,7 +44,6 @@
 import sun.lwawt.LWComponentPeer;
 import sun.lwawt.LWWindowPeer;
 import sun.lwawt.PlatformWindow;
-import sun.misc.ManagedLocalsThread;
 
 
 public final class CDragSourceContextPeer extends SunDragSourceContextPeer {
@@ -181,7 +180,7 @@
                     }
                 }
             };
-            new ManagedLocalsThread(dragRunnable).start();
+            new Thread(null, dragRunnable, "Drag", 0, false).start();
         } catch (Exception e) {
             final long nativeDragSource = getNativeContext();
             setNativeContext(0);
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CFileDialog.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CFileDialog.java	Wed Jul 05 21:37:42 2017 +0200
@@ -37,7 +37,6 @@
 import sun.awt.CausedFocusEvent.Cause;
 import sun.awt.AWTAccessor;
 import sun.java2d.pipe.Region;
-import sun.misc.ManagedLocalsThread;
 import sun.security.action.GetBooleanAction;
 
 class CFileDialog implements FileDialogPeer {
@@ -120,7 +119,7 @@
         if (visible) {
             // Java2 Dialog class requires peer to run code in a separate thread
             // and handles keeping the call modal
-            new ManagedLocalsThread(new Task()).start();
+            new Thread(null, new Task(), "FileDialog", 0, false).start();
         }
         // We hide ourself before "show" returns - setVisible(false)
         // doesn't apply
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterDialogPeer.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterDialogPeer.java	Wed Jul 05 21:37:42 2017 +0200
@@ -29,7 +29,6 @@
 import java.awt.dnd.*;
 
 import sun.lwawt.*;
-import sun.misc.ManagedLocalsThread;
 
 public class CPrinterDialogPeer extends LWWindowPeer {
     static {
@@ -59,7 +58,7 @@
                 printerDialog.setRetVal(printerDialog.showDialog());
                 printerDialog.setVisible(false);
             };
-            new ManagedLocalsThread(task).start();
+            new Thread(null, task, "PrintDialog", 0, false).start();
         }
     }
 
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterJob.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterJob.java	Wed Jul 05 21:37:42 2017 +0200
@@ -36,6 +36,7 @@
 import javax.print.*;
 import javax.print.attribute.PrintRequestAttributeSet;
 import javax.print.attribute.HashPrintRequestAttributeSet;
+import javax.print.attribute.standard.Copies;
 import javax.print.attribute.standard.Media;
 import javax.print.attribute.standard.MediaPrintableArea;
 import javax.print.attribute.standard.MediaSize;
@@ -43,7 +44,6 @@
 import javax.print.attribute.standard.PageRanges;
 
 import sun.java2d.*;
-import sun.misc.ManagedLocalsThread;
 import sun.print.*;
 
 public final class CPrinterJob extends RasterPrinterJob {
@@ -194,10 +194,37 @@
                 // setPageRange will set firstPage and lastPage as called in getFirstPage
                 // and getLastPage
                 setPageRange(range[0][0] - 1, range[0][1] - 1);
+            } else {
+                // if rangeSelect is SunPageSelection.ALL
+                // then setPageRange appropriately
+                setPageRange(-1, -1);
             }
         }
     }
 
+    private void setPageRangeAttribute(int from, int to, boolean isRangeSet) {
+        if (attributes != null) {
+            // since native Print use zero-based page indices,
+            // we need to store in 1-based format in attributes set
+            // but setPageRange again uses zero-based indices so it should be
+            // 1 less than pageRanges attribute
+            if (isRangeSet) {
+                attributes.add(new PageRanges(from+1, to+1));
+                attributes.add(SunPageSelection.RANGE);
+                setPageRange(from, to);
+            } else {
+                attributes.add(SunPageSelection.ALL);
+            }
+        }
+    }
+
+    private void setCopiesAttribute(int copies) {
+        if (attributes != null) {
+            attributes.add(new Copies(copies));
+            super.setCopies(copies);
+        }
+    }
+
     volatile boolean onEventThread;
 
     @Override
@@ -691,9 +718,15 @@
                 if (pageFormat != null) {
                     Printable printable = pageable.getPrintable(pageIndex);
                     if (printable != null) {
-                        BufferedImage bimg = new BufferedImage((int)Math.round(pageFormat.getWidth()), (int)Math.round(pageFormat.getHeight()), BufferedImage.TYPE_INT_ARGB_PRE);
-                        PeekGraphics peekGraphics = createPeekGraphics(bimg.createGraphics(), printerJob);
-                        Rectangle2D pageFormatArea = getPageFormatArea(pageFormat);
+                        BufferedImage bimg =
+                              new BufferedImage(
+                                  (int)Math.round(pageFormat.getWidth()),
+                                  (int)Math.round(pageFormat.getHeight()),
+                                  BufferedImage.TYPE_INT_ARGB_PRE);
+                        PeekGraphics peekGraphics =
+                         createPeekGraphics(bimg.createGraphics(), printerJob);
+                        Rectangle2D pageFormatArea =
+                             getPageFormatArea(pageFormat);
                         initPrinterGraphics(peekGraphics, pageFormatArea);
 
                         // Do the assignment here!
@@ -741,7 +774,8 @@
 
     // upcall from native
     private static void detachPrintLoop(final long target, final long arg) {
-        new ManagedLocalsThread(() -> _safePrintLoop(target, arg)).start();
+        new Thread(null, () -> _safePrintLoop(target, arg),
+                   "PrintLoop", 0, false).start();
     }
     private static native void _safePrintLoop(long target, long arg);
 
--- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CPrinterJob.m	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CPrinterJob.m	Wed Jul 05 21:37:42 2017 +0200
@@ -312,9 +312,9 @@
 static void nsPrintInfoToJavaPrinterJob(JNIEnv* env, NSPrintInfo* src, jobject dstPrinterJob, jobject dstPageable)
 {
     static JNF_MEMBER_CACHE(jm_setService, sjc_CPrinterJob, "setPrinterServiceFromNative", "(Ljava/lang/String;)V");
-    static JNF_MEMBER_CACHE(jm_setCopies, sjc_CPrinterJob, "setCopies", "(I)V");
+    static JNF_MEMBER_CACHE(jm_setCopiesAttribute, sjc_CPrinterJob, "setCopiesAttribute", "(I)V");
     static JNF_MEMBER_CACHE(jm_setCollated, sjc_CPrinterJob, "setCollated", "(Z)V");
-    static JNF_MEMBER_CACHE(jm_setPageRange, sjc_CPrinterJob, "setPageRange", "(II)V");
+    static JNF_MEMBER_CACHE(jm_setPageRangeAttribute, sjc_CPrinterJob, "setPageRangeAttribute", "(IIZ)V");
 
     // get the selected printer's name, and set the appropriate PrintService on the Java side
     NSString *name = [[src printer] name];
@@ -327,7 +327,7 @@
     NSNumber* nsCopies = [printingDictionary objectForKey:NSPrintCopies];
     if ([nsCopies respondsToSelector:@selector(integerValue)])
     {
-        JNFCallVoidMethod(env, dstPrinterJob, jm_setCopies, [nsCopies integerValue]); // AWT_THREADING Safe (known object)
+        JNFCallVoidMethod(env, dstPrinterJob, jm_setCopiesAttribute, [nsCopies integerValue]); // AWT_THREADING Safe (known object)
     }
 
     NSNumber* nsCollated = [printingDictionary objectForKey:NSPrintMustCollate];
@@ -340,6 +340,7 @@
     if ([nsPrintAllPages respondsToSelector:@selector(boolValue)])
     {
         jint jFirstPage = 0, jLastPage = java_awt_print_Pageable_UNKNOWN_NUMBER_OF_PAGES;
+        jboolean isRangeSet = false;
         if (![nsPrintAllPages boolValue])
         {
             NSNumber* nsFirstPage = [printingDictionary objectForKey:NSPrintFirstPage];
@@ -353,9 +354,12 @@
             {
                 jLastPage = [nsLastPage integerValue] - 1;
             }
-        }
+            isRangeSet = true;
+        } 
+        JNFCallVoidMethod(env, dstPrinterJob, jm_setPageRangeAttribute, 
+                          jFirstPage, jLastPage, isRangeSet); 
+            // AWT_THREADING Safe (known object)
 
-        JNFCallVoidMethod(env, dstPrinterJob, jm_setPageRange, jFirstPage, jLastPage); // AWT_THREADING Safe (known object)
     }
 }
 
@@ -368,6 +372,8 @@
     static JNF_MEMBER_CACHE(jm_isCollated, sjc_CPrinterJob, "isCollated", "()Z");
     static JNF_MEMBER_CACHE(jm_getFromPage, sjc_CPrinterJob, "getFromPageAttrib", "()I");
     static JNF_MEMBER_CACHE(jm_getToPage, sjc_CPrinterJob, "getToPageAttrib", "()I");
+    static JNF_MEMBER_CACHE(jm_getMinPage, sjc_CPrinterJob, "getMinPageAttrib", "()I");
+    static JNF_MEMBER_CACHE(jm_getMaxPage, sjc_CPrinterJob, "getMaxPageAttrib", "()I");
     static JNF_MEMBER_CACHE(jm_getSelectAttrib, sjc_CPrinterJob, "getSelectAttrib", "()I");
     static JNF_MEMBER_CACHE(jm_getNumberOfPages, jc_Pageable, "getNumberOfPages", "()I");
     static JNF_MEMBER_CACHE(jm_getPageFormat, sjc_CPrinterJob, "getPageFormatFromAttributes", "()Ljava/awt/print/PageFormat;");
@@ -379,31 +385,33 @@
 
     jboolean collated = JNFCallBooleanMethod(env, srcPrinterJob, jm_isCollated); // AWT_THREADING Safe (known object)
     [printingDictionary setObject:[NSNumber numberWithBool:collated ? YES : NO] forKey:NSPrintMustCollate];
-    jint jNumPages = JNFCallIntMethod(env, srcPageable, jm_getNumberOfPages); // AWT_THREADING Safe (!appKit)
-    if (jNumPages != java_awt_print_Pageable_UNKNOWN_NUMBER_OF_PAGES)
-    {
-        jint selectID = JNFCallIntMethod(env, srcPrinterJob, jm_getSelectAttrib);
-        if (selectID ==0) {
-            [printingDictionary setObject:[NSNumber numberWithBool:YES] forKey:NSPrintAllPages];
-        } else if (selectID == 2) {
-            // In Mac 10.7,  Print ALL is deselected if PrintSelection is YES whether
-            // NSPrintAllPages is YES or NO
-            [printingDictionary setObject:[NSNumber numberWithBool:NO] forKey:NSPrintAllPages];
-            [printingDictionary setObject:[NSNumber numberWithBool:YES] forKey:NSPrintSelectionOnly];
-        } else {
+    jint selectID = JNFCallIntMethod(env, srcPrinterJob, jm_getSelectAttrib);
+    jint fromPage = JNFCallIntMethod(env, srcPrinterJob, jm_getFromPage);
+    jint toPage = JNFCallIntMethod(env, srcPrinterJob, jm_getToPage);
+    if (selectID ==0) {
+        [printingDictionary setObject:[NSNumber numberWithBool:YES] forKey:NSPrintAllPages];
+    } else if (selectID == 2) {
+        // In Mac 10.7,  Print ALL is deselected if PrintSelection is YES whether
+        // NSPrintAllPages is YES or NO
+        [printingDictionary setObject:[NSNumber numberWithBool:NO] forKey:NSPrintAllPages];
+        [printingDictionary setObject:[NSNumber numberWithBool:YES] forKey:NSPrintSelectionOnly];
+    } else {
+        jint minPage = JNFCallIntMethod(env, srcPrinterJob, jm_getMinPage);
+        jint maxPage = JNFCallIntMethod(env, srcPrinterJob, jm_getMaxPage);
+
+        // for PD_SELECTION or PD_NOSELECTION, check from/to page
+        // to determine which radio button to select
+        if (fromPage > minPage || toPage < maxPage) {
             [printingDictionary setObject:[NSNumber numberWithBool:NO] forKey:NSPrintAllPages];
+        } else {
+            [printingDictionary setObject:[NSNumber numberWithBool:YES] forKey:NSPrintAllPages];
         }
+    }
 
-        jint fromPage = JNFCallIntMethod(env, srcPrinterJob, jm_getFromPage);
-        jint toPage = JNFCallIntMethod(env, srcPrinterJob, jm_getToPage);
-        // setting fromPage and toPage will not be shown in the dialog if printing All pages
-        [printingDictionary setObject:[NSNumber numberWithInteger:fromPage] forKey:NSPrintFirstPage];
-        [printingDictionary setObject:[NSNumber numberWithInteger:toPage] forKey:NSPrintLastPage];
-    }
-    else
-    {
-        [printingDictionary setObject:[NSNumber numberWithBool:YES] forKey:NSPrintAllPages];
-    }
+    // setting fromPage and toPage will not be shown in the dialog if printing All pages
+    [printingDictionary setObject:[NSNumber numberWithInteger:fromPage] forKey:NSPrintFirstPage];
+    [printingDictionary setObject:[NSNumber numberWithInteger:toPage] forKey:NSPrintLastPage];
+
     jobject page = JNFCallObjectMethod(env, srcPrinterJob, jm_getPageFormat); 
     if (page != NULL) {
         javaPageFormatToNSPrintInfo(env, NULL, page, dst);
--- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CTrayIcon.m	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CTrayIcon.m	Wed Jul 05 21:37:42 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
@@ -39,18 +39,21 @@
  * If the image of the specified size won't fit into the status bar,
  * then scale it down proprtionally. Otherwise, leave it as is.
  */
-static NSSize ScaledImageSizeForStatusBar(NSSize imageSize) {
+static NSSize ScaledImageSizeForStatusBar(NSSize imageSize, BOOL autosize) {
     NSRect imageRect = NSMakeRect(0.0, 0.0, imageSize.width, imageSize.height);
 
     // There is a black line at the bottom of the status bar
     // that we don't want to cover with image pixels.
-    CGFloat desiredHeight = [[NSStatusBar systemStatusBar] thickness] - 1.0;
-    CGFloat scaleFactor = MIN(1.0, desiredHeight/imageSize.height);
-
-    imageRect.size.width *= scaleFactor;
-    imageRect.size.height *= scaleFactor;
+    CGFloat desiredSize = [[NSStatusBar systemStatusBar] thickness] - 1.0;
+    if (autosize) {
+        imageRect.size.width = desiredSize;
+        imageRect.size.height = desiredSize;
+    } else {
+        CGFloat scaleFactor = MIN(1.0, desiredSize/imageSize.height);
+        imageRect.size.width *= scaleFactor;
+        imageRect.size.height *= scaleFactor;
+    }
     imageRect = NSIntegralRect(imageRect);
-
     return imageRect.size;
 }
 
@@ -101,9 +104,9 @@
     return peer;
 }
 
-- (void) setImage:(NSImage *) imagePtr sizing:(BOOL)autosize{
+- (void) setImage:(NSImage *) imagePtr sizing:(BOOL)autosize {
     NSSize imageSize = [imagePtr size];
-    NSSize scaledSize = ScaledImageSizeForStatusBar(imageSize);
+    NSSize scaledSize = ScaledImageSizeForStatusBar(imageSize, autosize);
     if (imageSize.width != scaledSize.width ||
         imageSize.height != scaledSize.height) {
         [imagePtr setSize: scaledSize];
--- a/jdk/src/java.desktop/share/classes/com/sun/imageio/stream/StreamCloser.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/com/sun/imageio/stream/StreamCloser.java	Wed Jul 05 21:37:42 2017 +0200
@@ -26,7 +26,6 @@
 package com.sun.imageio.stream;
 
 import sun.awt.util.ThreadGroupUtils;
-import sun.misc.ManagedLocalsThread;
 
 import java.io.IOException;
 import java.security.AccessController;
@@ -92,8 +91,8 @@
                      * Make its parent the top-level thread group.
                      */
                     ThreadGroup tg = ThreadGroupUtils.getRootThreadGroup();
-                    streamCloser = new ManagedLocalsThread(tg,
-                                                           streamCloserRunnable);
+                    streamCloser = new Thread(tg, streamCloserRunnable,
+                                              "StreamCloser", 0, false);
                     /* Set context class loader to null in order to avoid
                      * keeping a strong reference to an application classloader.
                      */
--- a/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsLookAndFeel.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsLookAndFeel.java	Wed Jul 05 21:37:42 2017 +0200
@@ -64,7 +64,6 @@
 import sun.awt.OSInfo;
 import sun.awt.shell.ShellFolder;
 import sun.font.FontUtilities;
-import sun.misc.ManagedLocalsThread;
 import sun.security.action.GetPropertyAction;
 
 import sun.swing.DefaultLayoutStyle;
@@ -2053,7 +2052,7 @@
             if (audioRunnable != null) {
                 // Runnable appears to block until completed playing, hence
                 // start up another thread to handle playing.
-                new ManagedLocalsThread(audioRunnable).start();
+                new Thread(null, audioRunnable, "Audio", 0, false).start();
             }
         }
     }
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/AudioFloatConverter.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/AudioFloatConverter.java	Wed Jul 05 21:37:42 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2013, 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
@@ -22,6 +22,7 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
+
 package com.sun.media.sound;
 
 import java.nio.ByteBuffer;
@@ -319,8 +320,10 @@
                 float[] out_buff, int out_offset, int out_len) {
             int ix = in_offset;
             int ox = out_offset;
-            for (int i = 0; i < out_len; i++)
-                out_buff[ox++] = in_buff[ix++] * (1.0f / 127.0f);
+            for (int i = 0; i < out_len; i++) {
+                byte x = in_buff[ix++];
+                out_buff[ox++] = x > 0 ? x / 127.0f : x / 128.0f;
+            }
             return out_buff;
         }
 
@@ -328,8 +331,10 @@
                 byte[] out_buff, int out_offset) {
             int ix = in_offset;
             int ox = out_offset;
-            for (int i = 0; i < in_len; i++)
-                out_buff[ox++] = (byte) (in_buff[ix++] * 127.0f);
+            for (int i = 0; i < in_len; i++) {
+                final float x = in_buff[ix++];
+                out_buff[ox++] = (byte) (x > 0 ? x * 127 : x * 128);
+            }
             return out_buff;
         }
     }
@@ -340,9 +345,10 @@
                 float[] out_buff, int out_offset, int out_len) {
             int ix = in_offset;
             int ox = out_offset;
-            for (int i = 0; i < out_len; i++)
-                out_buff[ox++] = ((in_buff[ix++] & 0xFF) - 127)
-                        * (1.0f / 127.0f);
+            for (int i = 0; i < out_len; i++) {
+                byte x = (byte) (in_buff[ix++] - 128);
+                out_buff[ox++] = x > 0 ? x / 127.0f : x / 128.0f;
+            }
             return out_buff;
         }
 
@@ -350,8 +356,10 @@
                 byte[] out_buff, int out_offset) {
             int ix = in_offset;
             int ox = out_offset;
-            for (int i = 0; i < in_len; i++)
-                out_buff[ox++] = (byte) (127 + in_buff[ix++] * 127.0f);
+            for (int i = 0; i < in_len; i++) {
+                float x = in_buff[ix++];
+                out_buff[ox++] = (byte) (128 + (x > 0 ? x * 127 : x * 128));
+            }
             return out_buff;
         }
     }
@@ -369,10 +377,9 @@
             int ix = in_offset;
             int len = out_offset + out_len;
             for (int ox = out_offset; ox < len; ox++) {
-                out_buff[ox] = ((short) ((in_buff[ix++] & 0xFF) |
-                           (in_buff[ix++] << 8))) * (1.0f / 32767.0f);
+                short x = (short) (in_buff[ix++] & 0xFF | (in_buff[ix++] << 8));
+                out_buff[ox] = x > 0 ? x / 32767.0f : x / 32768.0f;
             }
-
             return out_buff;
         }
 
@@ -381,7 +388,8 @@
             int ox = out_offset;
             int len = in_offset + in_len;
             for (int ix = in_offset; ix < len; ix++) {
-                int x = (int) (in_buff[ix] * 32767.0);
+                float f = in_buff[ix];
+                short x = (short) (f > 0 ? f * 32767 : f * 32768);
                 out_buff[ox++] = (byte) x;
                 out_buff[ox++] = (byte) (x >>> 8);
             }
@@ -396,8 +404,8 @@
             int ix = in_offset;
             int ox = out_offset;
             for (int i = 0; i < out_len; i++) {
-                out_buff[ox++] = ((short) ((in_buff[ix++] << 8) |
-                        (in_buff[ix++] & 0xFF))) * (1.0f / 32767.0f);
+                short x = (short) ((in_buff[ix++] << 8) | (in_buff[ix++] & 0xFF));
+                out_buff[ox++] = x > 0 ? x / 32767.0f : x / 32768.0f;
             }
             return out_buff;
         }
@@ -407,7 +415,8 @@
             int ix = in_offset;
             int ox = out_offset;
             for (int i = 0; i < in_len; i++) {
-                int x = (int) (in_buff[ix++] * 32767.0);
+                float f = in_buff[ix++];
+                short x = (short) (f > 0 ? f * 32767.0f : f * 32768.0f);
                 out_buff[ox++] = (byte) (x >>> 8);
                 out_buff[ox++] = (byte) x;
             }
@@ -423,7 +432,8 @@
             int ox = out_offset;
             for (int i = 0; i < out_len; i++) {
                 int x = (in_buff[ix++] & 0xFF) | ((in_buff[ix++] & 0xFF) << 8);
-                out_buff[ox++] = (x - 32767) * (1.0f / 32767.0f);
+                x -= 32768;
+                out_buff[ox++] = x > 0 ? x / 32767.0f : x / 32768.0f;
             }
             return out_buff;
         }
@@ -433,7 +443,8 @@
             int ix = in_offset;
             int ox = out_offset;
             for (int i = 0; i < in_len; i++) {
-                int x = 32767 + (int) (in_buff[ix++] * 32767.0);
+                float f = in_buff[ix++];
+                int x = 32768 + (int) (f > 0 ? f * 32767 : f * 32768);
                 out_buff[ox++] = (byte) x;
                 out_buff[ox++] = (byte) (x >>> 8);
             }
@@ -449,7 +460,8 @@
             int ox = out_offset;
             for (int i = 0; i < out_len; i++) {
                 int x = ((in_buff[ix++] & 0xFF) << 8) | (in_buff[ix++] & 0xFF);
-                out_buff[ox++] = (x - 32767) * (1.0f / 32767.0f);
+                x -= 32768;
+                out_buff[ox++] = x > 0 ? x / 32767.0f : x / 32768.0f;
             }
             return out_buff;
         }
@@ -459,7 +471,8 @@
             int ix = in_offset;
             int ox = out_offset;
             for (int i = 0; i < in_len; i++) {
-                int x = 32767 + (int) (in_buff[ix++] * 32767.0);
+                float f = in_buff[ix++];
+                int x = 32768 + (int) (f > 0 ? f * 32767 : f * 32768);
                 out_buff[ox++] = (byte) (x >>> 8);
                 out_buff[ox++] = (byte) x;
             }
@@ -484,7 +497,7 @@
                         | ((in_buff[ix++] & 0xFF) << 16);
                 if (x > 0x7FFFFF)
                     x -= 0x1000000;
-                out_buff[ox++] = x * (1.0f / (float)0x7FFFFF);
+                out_buff[ox++] = x > 0 ? x / 8388607.0f : x / 8388608.0f;
             }
             return out_buff;
         }
@@ -494,7 +507,8 @@
             int ix = in_offset;
             int ox = out_offset;
             for (int i = 0; i < in_len; i++) {
-                int x = (int) (in_buff[ix++] * (float)0x7FFFFF);
+                float f = in_buff[ix++];
+                int x = (int) (f > 0 ? f * 8388607.0f : f * 8388608.0f);
                 if (x < 0)
                     x += 0x1000000;
                 out_buff[ox++] = (byte) x;
@@ -516,7 +530,7 @@
                         | ((in_buff[ix++] & 0xFF) << 8) | (in_buff[ix++] & 0xFF);
                 if (x > 0x7FFFFF)
                     x -= 0x1000000;
-                out_buff[ox++] = x * (1.0f / (float)0x7FFFFF);
+                out_buff[ox++] = x > 0 ? x / 8388607.0f : x / 8388608.0f;
             }
             return out_buff;
         }
@@ -526,7 +540,8 @@
             int ix = in_offset;
             int ox = out_offset;
             for (int i = 0; i < in_len; i++) {
-                int x = (int) (in_buff[ix++] * (float)0x7FFFFF);
+                float f = in_buff[ix++];
+                int x = (int) (f > 0 ? f * 8388607.0f : f * 8388608.0f);
                 if (x < 0)
                     x += 0x1000000;
                 out_buff[ox++] = (byte) (x >>> 16);
@@ -546,8 +561,8 @@
             for (int i = 0; i < out_len; i++) {
                 int x = (in_buff[ix++] & 0xFF) | ((in_buff[ix++] & 0xFF) << 8)
                         | ((in_buff[ix++] & 0xFF) << 16);
-                x -= 0x7FFFFF;
-                out_buff[ox++] = x * (1.0f / (float)0x7FFFFF);
+                x -= 0x800000;
+                out_buff[ox++] = x > 0 ? x / 8388607.0f : x / 8388608.0f;
             }
             return out_buff;
         }
@@ -557,8 +572,9 @@
             int ix = in_offset;
             int ox = out_offset;
             for (int i = 0; i < in_len; i++) {
-                int x = (int) (in_buff[ix++] * (float)0x7FFFFF);
-                x += 0x7FFFFF;
+                float f = in_buff[ix++];
+                int x = (int) (f > 0 ? f * 8388607.0f : f * 8388608.0f);
+                x += 0x800000;
                 out_buff[ox++] = (byte) x;
                 out_buff[ox++] = (byte) (x >>> 8);
                 out_buff[ox++] = (byte) (x >>> 16);
@@ -576,8 +592,8 @@
             for (int i = 0; i < out_len; i++) {
                 int x = ((in_buff[ix++] & 0xFF) << 16)
                         | ((in_buff[ix++] & 0xFF) << 8) | (in_buff[ix++] & 0xFF);
-                x -= 0x7FFFFF;
-                out_buff[ox++] = x * (1.0f / (float)0x7FFFFF);
+                x -= 0x800000;
+                out_buff[ox++] = x > 0 ? x / 8388607.0f : x / 8388608.0f;
             }
             return out_buff;
         }
@@ -587,8 +603,9 @@
             int ix = in_offset;
             int ox = out_offset;
             for (int i = 0; i < in_len; i++) {
-                int x = (int) (in_buff[ix++] * (float)0x7FFFFF);
-                x += 0x7FFFFF;
+                float f = in_buff[ix++];
+                int x = (int) (f > 0 ? f * 8388607.0f : f * 8388608.0f);
+                x += 8388608;
                 out_buff[ox++] = (byte) (x >>> 16);
                 out_buff[ox++] = (byte) (x >>> 8);
                 out_buff[ox++] = (byte) x;
@@ -673,7 +690,7 @@
                 int x = (in_buff[ix++] & 0xFF) | ((in_buff[ix++] & 0xFF) << 8) |
                         ((in_buff[ix++] & 0xFF) << 16) |
                         ((in_buff[ix++] & 0xFF) << 24);
-                x -= 0x7FFFFFFF;
+                x -= 0x80000000;
                 out_buff[ox++] = x * (1.0f / (float)0x7FFFFFFF);
             }
             return out_buff;
@@ -685,7 +702,7 @@
             int ox = out_offset;
             for (int i = 0; i < in_len; i++) {
                 int x = (int) (in_buff[ix++] * (float)0x7FFFFFFF);
-                x += 0x7FFFFFFF;
+                x += 0x80000000;
                 out_buff[ox++] = (byte) x;
                 out_buff[ox++] = (byte) (x >>> 8);
                 out_buff[ox++] = (byte) (x >>> 16);
@@ -706,7 +723,7 @@
                 int x = ((in_buff[ix++] & 0xFF) << 24) |
                         ((in_buff[ix++] & 0xFF) << 16) |
                         ((in_buff[ix++] & 0xFF) << 8) | (in_buff[ix++] & 0xFF);
-                x -= 0x7FFFFFFF;
+                x -= 0x80000000;
                 out_buff[ox++] = x * (1.0f / (float)0x7FFFFFFF);
             }
             return out_buff;
@@ -718,7 +735,7 @@
             int ox = out_offset;
             for (int i = 0; i < in_len; i++) {
                 int x = (int) (in_buff[ix++] * (float)0x7FFFFFFF);
-                x += 0x7FFFFFFF;
+                x += 0x80000000;
                 out_buff[ox++] = (byte) (x >>> 24);
                 out_buff[ox++] = (byte) (x >>> 16);
                 out_buff[ox++] = (byte) (x >>> 8);
@@ -737,7 +754,7 @@
     // PCM 32+ bit, signed, little-endian
     private static class AudioFloatConversion32xSL extends AudioFloatConverter {
 
-        final int xbytes;
+        private final int xbytes;
 
         AudioFloatConversion32xSL(int xbytes) {
             this.xbytes = xbytes;
@@ -778,7 +795,7 @@
     // PCM 32+ bit, signed, big-endian
     private static class AudioFloatConversion32xSB extends AudioFloatConverter {
 
-        final int xbytes;
+        private final int xbytes;
 
         AudioFloatConversion32xSB(int xbytes) {
             this.xbytes = xbytes;
@@ -820,7 +837,7 @@
     // PCM 32+ bit, unsigned, little-endian
     private static class AudioFloatConversion32xUL extends AudioFloatConverter {
 
-        final int xbytes;
+        private final int xbytes;
 
         AudioFloatConversion32xUL(int xbytes) {
             this.xbytes = xbytes;
@@ -835,7 +852,7 @@
                 int x = (in_buff[ix++] & 0xFF) | ((in_buff[ix++] & 0xFF) << 8)
                         | ((in_buff[ix++] & 0xFF) << 16)
                         | ((in_buff[ix++] & 0xFF) << 24);
-                x -= 0x7FFFFFFF;
+                x -= 0x80000000;
                 out_buff[ox++] = x * (1.0f / (float)0x7FFFFFFF);
             }
             return out_buff;
@@ -847,7 +864,7 @@
             int ox = out_offset;
             for (int i = 0; i < in_len; i++) {
                 int x = (int) (in_buff[ix++] * (float)0x7FFFFFFF);
-                x += 0x7FFFFFFF;
+                x += 0x80000000;
                 for (int j = 0; j < xbytes; j++) {
                     out_buff[ox++] = 0;
                 }
@@ -863,7 +880,7 @@
     // PCM 32+ bit, unsigned, big-endian
     private static class AudioFloatConversion32xUB extends AudioFloatConverter {
 
-        final int xbytes;
+        private final int xbytes;
 
         AudioFloatConversion32xUB(int xbytes) {
             this.xbytes = xbytes;
@@ -878,7 +895,7 @@
                         ((in_buff[ix++] & 0xFF) << 16) |
                         ((in_buff[ix++] & 0xFF) << 8) | (in_buff[ix++] & 0xFF);
                 ix += xbytes;
-                x -= 2147483647;
+                x -= 0x80000000;
                 out_buff[ox++] = x * (1.0f / 2147483647.0f);
             }
             return out_buff;
@@ -889,8 +906,8 @@
             int ix = in_offset;
             int ox = out_offset;
             for (int i = 0; i < in_len; i++) {
-                int x = (int) (in_buff[ix++] * 2147483647.0);
-                x += 2147483647;
+                int x = (int) (in_buff[ix++] * 2147483647.0f);
+                x += 0x80000000;
                 out_buff[ox++] = (byte) (x >>> 24);
                 out_buff[ox++] = (byte) (x >>> 16);
                 out_buff[ox++] = (byte) (x >>> 8);
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/JSSecurityManager.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/JSSecurityManager.java	Wed Jul 05 21:37:42 2017 +0200
@@ -25,8 +25,6 @@
 
 package com.sun.media.sound;
 
-import sun.misc.ManagedLocalsThread;
-
 import java.io.BufferedInputStream;
 import java.io.InputStream;
 import java.io.File;
@@ -145,12 +143,11 @@
     static Thread createThread(final Runnable runnable,
                                final String threadName,
                                final boolean isDaemon, final int priority,
-                               final boolean doStart) {
-        Thread thread = new ManagedLocalsThread(runnable);
+                               final boolean doStart)
+    {
+        String name = (threadName != null) ? threadName : "JSSM Thread";
+        Thread thread = new Thread(null, runnable, threadName, 0, false);
 
-        if (threadName != null) {
-            thread.setName(threadName);
-        }
         thread.setDaemon(isDaemon);
         if (priority >= 0) {
             thread.setPriority(priority);
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/JavaSoundAudioClip.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/JavaSoundAudioClip.java	Wed Jul 05 21:37:42 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2013, 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
@@ -232,7 +232,7 @@
         } else if (sequencer != null) {
             try {
                 sequencerloop = false;
-                sequencer.addMetaEventListener(this);
+                sequencer.removeMetaEventListener(this);
                 sequencer.stop();
             } catch (Exception e3) {
                 if (Printer.err) e3.printStackTrace();
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/SoftAudioPusher.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/SoftAudioPusher.java	Wed Jul 05 21:37:42 2017 +0200
@@ -24,8 +24,6 @@
  */
 package com.sun.media.sound;
 
-import sun.misc.ManagedLocalsThread;
-
 import java.io.IOException;
 
 import javax.sound.sampled.AudioInputStream;
@@ -55,7 +53,7 @@
         if (active)
             return;
         active = true;
-        audiothread = new ManagedLocalsThread(this);
+        audiothread = new Thread(null, this, "AudioPusher", 0, false);
         audiothread.setDaemon(true);
         audiothread.setPriority(Thread.MAX_PRIORITY);
         audiothread.start();
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/SoftJitterCorrector.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/SoftJitterCorrector.java	Wed Jul 05 21:37:42 2017 +0200
@@ -24,8 +24,6 @@
  */
 package com.sun.media.sound;
 
-import sun.misc.ManagedLocalsThread;
-
 import javax.sound.sampled.AudioFormat;
 import javax.sound.sampled.AudioInputStream;
 import java.io.EOFException;
@@ -216,7 +214,7 @@
                 }
             };
 
-            thread = new ManagedLocalsThread(runnable);
+            thread = new Thread(null, runnable, "JitterCorrector", 0, false);
             thread.setDaemon(true);
             thread.setPriority(Thread.MAX_PRIORITY);
             thread.start();
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/SoftSynthesizer.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/SoftSynthesizer.java	Wed Jul 05 21:37:42 2017 +0200
@@ -25,8 +25,6 @@
 
 package com.sun.media.sound;
 
-import sun.misc.ManagedLocalsThread;
-
 import java.io.BufferedInputStream;
 import java.io.File;
 import java.io.FileInputStream;
@@ -141,7 +139,7 @@
                      pusher = null;
                      jitter_stream = null;
                      sourceDataLine = null;
-                     new ManagedLocalsThread(runnable).start();
+                     new Thread(null, runnable, "Synthesizer",0,false).start();
                  }
                  return len;
              }
--- a/jdk/src/java.desktop/share/classes/java/awt/EventDispatchThread.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/java/awt/EventDispatchThread.java	Wed Jul 05 21:37:42 2017 +0200
@@ -31,7 +31,6 @@
 
 import java.util.ArrayList;
 
-import sun.misc.ManagedLocalsThread;
 import sun.util.logging.PlatformLogger;
 
 import sun.awt.dnd.SunDragSourceContextPeer;
@@ -55,7 +54,7 @@
  *
  * @since 1.1
  */
-class EventDispatchThread extends ManagedLocalsThread {
+class EventDispatchThread extends Thread {
 
     private static final PlatformLogger eventLog = PlatformLogger.getLogger("java.awt.event.EventDispatchThread");
 
@@ -66,8 +65,16 @@
 
     private ArrayList<EventFilter> eventFilters = new ArrayList<EventFilter>();
 
+   /**
+    * Must always call 5 args super-class constructor passing false
+    * to indicate not to inherit locals.
+    */
+    private EventDispatchThread() {
+        throw new UnsupportedOperationException("Must erase locals");
+    }
+
     EventDispatchThread(ThreadGroup group, String name, EventQueue queue) {
-        super(group, name);
+        super(group, null, name, 0, false);
         setEventQueue(queue);
     }
 
--- a/jdk/src/java.desktop/share/classes/java/awt/Font.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/java/awt/Font.java	Wed Jul 05 21:37:42 2017 +0200
@@ -766,6 +766,49 @@
     }
 
     /**
+     * Returns true if any part of the specified text is from a
+     * complex script for which the implementation will need to invoke
+     * layout processing in order to render correctly when using
+     * {@link Graphics#drawString(String,int,int) drawString(String,int,int)}
+     * and other text rendering methods. Measurement of the text
+     * may similarly need the same extra processing.
+     * The {@code start} and {@code end} indices are provided so that
+     * the application can request only a subset of the text be considered.
+     * The last char index examined is at {@code "end-1"},
+     * i.e a request to examine the entire array would be
+     * <pre>
+     * {@code Font.textRequiresLayout(chars, 0, chars.length);}
+     * </pre>
+     * An application may find this information helpful in
+     * performance sensitive code.
+     * <p>
+     * Note that even if this method returns {@code false}, layout processing
+     * may still be invoked when used with any {@code Font}
+     * for which {@link #hasLayoutAttributes()} returns {@code true},
+     * so that method will need to be consulted for the specific font,
+     * in order to obtain an answer which accounts for such font attributes.
+     *
+     * @param chars the text.
+     * @param start the index of the first char to examine.
+     * @param end the ending index, exclusive.
+     * @return {@code true} if the specified text will need special layout.
+     * @throws NullPointerException if {@code chars} is null.
+     * @throws ArrayIndexOutOfBoundsException if {@code start} is negative or
+     * {@code end} is greater than the length of the {@code chars} array.
+     * @since 9
+     */
+    public static boolean textRequiresLayout(char[] chars,
+                                             int start, int end) {
+        if (chars == null) {
+           throw new NullPointerException("null char array");
+        }
+        if (start < 0 || end > chars.length) {
+            throw new ArrayIndexOutOfBoundsException("start < 0 or end > len");
+        }
+        return FontUtilities.isComplexScript(chars, start, end);
+    }
+
+    /**
      * Returns a {@code Font} appropriate to the attributes.
      * If {@code attributes} contains a {@code FONT} attribute
      * with a valid {@code Font} as its value, it will be
--- a/jdk/src/java.desktop/share/classes/java/awt/image/PackedColorModel.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/java/awt/image/PackedColorModel.java	Wed Jul 05 21:37:42 2017 +0200
@@ -404,9 +404,6 @@
 
         PackedColorModel cm = (PackedColorModel) obj;
         int numC = cm.getNumComponents();
-        if (numC != numComponents) {
-            return false;
-        }
         for(int i=0; i < numC; i++) {
             if (maskArray[i] != cm.getMask(i)) {
                 return false;
--- a/jdk/src/java.desktop/share/classes/java/awt/image/Raster.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/java/awt/image/Raster.java	Wed Jul 05 21:37:42 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -629,7 +629,8 @@
                                                          int scanlineStride,
                                                          int pixelStride,
                                                          int bandOffsets[],
-                                                         Point location) {
+                                                         Point location)
+    {
         if (dataBuffer == null) {
             throw new NullPointerException("DataBuffer cannot be null");
         }
@@ -645,15 +646,26 @@
                                             bandOffsets);
         switch(dataType) {
         case DataBuffer.TYPE_BYTE:
-            return new ByteInterleavedRaster(csm, dataBuffer, location);
+            if (dataBuffer instanceof DataBufferByte) {
+                return new ByteInterleavedRaster(csm,
+                        (DataBufferByte) dataBuffer, location);
+            }
+            break;
 
         case DataBuffer.TYPE_USHORT:
-            return new ShortInterleavedRaster(csm, dataBuffer, location);
+            if (dataBuffer instanceof DataBufferUShort) {
+                return new ShortInterleavedRaster(csm,
+                        (DataBufferUShort) dataBuffer, location);
+            }
+            break;
 
         default:
             throw new IllegalArgumentException("Unsupported data type " +
                                                 dataType);
         }
+
+        // Create the generic raster
+        return new SunWritableRaster(csm, dataBuffer, location);
     }
 
     /**
@@ -691,7 +703,8 @@
                                                     int scanlineStride,
                                                     int bankIndices[],
                                                     int bandOffsets[],
-                                                    Point location) {
+                                                    Point location)
+    {
         if (dataBuffer == null) {
             throw new NullPointerException("DataBuffer cannot be null");
         }
@@ -713,18 +726,29 @@
 
         switch(dataType) {
         case DataBuffer.TYPE_BYTE:
-            return new ByteBandedRaster(bsm, dataBuffer, location);
+            if (dataBuffer instanceof DataBufferByte) {
+                return new ByteBandedRaster(bsm,
+                        (DataBufferByte) dataBuffer, location);
+            }
+            break;
 
         case DataBuffer.TYPE_USHORT:
-            return new ShortBandedRaster(bsm, dataBuffer, location);
+            if (dataBuffer instanceof DataBufferUShort) {
+                return new ShortBandedRaster(bsm,
+                        (DataBufferUShort) dataBuffer, location);
+            }
+            break;
 
         case DataBuffer.TYPE_INT:
-            return new SunWritableRaster(bsm, dataBuffer, location);
+            break;
 
         default:
             throw new IllegalArgumentException("Unsupported data type " +
                                                 dataType);
         }
+
+        // Create the generic raster
+        return new SunWritableRaster(bsm, dataBuffer, location);
     }
 
     /**
@@ -761,7 +785,8 @@
                                                     int w, int h,
                                                     int scanlineStride,
                                                     int bandMasks[],
-                                                    Point location) {
+                                                    Point location)
+    {
         if (dataBuffer == null) {
             throw new NullPointerException("DataBuffer cannot be null");
         }
@@ -776,18 +801,33 @@
 
         switch(dataType) {
         case DataBuffer.TYPE_BYTE:
-            return new ByteInterleavedRaster(sppsm, dataBuffer, location);
+            if (dataBuffer instanceof DataBufferByte) {
+                return new ByteInterleavedRaster(sppsm,
+                        (DataBufferByte) dataBuffer, location);
+            }
+            break;
 
         case DataBuffer.TYPE_USHORT:
-            return new ShortInterleavedRaster(sppsm, dataBuffer, location);
+            if (dataBuffer instanceof DataBufferUShort) {
+                return new ShortInterleavedRaster(sppsm,
+                        (DataBufferUShort) dataBuffer, location);
+            }
+            break;
 
         case DataBuffer.TYPE_INT:
-            return new IntegerInterleavedRaster(sppsm, dataBuffer, location);
+            if (dataBuffer instanceof DataBufferInt) {
+                return new IntegerInterleavedRaster(sppsm,
+                        (DataBufferInt) dataBuffer, location);
+            }
+            break;
 
         default:
             throw new IllegalArgumentException("Unsupported data type " +
                                                 dataType);
         }
+
+        // Create the generic raster
+        return new SunWritableRaster(sppsm, dataBuffer, location);
     }
 
     /**
@@ -821,7 +861,8 @@
     public static WritableRaster createPackedRaster(DataBuffer dataBuffer,
                                                     int w, int h,
                                                     int bitsPerPixel,
-                                                    Point location) {
+                                                    Point location)
+    {
         if (dataBuffer == null) {
             throw new NullPointerException("DataBuffer cannot be null");
         }
@@ -846,9 +887,10 @@
         MultiPixelPackedSampleModel mppsm =
                 new MultiPixelPackedSampleModel(dataType, w, h, bitsPerPixel);
 
-        if (dataType == DataBuffer.TYPE_BYTE &&
-            (bitsPerPixel == 1 || bitsPerPixel == 2 || bitsPerPixel == 4)) {
-            return new BytePackedRaster(mppsm, dataBuffer, location);
+        if (dataBuffer instanceof DataBufferByte &&
+            (bitsPerPixel == 1 || bitsPerPixel == 2 || bitsPerPixel == 4))
+        {
+            return new BytePackedRaster(mppsm, (DataBufferByte) dataBuffer, location);
         } else {
             return new SunWritableRaster(mppsm, dataBuffer, location);
         }
@@ -878,7 +920,8 @@
      */
     public static Raster createRaster(SampleModel sm,
                                       DataBuffer db,
-                                      Point location) {
+                                      Point location)
+    {
         if ((sm == null) || (db == null)) {
             throw new NullPointerException("SampleModel and DataBuffer cannot be null");
         }
@@ -890,32 +933,53 @@
 
         if (sm instanceof PixelInterleavedSampleModel) {
             switch(dataType) {
-                case DataBuffer.TYPE_BYTE:
-                    return new ByteInterleavedRaster(sm, db, location);
+            case DataBuffer.TYPE_BYTE:
+                if (db instanceof DataBufferByte) {
+                    return new ByteInterleavedRaster(sm,
+                            (DataBufferByte) db, location);
+                }
+                break;
 
-                case DataBuffer.TYPE_USHORT:
-                    return new ShortInterleavedRaster(sm, db, location);
+            case DataBuffer.TYPE_USHORT:
+                if (db instanceof DataBufferUShort) {
+                    return new ShortInterleavedRaster(sm,
+                            (DataBufferUShort) db, location);
+                }
+                break;
             }
         } else if (sm instanceof SinglePixelPackedSampleModel) {
             switch(dataType) {
-                case DataBuffer.TYPE_BYTE:
-                    return new ByteInterleavedRaster(sm, db, location);
+            case DataBuffer.TYPE_BYTE:
+                if (db instanceof DataBufferByte) {
+                    return new ByteInterleavedRaster(sm,
+                            (DataBufferByte) db, location);
+                }
+                break;
 
-                case DataBuffer.TYPE_USHORT:
-                    return new ShortInterleavedRaster(sm, db, location);
+            case DataBuffer.TYPE_USHORT:
+                if (db instanceof DataBufferUShort) {
+                    return new ShortInterleavedRaster(sm,
+                            (DataBufferUShort) db, location);
+                }
+                break;
 
-                case DataBuffer.TYPE_INT:
-                    return new IntegerInterleavedRaster(sm, db, location);
+            case DataBuffer.TYPE_INT:
+                if (db instanceof DataBufferInt) {
+                    return new IntegerInterleavedRaster(sm,
+                            (DataBufferInt) db, location);
+                }
+                break;
             }
         } else if (sm instanceof MultiPixelPackedSampleModel &&
                    dataType == DataBuffer.TYPE_BYTE &&
-                   sm.getSampleSize(0) < 8) {
-            return new BytePackedRaster(sm, db, location);
+                   db instanceof DataBufferByte &&
+                   sm.getSampleSize(0) < 8)
+        {
+            return new BytePackedRaster(sm, (DataBufferByte) db, location);
         }
 
         // we couldn't do anything special - do the generic thing
-
-        return new Raster(sm,db,location);
+        return new Raster(sm, db, location);
     }
 
     /**
@@ -964,7 +1028,8 @@
      */
     public static WritableRaster createWritableRaster(SampleModel sm,
                                                       DataBuffer db,
-                                                      Point location) {
+                                                      Point location)
+    {
         if ((sm == null) || (db == null)) {
             throw new NullPointerException("SampleModel and DataBuffer cannot be null");
         }
@@ -976,32 +1041,53 @@
 
         if (sm instanceof PixelInterleavedSampleModel) {
             switch(dataType) {
-                case DataBuffer.TYPE_BYTE:
-                    return new ByteInterleavedRaster(sm, db, location);
+            case DataBuffer.TYPE_BYTE:
+                if (db instanceof DataBufferByte) {
+                    return new ByteInterleavedRaster(sm,
+                            (DataBufferByte) db, location);
+                }
+                break;
 
-                case DataBuffer.TYPE_USHORT:
-                    return new ShortInterleavedRaster(sm, db, location);
+            case DataBuffer.TYPE_USHORT:
+                if (db instanceof DataBufferUShort) {
+                    return new ShortInterleavedRaster(sm,
+                            (DataBufferUShort) db, location);
+                }
+                break;
             }
         } else if (sm instanceof SinglePixelPackedSampleModel) {
             switch(dataType) {
-                case DataBuffer.TYPE_BYTE:
-                    return new ByteInterleavedRaster(sm, db, location);
+            case DataBuffer.TYPE_BYTE:
+                if (db instanceof DataBufferByte) {
+                    return new ByteInterleavedRaster(sm,
+                            (DataBufferByte) db, location);
+                }
+                break;
 
-                case DataBuffer.TYPE_USHORT:
-                    return new ShortInterleavedRaster(sm, db, location);
+            case DataBuffer.TYPE_USHORT:
+                if (db instanceof DataBufferUShort) {
+                    return new ShortInterleavedRaster(sm,
+                            (DataBufferUShort) db, location);
+                }
+                break;
 
-                case DataBuffer.TYPE_INT:
-                    return new IntegerInterleavedRaster(sm, db, location);
+            case DataBuffer.TYPE_INT:
+                if (db instanceof DataBufferInt) {
+                    return new IntegerInterleavedRaster(sm,
+                            (DataBufferInt) db, location);
+                }
+                break;
             }
         } else if (sm instanceof MultiPixelPackedSampleModel &&
                    dataType == DataBuffer.TYPE_BYTE &&
-                   sm.getSampleSize(0) < 8) {
-            return new BytePackedRaster(sm, db, location);
+                   db instanceof DataBufferByte &&
+                   sm.getSampleSize(0) < 8)
+        {
+            return new BytePackedRaster(sm, (DataBufferByte) db, location);
         }
 
         // we couldn't do anything special - do the generic thing
-
-        return new SunWritableRaster(sm,db,location);
+        return new SunWritableRaster(sm, db, location);
     }
 
     /**
--- a/jdk/src/java.desktop/share/classes/java/awt/image/renderable/RenderableImageProducer.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/java/awt/image/renderable/RenderableImageProducer.java	Wed Jul 05 21:37:42 2017 +0200
@@ -35,8 +35,6 @@
 
 package java.awt.image.renderable;
 
-import sun.misc.ManagedLocalsThread;
-
 import java.awt.image.ColorModel;
 import java.awt.image.DataBuffer;
 import java.awt.image.ImageConsumer;
@@ -137,7 +135,7 @@
         addConsumer(ic);
         // Need to build a runnable object for the Thread.
         String name = "RenderableImageProducer Thread";
-        Thread thread = new ManagedLocalsThread(this, name);
+        Thread thread = new Thread(null, this, name, 0, false);
         thread.start();
     }
 
--- a/jdk/src/java.desktop/share/classes/javax/imageio/ImageIO.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/javax/imageio/ImageIO.java	Wed Jul 05 21:37:42 2017 +0200
@@ -1294,7 +1294,8 @@
      *
      * @exception IllegalArgumentException if {@code input} is
      * {@code null}.
-     * @exception IOException if an error occurs during reading.
+     * @exception IOException if an error occurs during reading or when not
+     * able to create required ImageInputStream.
      */
     public static BufferedImage read(File input) throws IOException {
         if (input == null) {
@@ -1344,7 +1345,8 @@
      *
      * @exception IllegalArgumentException if {@code input} is
      * {@code null}.
-     * @exception IOException if an error occurs during reading.
+     * @exception IOException if an error occurs during reading or when not
+     * able to create required ImageInputStream.
      */
     public static BufferedImage read(InputStream input) throws IOException {
         if (input == null) {
@@ -1352,6 +1354,9 @@
         }
 
         ImageInputStream stream = createImageInputStream(input);
+        if (stream == null) {
+            throw new IIOException("Can't create an ImageInputStream!");
+        }
         BufferedImage bi = read(stream);
         if (bi == null) {
             stream.close();
@@ -1384,7 +1389,8 @@
      *
      * @exception IllegalArgumentException if {@code input} is
      * {@code null}.
-     * @exception IOException if an error occurs during reading.
+     * @exception IOException if an error occurs during reading or when not
+     * able to create required ImageInputStream.
      */
     public static BufferedImage read(URL input) throws IOException {
         if (input == null) {
@@ -1398,6 +1404,14 @@
             throw new IIOException("Can't get input stream from URL!", e);
         }
         ImageInputStream stream = createImageInputStream(istream);
+        if (stream == null) {
+            /* close the istream when stream is null so that if user has
+             * given filepath as URL he can delete it, otherwise stream will
+             * be open to that file and he will not be able to delete it.
+             */
+            istream.close();
+            throw new IIOException("Can't create an ImageInputStream!");
+        }
         BufferedImage bi;
         try {
             bi = read(stream);
@@ -1510,7 +1524,8 @@
      *
      * @exception IllegalArgumentException if any parameter is
      * {@code null}.
-     * @exception IOException if an error occurs during writing.
+     * @exception IOException if an error occurs during writing or when not
+     * able to create required ImageOutputStream.
      */
     public static boolean write(RenderedImage im,
                                 String formatName,
@@ -1518,7 +1533,6 @@
         if (output == null) {
             throw new IllegalArgumentException("output == null!");
         }
-        ImageOutputStream stream = null;
 
         ImageWriter writer = getWriter(im, formatName);
         if (writer == null) {
@@ -1528,13 +1542,11 @@
             return false;
         }
 
-        try {
-            output.delete();
-            stream = createImageOutputStream(output);
-        } catch (IOException e) {
-            throw new IIOException("Can't create output stream!", e);
+        output.delete();
+        ImageOutputStream stream = createImageOutputStream(output);
+        if (stream == null) {
+            throw new IIOException("Can't create an ImageOutputStream!");
         }
-
         try {
             return doWrite(im, writer, stream);
         } finally {
@@ -1562,7 +1574,8 @@
      *
      * @exception IllegalArgumentException if any parameter is
      * {@code null}.
-     * @exception IOException if an error occurs during writing.
+     * @exception IOException if an error occurs during writing or when not
+     * able to create required ImageOutputStream.
      */
     public static boolean write(RenderedImage im,
                                 String formatName,
@@ -1570,13 +1583,10 @@
         if (output == null) {
             throw new IllegalArgumentException("output == null!");
         }
-        ImageOutputStream stream = null;
-        try {
-            stream = createImageOutputStream(output);
-        } catch (IOException e) {
-            throw new IIOException("Can't create output stream!", e);
+        ImageOutputStream stream = createImageOutputStream(output);
+        if (stream == null) {
+            throw new IIOException("Can't create an ImageOutputStream!");
         }
-
         try {
             return doWrite(im, getWriter(im, formatName), stream);
         } finally {
--- a/jdk/src/java.desktop/share/classes/javax/swing/JFileChooser.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/javax/swing/JFileChooser.java	Wed Jul 05 21:37:42 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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,13 +26,12 @@
 
 import javax.swing.event.*;
 import javax.swing.filechooser.*;
+import javax.swing.filechooser.FileFilter;
 import javax.swing.plaf.FileChooserUI;
 
 import javax.accessibility.*;
 
-import java.io.File;
-import java.io.ObjectOutputStream;
-import java.io.IOException;
+import java.io.*;
 
 import java.util.Vector;
 import java.awt.AWTEvent;
@@ -51,8 +50,6 @@
 import java.beans.BeanProperty;
 import java.beans.PropertyChangeListener;
 import java.beans.PropertyChangeEvent;
-import java.io.InvalidObjectException;
-import java.io.ObjectInputStream;
 import java.lang.ref.WeakReference;
 
 /**
@@ -390,19 +387,7 @@
     }
 
     private void installHierarchyListener() {
-        addHierarchyListener(new HierarchyListener() {
-            @Override
-            public void hierarchyChanged(HierarchyEvent e) {
-                if ((e.getChangeFlags() & HierarchyEvent.PARENT_CHANGED)
-                        == HierarchyEvent.PARENT_CHANGED) {
-                    JFileChooser fc = JFileChooser.this;
-                    JRootPane rootPane = SwingUtilities.getRootPane(fc);
-                    if (rootPane != null) {
-                        rootPane.setDefaultButton(fc.getUI().getDefaultButton(fc));
-                    }
-                }
-            }
-        });
+        addHierarchyListener(new FCHierarchyListener());
     }
 
     private void installShowFilesListener() {
@@ -2055,4 +2040,18 @@
 
     } // inner class AccessibleJFileChooser
 
+    private class FCHierarchyListener implements HierarchyListener,
+            Serializable {
+        @Override
+        public void hierarchyChanged(HierarchyEvent e) {
+            if ((e.getChangeFlags() & HierarchyEvent.PARENT_CHANGED)
+                    == HierarchyEvent.PARENT_CHANGED) {
+                JFileChooser fc = JFileChooser.this;
+                JRootPane rootPane = SwingUtilities.getRootPane(fc);
+                if (rootPane != null) {
+                    rootPane.setDefaultButton(fc.getUI().getDefaultButton(fc));
+                }
+            }
+        }
+    }
 }
--- a/jdk/src/java.desktop/share/classes/javax/swing/JMenu.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/javax/swing/JMenu.java	Wed Jul 05 21:37:42 2017 +0200
@@ -1296,7 +1296,7 @@
      * @return the array of menu items
      */
     private MenuElement[] buildMenuElementArray(JMenu leaf) {
-        Vector<MenuElement> elements = new Vector<MenuElement>();
+        Vector<MenuElement> elements = new Vector<>();
         Component current = leaf.getPopupMenu();
         JPopupMenu pop;
         JMenu menu;
@@ -1314,11 +1314,14 @@
             } else if (current instanceof JMenuBar) {
                 bar = (JMenuBar) current;
                 elements.insertElementAt(bar, 0);
-                MenuElement me[] = new MenuElement[elements.size()];
-                elements.copyInto(me);
-                return me;
+                break;
+            } else {
+                break;
             }
         }
+        MenuElement me[] = new MenuElement[elements.size()];
+        elements.copyInto(me);
+        return me;
     }
 
 
--- a/jdk/src/java.desktop/share/classes/javax/swing/JTable.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/javax/swing/JTable.java	Wed Jul 05 21:37:42 2017 +0200
@@ -56,7 +56,6 @@
 import javax.print.attribute.*;
 import javax.print.PrintService;
 
-import sun.misc.ManagedLocalsThread;
 import sun.reflect.misc.ReflectUtil;
 
 import sun.swing.SwingUtilities2;
@@ -6375,7 +6374,7 @@
         };
 
         // start printing on another thread
-        Thread th = new ManagedLocalsThread(runnable);
+        Thread th = new Thread(null, runnable, "JTablePrint", 0, false);
         th.start();
 
         printingStatus.showModal(true);
--- a/jdk/src/java.desktop/share/classes/javax/swing/TimerQueue.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/javax/swing/TimerQueue.java	Wed Jul 05 21:37:42 2017 +0200
@@ -36,7 +36,6 @@
 import java.util.concurrent.locks.*;
 import java.util.concurrent.atomic.AtomicLong;
 import sun.awt.AppContext;
-import sun.misc.ManagedLocalsThread;
 
 /**
  * Internal class to manage all Timers using one thread.
@@ -101,8 +100,8 @@
                 final ThreadGroup threadGroup = AppContext.getAppContext().getThreadGroup();
                 AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                     String name = "TimerQueue";
-                    Thread timerThread = new ManagedLocalsThread(threadGroup,
-                                                                 this, name);
+                    Thread timerThread =
+                        new Thread(threadGroup, this, name, 0, false);
                     timerThread.setDaemon(true);
                     timerThread.setPriority(Thread.NORM_PRIORITY);
                     timerThread.start();
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicDirectoryModel.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicDirectoryModel.java	Wed Jul 05 21:37:42 2017 +0200
@@ -26,7 +26,6 @@
 package javax.swing.plaf.basic;
 
 import sun.awt.shell.ShellFolder;
-import sun.misc.ManagedLocalsThread;
 
 import javax.swing.*;
 import javax.swing.event.ListDataEvent;
@@ -271,7 +270,7 @@
             this.currentDirectory = currentDirectory;
             this.fid = fid;
             String name = "Basic L&F File Loading Thread";
-            this.loadThread = new ManagedLocalsThread(this, name);
+            this.loadThread = new Thread(null, this, name, 0, false);
             this.loadThread.start();
         }
 
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicPopupMenuUI.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicPopupMenuUI.java	Wed Jul 05 21:37:42 2017 +0200
@@ -797,9 +797,11 @@
             if (invoker instanceof JPopupMenu) {
                 invoker = ((JPopupMenu)invoker).getInvoker();
             }
-            grabbedWindow = invoker instanceof Window?
-                    (Window)invoker :
-                    SwingUtilities.getWindowAncestor(invoker);
+            grabbedWindow = (invoker == null)
+                    ? null
+                    : ((invoker instanceof Window)
+                            ? (Window) invoker
+                            : SwingUtilities.getWindowAncestor(invoker));
             if(grabbedWindow != null) {
                 if(tk instanceof sun.awt.SunToolkit) {
                     ((sun.awt.SunToolkit)tk).grab(grabbedWindow);
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/nimbus/NimbusStyle.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/nimbus/NimbusStyle.java	Wed Jul 05 21:37:42 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2015, 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
@@ -995,16 +995,7 @@
                     // StateInfo match, otherwise a StateInfo with
                     // SELECTED | ENABLED would match ENABLED, which we
                     // don't want.
-
-                    // This comes from BigInteger.bitCnt
-                    int bitCount = oState;
-                    bitCount -= (0xaaaaaaaa & bitCount) >>> 1;
-                    bitCount = (bitCount & 0x33333333) + ((bitCount >>> 2) &
-                            0x33333333);
-                    bitCount = bitCount + (bitCount >>> 4) & 0x0f0f0f0f;
-                    bitCount += bitCount >>> 8;
-                    bitCount += bitCount >>> 16;
-                    bitCount = bitCount & 0xff;
+                    int bitCount = Integer.bitCount(oState);
                     if (bitCount > bestCount) {
                         bestIndex = counter;
                         bestCount = bitCount;
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthStyle.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthStyle.java	Wed Jul 05 21:37:42 2017 +0200
@@ -775,7 +775,7 @@
                 if (disabledColor == null || disabledColor instanceof UIResource) {
                     return getColorForState(context, type);
                 }
-            } else if (c instanceof JLabel &&
+            } else if ((c instanceof JLabel || c instanceof JMenuItem) &&
                             (type == ColorType.FOREGROUND ||
                              type == ColorType.TEXT_FOREGROUND)) {
                 return getColorForState(context, type);
--- a/jdk/src/java.desktop/share/classes/javax/swing/text/JTextComponent.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/javax/swing/text/JTextComponent.java	Wed Jul 05 21:37:42 2017 +0200
@@ -70,7 +70,6 @@
 import sun.awt.AppContext;
 
 
-import sun.misc.ManagedLocalsThread;
 import sun.swing.PrintingStatus;
 import sun.swing.SwingUtilities2;
 import sun.swing.text.TextComponentPrintable;
@@ -2353,7 +2352,8 @@
             runnablePrinting.run();
         } else {
             if (isEventDispatchThread) {
-                new ManagedLocalsThread(runnablePrinting).start();
+                new Thread(null, runnablePrinting,
+                           "JTextComponentPrint", 0, false ).start();
                 printingStatus.showModal(true);
             } else {
                 printingStatus.showModal(false);
--- a/jdk/src/java.desktop/share/classes/javax/swing/text/LayoutQueue.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/javax/swing/text/LayoutQueue.java	Wed Jul 05 21:37:42 2017 +0200
@@ -26,7 +26,6 @@
 
 import java.util.Vector;
 import sun.awt.AppContext;
-import sun.misc.ManagedLocalsThread;
 
 /**
  * A queue of text layout tasks.
@@ -92,7 +91,7 @@
                     }
                 } while (work != null);
             };
-            worker = new ManagedLocalsThread(workerRunnable, "text-layout");
+            worker = new Thread(null, workerRunnable, "text-layout", 0, false);
             worker.setPriority(Thread.MIN_PRIORITY);
             worker.start();
         }
--- a/jdk/src/java.desktop/share/classes/javax/swing/text/html/CSS.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/javax/swing/text/html/CSS.java	Wed Jul 05 21:37:42 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2014, 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
@@ -1522,8 +1522,16 @@
                 current++;
             }
             last = current;
-            while (current < length && !Character.isWhitespace
-                   (value.charAt(current))) {
+            int inParentheses = 0;
+            char ch;
+            while (current < length && (
+                    !Character.isWhitespace(ch = value.charAt(current))
+                            || inParentheses > 0)) {
+                if (ch == '(') {
+                    inParentheses++;
+                } else if (ch == ')') {
+                    inParentheses--;
+                }
                 current++;
             }
             if (last != current) {
--- a/jdk/src/java.desktop/share/classes/sun/applet/AppletClassLoader.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/sun/applet/AppletClassLoader.java	Wed Jul 05 21:37:42 2017 +0200
@@ -52,7 +52,6 @@
 import java.security.PermissionCollection;
 import sun.awt.AppContext;
 import sun.awt.SunToolkit;
-import sun.misc.ManagedLocalsThread;
 import sun.net.www.ParseUtil;
 import sun.security.util.SecurityConstants;
 
@@ -858,13 +857,20 @@
  * this operation to complete before continuing, wait for the notifyAll()
  * operation on the syncObject to occur.
  */
-class AppContextCreator extends ManagedLocalsThread {
+class AppContextCreator extends Thread {
     Object syncObject = new Object();
     AppContext appContext = null;
     volatile boolean created = false;
 
+    /**
+     * Must call the 5-args super-class constructor to erase locals.
+     */
+    private AppContextCreator() {
+        throw new UnsupportedOperationException("Must erase locals");
+    }
+
     AppContextCreator(ThreadGroup group)  {
-        super(group, "AppContextCreator");
+        super(group, null, "AppContextCreator", 0, false);
     }
 
     public void run()  {
--- a/jdk/src/java.desktop/share/classes/sun/applet/AppletPanel.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/sun/applet/AppletPanel.java	Wed Jul 05 21:37:42 2017 +0200
@@ -44,7 +44,6 @@
 import sun.awt.EmbeddedFrame;
 import sun.awt.SunToolkit;
 import sun.awt.util.PerformanceLogger;
-import sun.misc.ManagedLocalsThread;
 import sun.security.util.SecurityConstants;
 
 /**
@@ -166,7 +165,7 @@
 
 
         ThreadGroup appletGroup = loader.getThreadGroup();
-        handler = new ManagedLocalsThread(appletGroup, this, "thread " + nm);
+        handler = new Thread(appletGroup, this, "thread " + nm, 0, false);
         // set the context class loader for this thread
         AccessController.doPrivileged(new PrivilegedAction<Object>() {
                 @Override
@@ -396,9 +395,8 @@
                       // until the loader thread terminates.
                       // (one way or another).
                       if (loaderThread == null) {
-                          // REMIND: do we want a name?
-                          //System.out.println("------------------- loading applet");
-                          setLoaderThread(new ManagedLocalsThread(this));
+                          setLoaderThread(new Thread(null, this,
+                                          "AppletLoader", 0, false));
                           loaderThread.start();
                           // we get to go to sleep while this runs
                           loaderThread.join();
--- a/jdk/src/java.desktop/share/classes/sun/applet/AppletViewer.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/sun/applet/AppletViewer.java	Wed Jul 05 21:37:42 2017 +0200
@@ -38,7 +38,6 @@
 import java.security.PrivilegedAction;
 import sun.awt.SunToolkit;
 import sun.awt.AppContext;
-import sun.misc.ManagedLocalsThread;
 
 /**
  * A frame to show the applet tag in.
@@ -854,7 +853,7 @@
         //
         final AppletPanel p = panel;
 
-        new ManagedLocalsThread(new Runnable()
+        new Thread(null, new Runnable()
         {
             @Override
             public void run()
@@ -867,7 +866,8 @@
                     appletSystemExit();
                 }
             }
-        }).start();
+        },
+        "AppletCloser", 0, false).start();
     }
 
     /**
@@ -890,7 +890,7 @@
         // spawn a new thread to avoid blocking the event queue
         // when calling appletShutdown.
         //
-        new ManagedLocalsThread(new Runnable()
+        new Thread(null, new Runnable()
         {
             @Override
             public void run()
@@ -901,7 +901,8 @@
                 }
                 appletSystemExit();
             }
-        }).start();
+        },
+         "AppletQuit", 0, false).start();
     }
 
     /**
--- a/jdk/src/java.desktop/share/classes/sun/awt/AWTAutoShutdown.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/sun/awt/AWTAutoShutdown.java	Wed Jul 05 21:37:42 2017 +0200
@@ -34,7 +34,6 @@
 import java.util.Set;
 
 import sun.awt.util.ThreadGroupUtils;
-import sun.misc.ManagedLocalsThread;
 import sun.util.logging.PlatformLogger;
 
 /**
@@ -337,8 +336,8 @@
     private void activateBlockerThread() {
         AccessController.doPrivileged((PrivilegedAction<Thread>) () -> {
             String name = "AWT-Shutdown";
-            Thread thread = new ManagedLocalsThread(
-                    ThreadGroupUtils.getRootThreadGroup(), this, name);
+            Thread thread = new Thread(
+                   ThreadGroupUtils.getRootThreadGroup(), this, name, 0, false);
             thread.setContextClassLoader(null);
             thread.setDaemon(false);
             blockerThread = thread;
--- a/jdk/src/java.desktop/share/classes/sun/awt/AppContext.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/sun/awt/AppContext.java	Wed Jul 05 21:37:42 2017 +0200
@@ -46,7 +46,6 @@
 
 import jdk.internal.misc.JavaAWTAccess;
 import jdk.internal.misc.SharedSecrets;
-import sun.misc.ManagedLocalsThread;
 import sun.util.logging.PlatformLogger;
 import java.util.concurrent.locks.Condition;
 import java.util.concurrent.locks.Lock;
@@ -598,8 +597,8 @@
         }
 
         public Thread run() {
-            Thread t = new ManagedLocalsThread(appContext.getThreadGroup(),
-                                               runnable, "AppContext Disposer");
+            Thread t = new Thread(appContext.getThreadGroup(),
+                                  runnable, "AppContext Disposer", 0, false);
             t.setContextClassLoader(appContext.getContextClassLoader());
             t.setPriority(Thread.NORM_PRIORITY + 1);
             t.setDaemon(true);
--- a/jdk/src/java.desktop/share/classes/sun/awt/im/InputMethodManager.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/sun/awt/im/InputMethodManager.java	Wed Jul 05 21:37:42 2017 +0200
@@ -55,7 +55,6 @@
 import java.util.prefs.Preferences;
 import sun.awt.InputMethodSupport;
 import sun.awt.SunToolkit;
-import sun.misc.ManagedLocalsThread;
 
 /**
  * {@code InputMethodManager} is an abstract class that manages the input
@@ -166,7 +165,8 @@
                 // to choose from. Otherwise, just keep the instance.
                 if (imm.hasMultipleInputMethods()) {
                     imm.initialize();
-                    Thread immThread = new ManagedLocalsThread(imm, threadName);
+                    Thread immThread =
+                        new Thread(null, imm, threadName, 0, false);
                     immThread.setDaemon(true);
                     immThread.setPriority(Thread.NORM_PRIORITY + 1);
                     immThread.start();
--- a/jdk/src/java.desktop/share/classes/sun/awt/image/ByteBandedRaster.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/sun/awt/image/ByteBandedRaster.java	Wed Jul 05 21:37:42 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -29,7 +29,6 @@
 import java.awt.image.RasterFormatException;
 import java.awt.image.SampleModel;
 import java.awt.image.BandedSampleModel;
-import java.awt.image.DataBuffer;
 import java.awt.image.DataBufferByte;
 import java.awt.Rectangle;
 import java.awt.Point;
@@ -74,10 +73,9 @@
      *  @param sampleModel     The SampleModel that specifies the layout.
      *  @param origin          The Point that specifies the origin.
      */
-    public ByteBandedRaster(SampleModel sampleModel,
-                               Point origin) {
+    public ByteBandedRaster(SampleModel sampleModel, Point origin) {
         this(sampleModel,
-             sampleModel.createDataBuffer(),
+             (DataBufferByte) sampleModel.createDataBuffer(),
              new Rectangle(origin.x,
                            origin.y,
                            sampleModel.getWidth(),
@@ -93,12 +91,13 @@
      *  initialized and must be a DataBufferShort compatible with SampleModel.
      *  SampleModel must be of type BandedSampleModel.
      *  @param sampleModel     The SampleModel that specifies the layout.
-     *  @param dataBuffer      The DataBufferShort that contains the image data.
+     *  @param dataBuffer      The DataBufferByte that contains the image data.
      *  @param origin          The Point that specifies the origin.
      */
     public ByteBandedRaster(SampleModel sampleModel,
-                               DataBuffer dataBuffer,
-                               Point origin) {
+                            DataBufferByte dataBuffer,
+                            Point origin)
+    {
         this(sampleModel, dataBuffer,
              new Rectangle(origin.x , origin.y,
                            sampleModel.getWidth(),
@@ -119,39 +118,33 @@
      *  Note that this constructor should generally be called by other
      *  constructors or create methods, it should not be used directly.
      *  @param sampleModel     The SampleModel that specifies the layout.
-     *  @param dataBuffer      The DataBufferShort that contains the image data.
+     *  @param dataBuffer      The DataBufferByte that contains the image data.
      *  @param aRegion         The Rectangle that specifies the image area.
      *  @param origin          The Point that specifies the origin.
      *  @param parent          The parent (if any) of this raster.
      */
     public ByteBandedRaster(SampleModel sampleModel,
-                            DataBuffer dataBuffer,
+                            DataBufferByte dataBuffer,
                             Rectangle aRegion,
                             Point origin,
-                            ByteBandedRaster parent) {
-
+                            ByteBandedRaster parent)
+    {
         super(sampleModel, dataBuffer, aRegion, origin, parent);
         this.maxX = minX + width;
         this.maxY = minY + height;
 
-        if (!(dataBuffer instanceof DataBufferByte)) {
-           throw new RasterFormatException("ByteBandedRaster must have" +
-                "byte DataBuffers");
-        }
-        DataBufferByte dbb = (DataBufferByte)dataBuffer;
-
         if (sampleModel instanceof BandedSampleModel) {
             BandedSampleModel bsm = (BandedSampleModel)sampleModel;
             this.scanlineStride = bsm.getScanlineStride();
             int bankIndices[] = bsm.getBankIndices();
             int bandOffsets[] = bsm.getBandOffsets();
-            int dOffsets[] = dbb.getOffsets();
+            int dOffsets[] = dataBuffer.getOffsets();
             dataOffsets = new int[bankIndices.length];
             data = new byte[bankIndices.length][];
             int xOffset = aRegion.x - origin.x;
             int yOffset = aRegion.y - origin.y;
             for (int i = 0; i < bankIndices.length; i++) {
-               data[i] = stealData(dbb, bankIndices[i]);
+               data[i] = stealData(dataBuffer, bankIndices[i]);
                dataOffsets[i] = dOffsets[bankIndices[i]] +
                    xOffset + yOffset*scanlineStride + bandOffsets[i];
             }
@@ -672,7 +665,7 @@
         int deltaY = y0 - y;
 
         return new ByteBandedRaster(sm,
-                                    dataBuffer,
+                                    (DataBufferByte) dataBuffer,
                                     new Rectangle(x0,y0,width,height),
                                     new Point(sampleModelTranslateX+deltaX,
                                               sampleModelTranslateY+deltaY),
--- a/jdk/src/java.desktop/share/classes/sun/awt/image/ByteComponentRaster.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/sun/awt/image/ByteComponentRaster.java	Wed Jul 05 21:37:42 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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,7 +30,6 @@
 import java.awt.image.SampleModel;
 import java.awt.image.ComponentSampleModel;
 import java.awt.image.SinglePixelPackedSampleModel;
-import java.awt.image.DataBuffer;
 import java.awt.image.DataBufferByte;
 import java.awt.Rectangle;
 import java.awt.Point;
@@ -94,7 +93,7 @@
      */
     public ByteComponentRaster(SampleModel sampleModel, Point origin) {
         this(sampleModel,
-             sampleModel.createDataBuffer(),
+             (DataBufferByte) sampleModel.createDataBuffer(),
              new Rectangle(origin.x,
                            origin.y,
                            sampleModel.getWidth(),
@@ -111,12 +110,13 @@
      * SampleModel must be of type SinglePixelPackedSampleModel
      * or ComponentSampleModel.
      * @param sampleModel     The SampleModel that specifies the layout.
-     * @param dataBuffer      The DataBufferShort that contains the image data.
+     * @param dataBuffer      The DataBufferByte that contains the image data.
      * @param origin          The Point that specifies the origin.
      */
     public ByteComponentRaster(SampleModel sampleModel,
-                                  DataBuffer dataBuffer,
-                                  Point origin) {
+                               DataBufferByte dataBuffer,
+                               Point origin)
+    {
         this(sampleModel,
              dataBuffer,
              new Rectangle(origin.x,
@@ -141,33 +141,28 @@
      * Note that this constructor should generally be called by other
      * constructors or create methods, it should not be used directly.
      * @param sampleModel     The SampleModel that specifies the layout.
-     * @param dataBuffer      The DataBufferShort that contains the image data.
+     * @param dataBuffer      The DataBufferByte that contains the image data.
      * @param aRegion         The Rectangle that specifies the image area.
      * @param origin          The Point that specifies the origin.
      * @param parent          The parent (if any) of this raster.
      */
     public ByteComponentRaster(SampleModel sampleModel,
-                                  DataBuffer dataBuffer,
-                                  Rectangle aRegion,
-                                  Point origin,
-                                  ByteComponentRaster parent) {
+                               DataBufferByte dataBuffer,
+                               Rectangle aRegion,
+                               Point origin,
+                               ByteComponentRaster parent)
+    {
         super(sampleModel, dataBuffer, aRegion, origin, parent);
         this.maxX = minX + width;
         this.maxY = minY + height;
 
-        if (!(dataBuffer instanceof DataBufferByte)) {
-            throw new RasterFormatException("ByteComponentRasters must have " +
-                                            "byte DataBuffers");
-        }
-
-        DataBufferByte dbb = (DataBufferByte)dataBuffer;
-        this.data = stealData(dbb, 0);
-        if (dbb.getNumBanks() != 1) {
+        this.data = stealData(dataBuffer, 0);
+        if (dataBuffer.getNumBanks() != 1) {
             throw new
                 RasterFormatException("DataBuffer for ByteComponentRasters"+
                                       " must only have 1 bank.");
         }
-        int dbOffset = dbb.getOffset();
+        int dbOffset = dataBuffer.getOffset();
 
         if (sampleModel instanceof ComponentSampleModel) {
             ComponentSampleModel ism = (ComponentSampleModel)sampleModel;
@@ -823,7 +818,7 @@
         int deltaY = y0 - y;
 
         return new ByteComponentRaster(sm,
-                                       dataBuffer,
+                                       (DataBufferByte) dataBuffer,
                                        new Rectangle(x0, y0, width, height),
                                        new Point(sampleModelTranslateX+deltaX,
                                                  sampleModelTranslateY+deltaY),
--- a/jdk/src/java.desktop/share/classes/sun/awt/image/ByteInterleavedRaster.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/sun/awt/image/ByteInterleavedRaster.java	Wed Jul 05 21:37:42 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2014, 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
@@ -31,7 +31,6 @@
 import java.awt.image.ComponentSampleModel;
 import java.awt.image.PixelInterleavedSampleModel;
 import java.awt.image.SinglePixelPackedSampleModel;
-import java.awt.image.DataBuffer;
 import java.awt.image.DataBufferByte;
 import java.awt.Rectangle;
 import java.awt.Point;
@@ -87,7 +86,7 @@
      */
     public ByteInterleavedRaster(SampleModel sampleModel, Point origin) {
         this(sampleModel,
-             sampleModel.createDataBuffer(),
+             (DataBufferByte) sampleModel.createDataBuffer(),
              new Rectangle(origin.x,
                            origin.y,
                            sampleModel.getWidth(),
@@ -104,12 +103,13 @@
      * SampleModel must be of type SinglePixelPackedSampleModel
      * or InterleavedSampleModel.
      * @param sampleModel     The SampleModel that specifies the layout.
-     * @param dataBuffer      The DataBufferShort that contains the image data.
+     * @param dataBuffer      The DataBufferByte that contains the image data.
      * @param origin          The Point that specifies the origin.
      */
     public ByteInterleavedRaster(SampleModel sampleModel,
-                                  DataBuffer dataBuffer,
-                                  Point origin) {
+                                 DataBufferByte dataBuffer,
+                                 Point origin)
+    {
         this(sampleModel,
              dataBuffer,
              new Rectangle(origin.x,
@@ -178,27 +178,22 @@
      * Note that this constructor should generally be called by other
      * constructors or create methods, it should not be used directly.
      * @param sampleModel     The SampleModel that specifies the layout.
-     * @param dataBuffer      The DataBufferShort that contains the image data.
+     * @param dataBuffer      The DataBufferByte that contains the image data.
      * @param aRegion         The Rectangle that specifies the image area.
      * @param origin          The Point that specifies the origin.
      * @param parent          The parent (if any) of this raster.
      */
     public ByteInterleavedRaster(SampleModel sampleModel,
-                                  DataBuffer dataBuffer,
-                                  Rectangle aRegion,
-                                  Point origin,
-                                  ByteInterleavedRaster parent) {
+                                 DataBufferByte dataBuffer,
+                                 Rectangle aRegion,
+                                 Point origin,
+                                 ByteInterleavedRaster parent)
+    {
         super(sampleModel, dataBuffer, aRegion, origin, parent);
         this.maxX = minX + width;
         this.maxY = minY + height;
 
-        if (!(dataBuffer instanceof DataBufferByte)) {
-            throw new RasterFormatException("ByteInterleavedRasters must have " +
-                                            "byte DataBuffers");
-        }
-
-        DataBufferByte dbb = (DataBufferByte)dataBuffer;
-        this.data = stealData(dbb, 0);
+        this.data = stealData(dataBuffer, 0);
 
         int xOffset = aRegion.x - origin.x;
         int yOffset = aRegion.y - origin.y;
@@ -221,7 +216,7 @@
             this.scanlineStride = sppsm.getScanlineStride();
             this.pixelStride = 1;
             this.dataOffsets = new int[1];
-            this.dataOffsets[0] = dbb.getOffset();
+            this.dataOffsets[0] = dataBuffer.getOffset();
             dataOffsets[0] += xOffset*pixelStride+yOffset*scanlineStride;
         } else {
             throw new RasterFormatException("ByteInterleavedRasters must " +
@@ -1259,7 +1254,7 @@
         int deltaY = y0 - y;
 
         return new ByteInterleavedRaster(sm,
-                                       dataBuffer,
+                                       (DataBufferByte) dataBuffer,
                                        new Rectangle(x0, y0, width, height),
                                        new Point(sampleModelTranslateX+deltaX,
                                                  sampleModelTranslateY+deltaY),
--- a/jdk/src/java.desktop/share/classes/sun/awt/image/BytePackedRaster.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/sun/awt/image/BytePackedRaster.java	Wed Jul 05 21:37:42 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -29,7 +29,6 @@
 import java.awt.image.RasterFormatException;
 import java.awt.image.SampleModel;
 import java.awt.image.MultiPixelPackedSampleModel;
-import java.awt.image.DataBuffer;
 import java.awt.image.DataBufferByte;
 import java.awt.Rectangle;
 import java.awt.Point;
@@ -89,10 +88,9 @@
      * @param sampleModel     The SampleModel that specifies the layout.
      * @param origin          The Point that specified the origin.
      */
-    public BytePackedRaster(SampleModel sampleModel,
-                            Point origin) {
+    public BytePackedRaster(SampleModel sampleModel, Point origin) {
         this(sampleModel,
-             sampleModel.createDataBuffer(),
+             (DataBufferByte) sampleModel.createDataBuffer(),
              new Rectangle(origin.x,
                            origin.y,
                            sampleModel.getWidth(),
@@ -108,12 +106,13 @@
      * initialized and must be a DataBufferByte compatible with SampleModel.
      * SampleModel must be of type MultiPixelPackedSampleModel.
      * @param sampleModel     The SampleModel that specifies the layout.
-     * @param dataBuffer      The DataBufferShort that contains the image data.
+     * @param dataBuffer      The DataBufferByte that contains the image data.
      * @param origin          The Point that specifies the origin.
      */
     public BytePackedRaster(SampleModel sampleModel,
-                            DataBuffer dataBuffer,
-                            Point origin) {
+                            DataBufferByte dataBuffer,
+                            Point origin)
+    {
         this(sampleModel,
              dataBuffer,
              new Rectangle(origin.x,
@@ -137,7 +136,7 @@
      * Note that this constructor should generally be called by other
      * constructors or create methods, it should not be used directly.
      * @param sampleModel     The SampleModel that specifies the layout.
-     * @param dataBuffer      The DataBufferShort that contains the image data.
+     * @param dataBuffer      The DataBufferByte that contains the image data.
      * @param aRegion         The Rectangle that specifies the image area.
      * @param origin          The Point that specifies the origin.
      * @param parent          The parent (if any) of this raster.
@@ -146,26 +145,22 @@
      * to requirements of this Raster type.
      */
     public BytePackedRaster(SampleModel sampleModel,
-                            DataBuffer dataBuffer,
+                            DataBufferByte dataBuffer,
                             Rectangle aRegion,
                             Point origin,
-                            BytePackedRaster parent){
+                            BytePackedRaster parent)
+    {
         super(sampleModel,dataBuffer,aRegion,origin, parent);
         this.maxX = minX + width;
         this.maxY = minY + height;
 
-        if (!(dataBuffer instanceof DataBufferByte)) {
-           throw new RasterFormatException("BytePackedRasters must have" +
-                "byte DataBuffers");
-        }
-        DataBufferByte dbb = (DataBufferByte)dataBuffer;
-        this.data = stealData(dbb, 0);
-        if (dbb.getNumBanks() != 1) {
+        this.data = stealData(dataBuffer, 0);
+        if (dataBuffer.getNumBanks() != 1) {
             throw new
                 RasterFormatException("DataBuffer for BytePackedRasters"+
                                       " must only have 1 bank.");
         }
-        int dbOffset = dbb.getOffset();
+        int dbOffset = dataBuffer.getOffset();
 
         if (sampleModel instanceof MultiPixelPackedSampleModel) {
             MultiPixelPackedSampleModel mppsm =
@@ -1322,7 +1317,7 @@
         int deltaY = y0 - y;
 
         return new BytePackedRaster(sm,
-                                    dataBuffer,
+                                    (DataBufferByte) dataBuffer,
                                     new Rectangle(x0, y0, width, height),
                                     new Point(sampleModelTranslateX+deltaX,
                                               sampleModelTranslateY+deltaY),
--- a/jdk/src/java.desktop/share/classes/sun/awt/image/ImageFetcher.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/sun/awt/image/ImageFetcher.java	Wed Jul 05 21:37:42 2017 +0200
@@ -27,7 +27,6 @@
 
 import java.util.Vector;
 import sun.awt.AppContext;
-import sun.misc.ManagedLocalsThread;
 
 /**
   * An ImageFetcher is a thread used to fetch ImageFetchable objects.
@@ -42,7 +41,7 @@
   * @author Jim Graham
   * @author Fred Ecks
   */
-class ImageFetcher extends ManagedLocalsThread {
+class ImageFetcher extends Thread {
     static final int HIGH_PRIORITY = 8;
     static final int LOW_PRIORITY = 3;
     static final int ANIM_PRIORITY = 2;
@@ -52,10 +51,17 @@
                                      // queue before an ImageFetcher dies
 
     /**
+     * We must only call the 5 args super() constructor passing
+     * in "false" to indicate to not inherit locals.
+     */
+    private ImageFetcher() {
+        throw new UnsupportedOperationException("Must erase locals");
+    }
+    /**
       * Constructor for ImageFetcher -- only called by add() below.
       */
     private ImageFetcher(ThreadGroup threadGroup, int index) {
-        super(threadGroup, "Image Fetcher " + index);
+        super(threadGroup, null, "Image Fetcher " + index, 0, false);
         setDaemon(true);
     }
 
--- a/jdk/src/java.desktop/share/classes/sun/awt/image/IntegerComponentRaster.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/sun/awt/image/IntegerComponentRaster.java	Wed Jul 05 21:37:42 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -29,7 +29,6 @@
 import java.awt.image.RasterFormatException;
 import java.awt.image.SampleModel;
 import java.awt.image.SinglePixelPackedSampleModel;
-import java.awt.image.DataBuffer;
 import java.awt.image.DataBufferInt;
 import java.awt.Rectangle;
 import java.awt.Point;
@@ -107,10 +106,9 @@
      *  @param sampleModel     The SampleModel that specifies the layout.
      *  @param origin          The Point that specified the origin.
      */
-    public IntegerComponentRaster(SampleModel sampleModel,
-                                     Point origin) {
+    public IntegerComponentRaster(SampleModel sampleModel, Point origin) {
         this(sampleModel,
-             sampleModel.createDataBuffer(),
+             (DataBufferInt) sampleModel.createDataBuffer(),
              new Rectangle(origin.x,
                            origin.y,
                            sampleModel.getWidth(),
@@ -130,8 +128,9 @@
      * @param origin          The Point that specifies the origin.
      */
     public IntegerComponentRaster(SampleModel sampleModel,
-                                     DataBuffer dataBuffer,
-                                     Point origin) {
+                                  DataBufferInt dataBuffer,
+                                  Point origin)
+    {
         this(sampleModel,
              dataBuffer,
              new Rectangle(origin.x,
@@ -161,24 +160,21 @@
      * @param parent          The parent (if any) of this raster.
      */
     public IntegerComponentRaster(SampleModel sampleModel,
-                                     DataBuffer dataBuffer,
-                                     Rectangle aRegion,
-                                     Point origin,
-                                     IntegerComponentRaster parent){
+                                  DataBufferInt dataBuffer,
+                                  Rectangle aRegion,
+                                  Point origin,
+                                  IntegerComponentRaster parent)
+    {
         super(sampleModel,dataBuffer,aRegion,origin,parent);
         this.maxX = minX + width;
         this.maxY = minY + height;
-        if (!(dataBuffer instanceof DataBufferInt)) {
-           throw new RasterFormatException("IntegerComponentRasters must have" +
-                "integer DataBuffers");
-        }
-        DataBufferInt dbi = (DataBufferInt)dataBuffer;
-        if (dbi.getNumBanks() != 1) {
+
+        if (dataBuffer.getNumBanks() != 1) {
             throw new
                 RasterFormatException("DataBuffer for IntegerComponentRasters"+
                                       " must only have 1 bank.");
         }
-        this.data = stealData(dbi, 0);
+        this.data = stealData(dataBuffer, 0);
 
         if (sampleModel instanceof SinglePixelPackedSampleModel) {
             SinglePixelPackedSampleModel sppsm =
@@ -197,7 +193,7 @@
             this.scanlineStride = sppsm.getScanlineStride();
             this.pixelStride    = 1;
             this.dataOffsets = new int[1];
-            this.dataOffsets[0] = dbi.getOffset();
+            this.dataOffsets[0] = dataBuffer.getOffset();
             this.bandOffset = this.dataOffsets[0];
             int xOffset = aRegion.x - origin.x;
             int yOffset = aRegion.y - origin.y;
@@ -569,7 +565,7 @@
         int deltaY = y0 - y;
 
         return new IntegerComponentRaster(sm,
-                                          dataBuffer,
+                                          (DataBufferInt) dataBuffer,
                                           new Rectangle(x0,y0,width,height),
                                           new Point(sampleModelTranslateX+deltaX,
                                                     sampleModelTranslateY+deltaY),
--- a/jdk/src/java.desktop/share/classes/sun/awt/image/IntegerInterleavedRaster.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/sun/awt/image/IntegerInterleavedRaster.java	Wed Jul 05 21:37:42 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2014, 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
@@ -29,7 +29,6 @@
 import java.awt.image.RasterFormatException;
 import java.awt.image.SampleModel;
 import java.awt.image.SinglePixelPackedSampleModel;
-import java.awt.image.DataBuffer;
 import java.awt.image.DataBufferInt;
 import java.awt.Rectangle;
 import java.awt.Point;
@@ -67,10 +66,9 @@
      *  @param sampleModel     The SampleModel that specifies the layout.
      *  @param origin          The Point that specified the origin.
      */
-    public IntegerInterleavedRaster(SampleModel sampleModel,
-                                     Point origin) {
+    public IntegerInterleavedRaster(SampleModel sampleModel, Point origin) {
         this(sampleModel,
-             sampleModel.createDataBuffer(),
+             (DataBufferInt) sampleModel.createDataBuffer(),
              new Rectangle(origin.x,
                            origin.y,
                            sampleModel.getWidth(),
@@ -90,8 +88,9 @@
      * @param origin          The Point that specifies the origin.
      */
     public IntegerInterleavedRaster(SampleModel sampleModel,
-                                     DataBuffer dataBuffer,
-                                     Point origin) {
+                                    DataBufferInt dataBuffer,
+                                    Point origin)
+    {
         this(sampleModel,
              dataBuffer,
              new Rectangle(origin.x,
@@ -121,19 +120,16 @@
      * @param parent          The parent (if any) of this raster.
      */
     public IntegerInterleavedRaster(SampleModel sampleModel,
-                                     DataBuffer dataBuffer,
-                                     Rectangle aRegion,
-                                     Point origin,
-                                     IntegerInterleavedRaster parent){
+                                    DataBufferInt dataBuffer,
+                                    Rectangle aRegion,
+                                    Point origin,
+                                    IntegerInterleavedRaster parent)
+    {
         super(sampleModel,dataBuffer,aRegion,origin,parent);
         this.maxX = minX + width;
         this.maxY = minY + height;
-        if (!(dataBuffer instanceof DataBufferInt)) {
-           throw new RasterFormatException("IntegerInterleavedRasters must have" +
-                "integer DataBuffers");
-        }
-        DataBufferInt dbi = (DataBufferInt)dataBuffer;
-        this.data = stealData(dbi, 0);
+
+        this.data = stealData(dataBuffer, 0);
 
         if (sampleModel instanceof SinglePixelPackedSampleModel) {
             SinglePixelPackedSampleModel sppsm =
@@ -141,7 +137,7 @@
             this.scanlineStride = sppsm.getScanlineStride();
             this.pixelStride    = 1;
             this.dataOffsets = new int[1];
-            this.dataOffsets[0] = dbi.getOffset();
+            this.dataOffsets[0] = dataBuffer.getOffset();
             this.bandOffset = this.dataOffsets[0];
             int xOffset = aRegion.x - origin.x;
             int yOffset = aRegion.y - origin.y;
@@ -481,7 +477,7 @@
         int deltaY = y0 - y;
 
         return new IntegerInterleavedRaster(sm,
-                                          dataBuffer,
+                                          (DataBufferInt) dataBuffer,
                                           new Rectangle(x0,y0,width,height),
                                           new Point(sampleModelTranslateX+deltaX,
                                                     sampleModelTranslateY+deltaY),
--- a/jdk/src/java.desktop/share/classes/sun/awt/image/ShortBandedRaster.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/sun/awt/image/ShortBandedRaster.java	Wed Jul 05 21:37:42 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -29,7 +29,6 @@
 import java.awt.image.RasterFormatException;
 import java.awt.image.SampleModel;
 import java.awt.image.BandedSampleModel;
-import java.awt.image.DataBuffer;
 import java.awt.image.DataBufferUShort;
 import java.awt.Rectangle;
 import java.awt.Point;
@@ -72,10 +71,9 @@
      * @param sampleModel     The SampleModel that specifies the layout.
      * @param origin          The Point that specified the origin.
      */
-    public ShortBandedRaster(SampleModel sampleModel,
-                                Point origin) {
+    public ShortBandedRaster(SampleModel sampleModel, Point origin) {
         this(sampleModel,
-             sampleModel.createDataBuffer(),
+             (DataBufferUShort) sampleModel.createDataBuffer(),
              new Rectangle(origin.x,
                            origin.y,
                            sampleModel.getWidth(),
@@ -95,8 +93,9 @@
      * @param origin          The Point that specifies the origin.
      */
     public ShortBandedRaster(SampleModel sampleModel,
-                                DataBuffer dataBuffer,
-                                Point origin) {
+                             DataBufferUShort dataBuffer,
+                             Point origin)
+    {
         this(sampleModel, dataBuffer,
              new Rectangle(origin.x, origin.y,
                            sampleModel.getWidth(),
@@ -123,32 +122,27 @@
      * @param parent          The parent (if any) of this raster.
      */
     public ShortBandedRaster(SampleModel sampleModel,
-                                DataBuffer dataBuffer,
-                                Rectangle aRegion,
-                                Point origin,
-                                ShortBandedRaster parent) {
-
+                             DataBufferUShort dataBuffer,
+                             Rectangle aRegion,
+                             Point origin,
+                             ShortBandedRaster parent)
+    {
         super(sampleModel, dataBuffer, aRegion, origin, parent);
         this.maxX = minX + width;
         this.maxY = minY + height;
-        if (!(dataBuffer instanceof DataBufferUShort)) {
-           throw new RasterFormatException("ShortBandedRaster must have " +
-                "ushort DataBuffers");
-        }
-        DataBufferUShort dbus = (DataBufferUShort)dataBuffer;
 
         if (sampleModel instanceof BandedSampleModel) {
             BandedSampleModel bsm = (BandedSampleModel)sampleModel;
             this.scanlineStride = bsm.getScanlineStride();
             int bankIndices[] = bsm.getBankIndices();
             int bandOffsets[] = bsm.getBandOffsets();
-            int dOffsets[] = dbus.getOffsets();
+            int dOffsets[] = dataBuffer.getOffsets();
             dataOffsets = new int[bankIndices.length];
             data = new short[bankIndices.length][];
             int xOffset = aRegion.x - origin.x;
             int yOffset = aRegion.y - origin.y;
             for (int i = 0; i < bankIndices.length; i++) {
-               data[i] = stealData(dbus, bankIndices[i]);
+               data[i] = stealData(dataBuffer, bankIndices[i]);
                dataOffsets[i] = dOffsets[bankIndices[i]] +
                    xOffset + yOffset*scanlineStride + bandOffsets[i];
             }
@@ -670,7 +664,7 @@
         int deltaY = y0 - y;
 
         return new ShortBandedRaster(sm,
-                                     dataBuffer,
+                                     (DataBufferUShort) dataBuffer,
                                      new Rectangle(x0, y0, width, height),
                                      new Point(sampleModelTranslateX+deltaX,
                                                sampleModelTranslateY+deltaY),
--- a/jdk/src/java.desktop/share/classes/sun/awt/image/ShortComponentRaster.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/sun/awt/image/ShortComponentRaster.java	Wed Jul 05 21:37:42 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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,7 +30,6 @@
 import java.awt.image.SampleModel;
 import java.awt.image.ComponentSampleModel;
 import java.awt.image.SinglePixelPackedSampleModel;
-import java.awt.image.DataBuffer;
 import java.awt.image.DataBufferUShort;
 import java.awt.Rectangle;
 import java.awt.Point;
@@ -94,7 +93,7 @@
      */
     public ShortComponentRaster(SampleModel sampleModel, Point origin) {
         this(sampleModel,
-             sampleModel.createDataBuffer(),
+             (DataBufferUShort) sampleModel.createDataBuffer(),
              new Rectangle(origin.x,
                            origin.y,
                            sampleModel.getWidth(),
@@ -115,8 +114,9 @@
      * @param origin          The Point that specifies the origin.
      */
     public ShortComponentRaster(SampleModel sampleModel,
-                                   DataBuffer dataBuffer,
-                                   Point origin) {
+                                DataBufferUShort dataBuffer,
+                                Point origin)
+    {
         this(sampleModel,
              dataBuffer,
              new Rectangle(origin.x,
@@ -146,28 +146,22 @@
      * @param parent          The parent (if any) of this raster.
      */
     public ShortComponentRaster(SampleModel sampleModel,
-                                   DataBuffer dataBuffer,
-                                   Rectangle aRegion,
-                                   Point origin,
-                                   ShortComponentRaster parent) {
-
+                                DataBufferUShort dataBuffer,
+                                Rectangle aRegion,
+                                Point origin,
+                                ShortComponentRaster parent)
+    {
         super(sampleModel, dataBuffer, aRegion, origin, parent);
         this.maxX = minX + width;
         this.maxY = minY + height;
 
-        if(!(dataBuffer instanceof DataBufferUShort)) {
-            throw new RasterFormatException("ShortComponentRasters must have "+
-                                            "short DataBuffers");
-        }
-
-        DataBufferUShort dbus = (DataBufferUShort)dataBuffer;
-        this.data = stealData(dbus, 0);
-        if (dbus.getNumBanks() != 1) {
+        this.data = stealData(dataBuffer, 0);
+        if (dataBuffer.getNumBanks() != 1) {
             throw new
                 RasterFormatException("DataBuffer for ShortComponentRasters"+
                                       " must only have 1 bank.");
         }
-        int dbOffset = dbus.getOffset();
+        int dbOffset = dataBuffer.getOffset();
 
         if (sampleModel instanceof ComponentSampleModel) {
             ComponentSampleModel csm = (ComponentSampleModel)sampleModel;
@@ -758,7 +752,7 @@
         int deltaY = y0 - y;
 
         return new ShortComponentRaster(sm,
-                                       dataBuffer,
+                                       (DataBufferUShort) dataBuffer,
                                        new Rectangle(x0, y0, width, height),
                                        new Point(sampleModelTranslateX+deltaX,
                                                  sampleModelTranslateY+deltaY),
--- a/jdk/src/java.desktop/share/classes/sun/awt/image/ShortInterleavedRaster.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/sun/awt/image/ShortInterleavedRaster.java	Wed Jul 05 21:37:42 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2014, 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
@@ -31,7 +31,6 @@
 import java.awt.image.ComponentSampleModel;
 import java.awt.image.PixelInterleavedSampleModel;
 import java.awt.image.SinglePixelPackedSampleModel;
-import java.awt.image.DataBuffer;
 import java.awt.image.DataBufferUShort;
 import java.awt.Rectangle;
 import java.awt.Point;
@@ -71,7 +70,7 @@
      */
     public ShortInterleavedRaster(SampleModel sampleModel, Point origin) {
         this(sampleModel,
-             sampleModel.createDataBuffer(),
+             (DataBufferUShort) sampleModel.createDataBuffer(),
              new Rectangle(origin.x,
                            origin.y,
                            sampleModel.getWidth(),
@@ -92,8 +91,9 @@
      * @param origin          The Point that specifies the origin.
      */
     public ShortInterleavedRaster(SampleModel sampleModel,
-                                   DataBuffer dataBuffer,
-                                   Point origin) {
+                                  DataBufferUShort dataBuffer,
+                                  Point origin)
+    {
         this(sampleModel,
              dataBuffer,
              new Rectangle(origin.x,
@@ -123,22 +123,17 @@
      * @param parent          The parent (if any) of this raster.
      */
     public ShortInterleavedRaster(SampleModel sampleModel,
-                                   DataBuffer dataBuffer,
-                                   Rectangle aRegion,
-                                   Point origin,
-                                   ShortInterleavedRaster parent) {
+                                  DataBufferUShort dataBuffer,
+                                  Rectangle aRegion,
+                                  Point origin,
+                                  ShortInterleavedRaster parent)
+    {
 
         super(sampleModel, dataBuffer, aRegion, origin, parent);
         this.maxX = minX + width;
         this.maxY = minY + height;
 
-        if(!(dataBuffer instanceof DataBufferUShort)) {
-            throw new RasterFormatException("ShortInterleavedRasters must "+
-                                            "have ushort DataBuffers");
-        }
-
-        DataBufferUShort dbus = (DataBufferUShort)dataBuffer;
-        this.data = stealData(dbus, 0);
+        this.data = stealData(dataBuffer, 0);
 
         // REMIND: need case for interleaved ComponentSampleModel
         if ((sampleModel instanceof PixelInterleavedSampleModel) ||
@@ -160,7 +155,7 @@
             this.scanlineStride = sppsm.getScanlineStride();
             this.pixelStride    = 1;
             this.dataOffsets = new int[1];
-            this.dataOffsets[0] = dbus.getOffset();
+            this.dataOffsets[0] = dataBuffer.getOffset();
             int xOffset = aRegion.x - origin.x;
             int yOffset = aRegion.y - origin.y;
             dataOffsets[0] += xOffset+yOffset*scanlineStride;
@@ -730,7 +725,7 @@
         int deltaY = y0 - y;
 
         return new ShortInterleavedRaster(sm,
-                                       dataBuffer,
+                                       (DataBufferUShort) dataBuffer,
                                        new Rectangle(x0, y0, width, height),
                                        new Point(sampleModelTranslateX+deltaX,
                                                  sampleModelTranslateY+deltaY),
--- a/jdk/src/java.desktop/share/classes/sun/font/CreatedFontTracker.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/sun/font/CreatedFontTracker.java	Wed Jul 05 21:37:42 2017 +0200
@@ -36,7 +36,6 @@
 
 import sun.awt.AppContext;
 import sun.awt.util.ThreadGroupUtils;
-import sun.misc.ManagedLocalsThread;
 
 public class CreatedFontTracker {
 
@@ -122,8 +121,8 @@
                      * Make its parent the top-level thread group.
                      */
                     ThreadGroup rootTG = ThreadGroupUtils.getRootThreadGroup();
-                    t = new ManagedLocalsThread(rootTG,
-                                                TempFileDeletionHook::runHooks);
+                    t = new Thread(rootTG, TempFileDeletionHook::runHooks,
+                                   "TempFontFileDeleter", 0, false);
                     /* Set context class loader to null in order to avoid
                      * keeping a strong reference to an application classloader.
                      */
--- a/jdk/src/java.desktop/share/classes/sun/font/FontUtilities.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/sun/font/FontUtilities.java	Wed Jul 05 21:37:42 2017 +0200
@@ -183,6 +183,25 @@
     }
 
     /**
+     * Return true if there any characters which would trigger layout.
+     * This method considers supplementary characters to be simple,
+     * since we do not presently invoke layout on any code points in
+     * outside the BMP.
+     */
+    public static boolean isComplexScript(char [] chs, int start, int limit) {
+
+        for (int i = start; i < limit; i++) {
+            if (chs[i] < MIN_LAYOUT_CHARCODE) {
+                continue;
+            }
+            else if (isComplexCharCode(chs[i])) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
      * If there is anything in the text which triggers a case
      * where char->glyph does not map 1:1 in straightforward
      * left->right ordering, then this method returns true.
--- a/jdk/src/java.desktop/share/classes/sun/font/SunFontManager.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/sun/font/SunFontManager.java	Wed Jul 05 21:37:42 2017 +0200
@@ -55,7 +55,6 @@
 import sun.awt.SunToolkit;
 import sun.awt.util.ThreadGroupUtils;
 import sun.java2d.FontSupport;
-import sun.misc.ManagedLocalsThread;
 import sun.util.logging.PlatformLogger;
 
 /**
@@ -2513,8 +2512,8 @@
                     };
                     AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
                         ThreadGroup rootTG = ThreadGroupUtils.getRootThreadGroup();
-                        fileCloser = new ManagedLocalsThread(rootTG,
-                                                             fileCloserRunnable);
+                        fileCloser = new Thread(rootTG, fileCloserRunnable,
+                                                "FileCloser", 0, false);
                         fileCloser.setContextClassLoader(null);
                         Runtime.getRuntime().addShutdownHook(fileCloser);
                         return null;
--- a/jdk/src/java.desktop/share/classes/sun/java2d/Disposer.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/Disposer.java	Wed Jul 05 21:37:42 2017 +0200
@@ -26,7 +26,6 @@
 package sun.java2d;
 
 import sun.awt.util.ThreadGroupUtils;
-import sun.misc.ManagedLocalsThread;
 
 import java.lang.ref.Reference;
 import java.lang.ref.ReferenceQueue;
@@ -85,7 +84,7 @@
         AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
             String name = "Java2D Disposer";
             ThreadGroup rootTG = ThreadGroupUtils.getRootThreadGroup();
-            Thread t = new ManagedLocalsThread(rootTG, disposerInstance, name);
+            Thread t = new Thread(rootTG, disposerInstance, name, 0, false);
             t.setContextClassLoader(null);
             t.setDaemon(true);
             t.setPriority(Thread.MAX_PRIORITY);
--- a/jdk/src/java.desktop/share/classes/sun/java2d/loops/GraphicsPrimitive.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/loops/GraphicsPrimitive.java	Wed Jul 05 21:37:42 2017 +0200
@@ -48,7 +48,6 @@
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 
-import sun.misc.ManagedLocalsThread;
 import sun.security.action.GetPropertyAction;
 
 /**
@@ -420,8 +419,9 @@
         public static void setShutdownHook() {
             AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
                 TraceReporter t = new TraceReporter();
-                Thread thread = new ManagedLocalsThread(
-                        ThreadGroupUtils.getRootThreadGroup(), t);
+                Thread thread = new Thread(
+                        ThreadGroupUtils.getRootThreadGroup(), t,
+                        "TraceReporter", 0, false);
                 thread.setContextClassLoader(null);
                 Runtime.getRuntime().addShutdownHook(thread);
                 return null;
--- a/jdk/src/java.desktop/share/classes/sun/java2d/opengl/OGLRenderQueue.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/opengl/OGLRenderQueue.java	Wed Jul 05 21:37:42 2017 +0200
@@ -28,7 +28,6 @@
 import sun.awt.util.ThreadGroupUtils;
 import sun.java2d.pipe.RenderBuffer;
 import sun.java2d.pipe.RenderQueue;
-import sun.misc.ManagedLocalsThread;
 
 import static sun.java2d.pipe.BufferedOpCodes.*;
 import java.security.AccessController;
@@ -161,7 +160,8 @@
 
         public QueueFlusher() {
             String name = "Java2D Queue Flusher";
-            thread = new ManagedLocalsThread(ThreadGroupUtils.getRootThreadGroup(), this, name);
+            thread = new Thread(ThreadGroupUtils.getRootThreadGroup(),
+                                this, name, 0, false);
             thread.setDaemon(true);
             thread.setPriority(Thread.MAX_PRIORITY);
             thread.start();
--- a/jdk/src/java.desktop/share/classes/sun/print/PrintJob2D.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/sun/print/PrintJob2D.java	Wed Jul 05 21:37:42 2017 +0200
@@ -71,7 +71,6 @@
 import javax.print.attribute.standard.MediaSizeName;
 import javax.print.attribute.standard.PageRanges;
 
-import sun.misc.ManagedLocalsThread;
 import sun.print.SunPageSelection;
 import sun.print.SunMinMaxPage;
 
@@ -483,8 +482,30 @@
                 pageFormat.setOrientation(PageFormat.LANDSCAPE);
             } else {
                 pageFormat.setOrientation(PageFormat.PORTRAIT);
+            }
+
+            PageRanges pageRangesAttr
+                    = (PageRanges) attributes.get(PageRanges.class);
+            if (pageRangesAttr != null) {
+                // Get the PageRanges from print dialog.
+                int[][] range = pageRangesAttr.getMembers();
+
+                int prevFromPage = this.jobAttributes.getFromPage();
+                int prevToPage = this.jobAttributes.getToPage();
+
+                int currFromPage = range[0][0];
+                int currToPage = range[range.length - 1][1];
+
+                // if from < to update fromPage first followed by toPage
+                // else update toPage first followed by fromPage
+                if (currFromPage < prevToPage) {
+                    this.jobAttributes.setFromPage(currFromPage);
+                    this.jobAttributes.setToPage(currToPage);
+                } else {
+                    this.jobAttributes.setToPage(currToPage);
+                    this.jobAttributes.setFromPage(currFromPage);
                 }
-
+            }
             printerJob.setPrintable(this, pageFormat);
 
         }
@@ -987,7 +1008,8 @@
     }
 
     private void startPrinterJobThread() {
-        printerJobThread = new ManagedLocalsThread(this, "printerJobThread");
+        printerJobThread =
+            new Thread(null, this, "printerJobThread", 0, false);
         printerJobThread.start();
     }
 
--- a/jdk/src/java.desktop/share/classes/sun/print/ServiceNotifier.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/sun/print/ServiceNotifier.java	Wed Jul 05 21:37:42 2017 +0200
@@ -25,8 +25,6 @@
 
 package sun.print;
 
-import sun.misc.ManagedLocalsThread;
-
 import java.util.Vector;
 
 import javax.print.PrintService;
@@ -42,15 +40,19 @@
  * to obtain the state of the attributes and notifies the listeners of
  * any changes.
  */
-class ServiceNotifier extends ManagedLocalsThread {
+class ServiceNotifier extends Thread {
 
     private PrintService service;
     private Vector<PrintServiceAttributeListener> listeners;
     private boolean stop = false;
     private PrintServiceAttributeSet lastSet;
 
+    /*
+     * If adding any other constructors, always call the 5-args
+     * super-class constructor passing "false" for inherit-locals.
+     */
     ServiceNotifier(PrintService service) {
-        super(service.getName() + " notifier");
+        super(null, null, service.getName() + " notifier", 0, false);
         this.service = service;
         listeners = new Vector<>();
         try {
@@ -70,7 +72,7 @@
         }
     }
 
-    void removeListener(PrintServiceAttributeListener listener) {
+   void removeListener(PrintServiceAttributeListener listener) {
          synchronized (this) {
             if (listener == null || listeners == null) {
                 return;
--- a/jdk/src/java.desktop/share/classes/sun/swing/plaf/synth/DefaultSynthStyle.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/sun/swing/plaf/synth/DefaultSynthStyle.java	Wed Jul 05 21:37:42 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2014, 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
@@ -645,16 +645,7 @@
                     // StateInfo match, otherwise a StateInfo with
                     // SELECTED | ENABLED would match ENABLED, which we
                     // don't want.
-
-                    // This comes from BigInteger.bitCnt
-                    int bitCount = oState;
-                    bitCount -= (0xaaaaaaaa & bitCount) >>> 1;
-                    bitCount = (bitCount & 0x33333333) + ((bitCount >>> 2) &
-                                                      0x33333333);
-                    bitCount = bitCount + (bitCount >>> 4) & 0x0f0f0f0f;
-                    bitCount += bitCount >>> 8;
-                    bitCount += bitCount >>> 16;
-                    bitCount = bitCount & 0xff;
+                    int bitCount = Integer.bitCount(oState);
                     if (bitCount > bestCount) {
                         bestIndex = counter;
                         bestCount = bitCount;
@@ -883,21 +874,6 @@
         }
 
         /**
-         * Returns the number of states that are similar between the
-         * ComponentState this StateInfo represents and val.
-         */
-        private int getMatchCount(int val) {
-            // This comes from BigInteger.bitCnt
-            val &= state;
-            val -= (0xaaaaaaaa & val) >>> 1;
-            val = (val & 0x33333333) + ((val >>> 2) & 0x33333333);
-            val = val + (val >>> 4) & 0x0f0f0f0f;
-            val += val >>> 8;
-            val += val >>> 16;
-            return val & 0xff;
-        }
-
-        /**
          * Creates and returns a copy of this StateInfo.
          *
          * @return Copy of this StateInfo.
--- a/jdk/src/java.desktop/share/native/libfontmanager/layout/DeviceTables.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/share/native/libfontmanager/layout/DeviceTables.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -45,9 +45,12 @@
 
 le_int16 DeviceTable::getAdjustment(const LEReferenceTo<DeviceTable>&base, le_uint16 ppem, LEErrorCode &success) const
 {
+    le_int16 result = 0;
+    if (LE_FAILURE(success)) {
+        return result;
+    }
     le_uint16 start = SWAPW(startSize);
     le_uint16 format = SWAPW(deltaFormat) - 1;
-    le_int16 result = 0;
 
     if (ppem >= start && ppem <= SWAPW(endSize) && format < FORMAT_COUNT) {
         le_uint16 sizeIndex = ppem - start;
--- a/jdk/src/java.desktop/share/native/libfontmanager/layout/LigatureSubstProc.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/share/native/libfontmanager/layout/LigatureSubstProc.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -71,6 +71,10 @@
 {
   LEErrorCode success = LE_NO_ERROR;
   const LigatureSubstitutionStateEntry *entry = entryTable.getAlias(index, success);
+  if (LE_FAILURE(success)) {
+      currGlyph++;
+      return 0;
+  }
 
     ByteOffset newState = SWAPW(entry->newStateOffset);
     le_uint16 flags = SWAPW(entry->flags);
@@ -91,6 +95,10 @@
 
     if (actionOffset != 0) {
       LEReferenceTo<LigatureActionEntry> ap(stHeader, success, actionOffset);
+      if (LE_FAILURE(success)) {
+          currGlyph++;
+          return newState;
+      }
         LigatureActionEntry action;
         le_int32 offset, i = 0, j = 0;
         le_int32 stack[nComponents];
@@ -101,6 +109,10 @@
 
             if (j++ > 0) {
                 ap.addObject(success);
+                if (LE_FAILURE(success)) {
+                    currGlyph++;
+                    return newState;
+                }
             }
 
             action = SWAPL(*ap.getAlias());
@@ -124,9 +136,17 @@
                 return newState; // get out! bad font
               }
               i += SWAPW(offsetTable.getObject(LE_GET_GLYPH(glyphStorage[componentGlyph]), success));
+              if (LE_FAILURE(success)) {
+                  currGlyph++;
+                  return newState;
+              }
 
                 if (action & (lafLast | lafStore))  {
                   LEReferenceTo<TTGlyphID> ligatureOffset(stHeader, success, i);
+                  if (LE_FAILURE(success)) {
+                      currGlyph++;
+                      return newState;
+                  }
                   TTGlyphID ligatureGlyph = SWAPW(*ligatureOffset.getAlias());
 
                   glyphStorage[componentGlyph] = LE_SET_GLYPH(glyphStorage[componentGlyph], ligatureGlyph);
--- a/jdk/src/java.desktop/share/native/libfontmanager/layout/LigatureSubstProc2.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/share/native/libfontmanager/layout/LigatureSubstProc2.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -95,6 +95,10 @@
 
     if (actionOffset != 0) {
         LEReferenceTo<LigatureActionEntry> ap(stHeader, success, ligActionOffset); // byte offset
+        if (LE_FAILURE(success)) {
+            currGlyph+= dir;
+            return nextStateIndex;
+        }
         ap.addObject(ligActionIndex, success);
         LEReferenceToArrayOf<TTGlyphID> ligatureTable(stHeader, success, ligatureOffset, LE_UNBOUNDED_ARRAY);
         LigatureActionEntry action;
@@ -104,8 +108,8 @@
 
         LEReferenceToArrayOf<le_uint16> componentTable(stHeader, success, componentOffset, LE_UNBOUNDED_ARRAY);
         if(LE_FAILURE(success)) {
-          currGlyph+= dir;
-          return nextStateIndex; // get out! bad font
+            currGlyph+= dir;
+            return nextStateIndex; // get out! bad font
         }
 
         do {
@@ -114,6 +118,10 @@
             if (j++ > 0) {
                 ap.addObject(success);
             }
+            if (LE_FAILURE(success)) {
+                currGlyph+= dir;
+                return nextStateIndex;
+            }
 
             action = SWAPL(*ap.getAlias());
 
@@ -129,9 +137,17 @@
                   return nextStateIndex; // get out! bad font
                 }
                 i += SWAPW(componentTable(LE_GET_GLYPH(glyphStorage[componentGlyph]) + (SignExtend(offset, lafComponentOffsetMask)),success));
+                if (LE_FAILURE(success)) {
+                    currGlyph+= dir;
+                    return nextStateIndex;
+                }
 
                 if (action & (lafLast | lafStore))  {
                   TTGlyphID ligatureGlyph = SWAPW(ligatureTable(i,success));
+                  if (LE_FAILURE(success)) {
+                      currGlyph+= dir;
+                      return nextStateIndex;
+                  }
                     glyphStorage[componentGlyph] = LE_SET_GLYPH(glyphStorage[componentGlyph], ligatureGlyph);
                     if(mm==nComponents) {
                       LE_DEBUG_BAD_FONT("exceeded nComponents");
--- a/jdk/src/java.desktop/share/native/libfontmanager/layout/StateTableProcessor2.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/share/native/libfontmanager/layout/StateTableProcessor2.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -60,6 +60,7 @@
   entryTableOffset = SWAPL(stHeader->entryTableOffset);
 
   classTable = LEReferenceTo<LookupTable>(stHeader, success, classTableOffset);
+  if (LE_FAILURE(success)) return;
   format = SWAPW(classTable->format);
 
   stateArray = LEReferenceToArrayOf<EntryTableIndex2>(stHeader, success, stateArrayOffset, LE_UNBOUNDED_ARRAY);
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/GtkFileDialogPeer.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/GtkFileDialogPeer.java	Wed Jul 05 21:37:42 2017 +0200
@@ -29,7 +29,6 @@
 import java.io.File;
 import java.io.FilenameFilter;
 import sun.awt.AWTAccessor;
-import sun.misc.ManagedLocalsThread;
 
 /**
  * FileDialogPeer for the GtkFileChooser.
@@ -120,7 +119,7 @@
                     standaloneWindow = 0;
                     fd.setVisible(false);
                 };
-                new ManagedLocalsThread(task).start();
+                new Thread(null, task, "ShowDialog", 0, false).start();
             } else {
                 quit();
                 fd.setVisible(false);
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/InfoWindow.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/InfoWindow.java	Wed Jul 05 21:37:42 2017 +0200
@@ -29,7 +29,6 @@
 import java.awt.event.*;
 import java.awt.peer.TrayIconPeer;
 import sun.awt.*;
-import sun.misc.ManagedLocalsThread;
 
 import java.awt.image.*;
 import java.text.BreakIterator;
@@ -452,7 +451,7 @@
             final Thread thread;
 
             Displayer() {
-                this.thread = new ManagedLocalsThread(this);
+                this.thread = new Thread(null, this, "Displayer", 0, false);
                 this.thread.setDaemon(true);
             }
 
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XBaseMenuWindow.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XBaseMenuWindow.java	Wed Jul 05 21:37:42 2017 +0200
@@ -1087,7 +1087,7 @@
                       }
                   } else {
                       //Invoke action event
-                      item.action(mouseEvent.getWhen());
+                      item.action(mouseEvent.getWhen(), mouseEvent.getModifiers());
                       ungrabInput();
                   }
               } else {
@@ -1200,7 +1200,7 @@
               if (citem instanceof XMenuPeer) {
                   cwnd.selectItem(citem, true);
               } else if (citem != null) {
-                  citem.action(event.getWhen());
+                  citem.action(event.getWhen(), event.getModifiers());
                   ungrabInput();
               }
               break;
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XMenuItemPeer.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XMenuItemPeer.java	Wed Jul 05 21:37:42 2017 +0200
@@ -323,11 +323,11 @@
      * on menu item.
      * @param when the timestamp of action event
      */
-    void action(long when) {
+    void action(long when, int modifiers) {
         if (!isSeparator() && isTargetItemEnabled()) {
             XWindow.postEventStatic(new ActionEvent(target, ActionEvent.ACTION_PERFORMED,
                                                     getTargetActionCommand(), when,
-                                                    0));
+                                                    modifiers));
         }
     }
     /************************************************
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XTaskbarPeer.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XTaskbarPeer.java	Wed Jul 05 21:37:42 2017 +0200
@@ -29,7 +29,6 @@
 import java.awt.Taskbar.Feature;
 import java.awt.peer.TaskbarPeer;
 import java.awt.event.ActionEvent;
-import sun.misc.ManagedLocalsThread;
 import java.security.AccessController;
 import sun.security.action.GetPropertyAction;
 
@@ -48,10 +47,8 @@
                                 new GetPropertyAction("java.desktop.appName", ""));
                 nativeLibraryLoaded = init(dname);
                 if (nativeLibraryLoaded) {
-                    ManagedLocalsThread t
-                            = new ManagedLocalsThread(() -> {
-                                runloop();
-                            });
+                    Thread t = new Thread(null, () -> { runloop(); },
+                                          "TaskBar", 0, false);
                     t.setDaemon(true);
                     t.start();
                 }
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java	Wed Jul 05 21:37:42 2017 +0200
@@ -284,8 +284,8 @@
                 }
             };
             String name = "XToolkt-Shutdown-Thread";
-            Thread shutdownThread = new ManagedLocalsThread(
-                    ThreadGroupUtils.getRootThreadGroup(), r, name);
+            Thread shutdownThread = new Thread(
+                    ThreadGroupUtils.getRootThreadGroup(), r, name, 0, false);
             shutdownThread.setContextClassLoader(null);
             Runtime.getRuntime().addShutdownHook(shutdownThread);
             return null;
@@ -332,8 +332,9 @@
 
             toolkitThread = AccessController.doPrivileged((PrivilegedAction<Thread>) () -> {
                 String name = "AWT-XAWT";
-                Thread thread = new ManagedLocalsThread(
-                        ThreadGroupUtils.getRootThreadGroup(), this, name);
+                Thread thread = new Thread(
+                        ThreadGroupUtils.getRootThreadGroup(), this, name,
+                        0, false);
                 thread.setContextClassLoader(null);
                 thread.setPriority(Thread.NORM_PRIORITY + 1);
                 thread.setDaemon(true);
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11GraphicsDevice.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11GraphicsDevice.java	Wed Jul 05 21:37:42 2017 +0200
@@ -44,7 +44,6 @@
 
 import sun.awt.util.ThreadGroupUtils;
 import sun.java2d.SunGraphicsEnvironment;
-import sun.misc.ManagedLocalsThread;
 
 /**
  * This is an implementation of a GraphicsDevice object for a single
@@ -442,8 +441,8 @@
                     }
                 };
                 String name = "Display-Change-Shutdown-Thread-" + screen;
-                Thread t = new ManagedLocalsThread(
-                        ThreadGroupUtils.getRootThreadGroup(), r, name);
+                Thread t = new Thread(
+                      ThreadGroupUtils.getRootThreadGroup(), r, name, 0, false);
                 t.setContextClassLoader(null);
                 Runtime.getRuntime().addShutdownHook(t);
                 return null;
--- a/jdk/src/java.desktop/unix/classes/sun/print/PrintServiceLookupProvider.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/unix/classes/sun/print/PrintServiceLookupProvider.java	Wed Jul 05 21:37:42 2017 +0200
@@ -25,8 +25,6 @@
 
 package sun.print;
 
-import sun.misc.ManagedLocalsThread;
-
 import java.io.BufferedReader;
 import java.io.FileInputStream;
 import java.io.InputStream;
@@ -213,7 +211,8 @@
     public PrintServiceLookupProvider() {
         // start the printer listener thread
         if (pollServices) {
-            Thread thr = new ManagedLocalsThread(new PrinterChangeListener());
+            Thread thr = new Thread(null, new PrinterChangeListener(),
+                                    "PrinterListener", 0, false);
             thr.setDaemon(true);
             thr.start();
             IPPPrintService.debug_println(debugPrefix+"polling turned on");
--- a/jdk/src/java.desktop/unix/native/libawt_xawt/awt/awt_GraphicsEnv.c	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/awt/awt_GraphicsEnv.c	Wed Jul 05 21:37:42 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -1877,31 +1877,34 @@
 
     AWT_LOCK();
 
-    config = awt_XRRGetScreenInfo(awt_display,
-                                  RootWindow(awt_display, screen));
-    if (config != NULL) {
-        Rotation rotation;
-        short curRate;
-        SizeID curSizeIndex;
-        XRRScreenSize *sizes;
-        int nsizes;
+    if (screen < ScreenCount(awt_display)) {
 
-        curSizeIndex = awt_XRRConfigCurrentConfiguration(config, &rotation);
-        sizes = awt_XRRConfigSizes(config, &nsizes);
-        curRate = awt_XRRConfigCurrentRate(config);
+        config = awt_XRRGetScreenInfo(awt_display,
+                                      RootWindow(awt_display, screen));
+        if (config != NULL) {
+            Rotation rotation;
+            short curRate;
+            SizeID curSizeIndex;
+            XRRScreenSize *sizes;
+            int nsizes;
 
-        if ((sizes != NULL) &&
-            (curSizeIndex < nsizes))
-        {
-            XRRScreenSize curSize = sizes[curSizeIndex];
-            displayMode = X11GD_CreateDisplayMode(env,
-                                                  curSize.width,
-                                                  curSize.height,
-                                                  BIT_DEPTH_MULTI,
-                                                  curRate);
+            curSizeIndex = awt_XRRConfigCurrentConfiguration(config, &rotation);
+            sizes = awt_XRRConfigSizes(config, &nsizes);
+            curRate = awt_XRRConfigCurrentRate(config);
+
+            if ((sizes != NULL) &&
+                (curSizeIndex < nsizes))
+            {
+                XRRScreenSize curSize = sizes[curSizeIndex];
+                displayMode = X11GD_CreateDisplayMode(env,
+                                                      curSize.width,
+                                                      curSize.height,
+                                                      BIT_DEPTH_MULTI,
+                                                      curRate);
+            }
+
+            awt_XRRFreeScreenConfigInfo(config);
         }
-
-        awt_XRRFreeScreenConfigInfo(config);
     }
 
     AWT_FLUSH_UNLOCK();
--- a/jdk/src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java	Wed Jul 05 21:37:42 2017 +0200
@@ -41,7 +41,6 @@
 import static sun.awt.shell.Win32ShellFolder2.*;
 import sun.awt.OSInfo;
 import sun.awt.util.ThreadGroupUtils;
-import sun.misc.ManagedLocalsThread;
 // NOTE: This class supersedes Win32ShellFolderManager, which was removed
 //       from distribution after version 1.4.2.
 
@@ -524,8 +523,9 @@
                 return null;
             });
             AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
-                Thread t = new ManagedLocalsThread(
-                        ThreadGroupUtils.getRootThreadGroup(), shutdownHook);
+                Thread t = new Thread(
+                        ThreadGroupUtils.getRootThreadGroup(), shutdownHook,
+                        "ShellFolder", 0, false);
                 Runtime.getRuntime().addShutdownHook(t);
                 return null;
             });
@@ -548,8 +548,9 @@
                   * which will not get GCed before VM exit.
                   * Make its parent the top-level thread group.
                   */
-                Thread thread = new ManagedLocalsThread(
-                        ThreadGroupUtils.getRootThreadGroup(), comRun, name);
+                Thread thread = new Thread(
+                        ThreadGroupUtils.getRootThreadGroup(), comRun, name,
+                        0, false);
                 thread.setDaemon(true);
                 return thread;
             });
--- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WFileDialogPeer.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WFileDialogPeer.java	Wed Jul 05 21:37:42 2017 +0200
@@ -36,7 +36,6 @@
 import java.util.Vector;
 import sun.awt.CausedFocusEvent;
 import sun.awt.AWTAccessor;
-import sun.misc.ManagedLocalsThread;
 
 final class WFileDialogPeer extends WWindowPeer implements FileDialogPeer {
 
@@ -98,7 +97,7 @@
 
     @Override
     public void show() {
-        new ManagedLocalsThread(this::_show).start();
+        new Thread(null, this::_show, "FileDialog", 0, false).start();
     }
 
     @Override
--- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WPageDialogPeer.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WPageDialogPeer.java	Wed Jul 05 21:37:42 2017 +0200
@@ -25,8 +25,6 @@
 
 package sun.awt.windows;
 
-import sun.misc.ManagedLocalsThread;
-
 final class WPageDialogPeer extends WPrintDialogPeer {
 
     WPageDialogPeer(WPageDialog target) {
@@ -53,6 +51,6 @@
             }
             ((WPrintDialog)target).setVisible(false);
         };
-        new ManagedLocalsThread(runnable).start();
+        new Thread(null, runnable, "PageDialog", 0, false).start();
     }
 }
--- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WPrintDialogPeer.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WPrintDialogPeer.java	Wed Jul 05 21:37:42 2017 +0200
@@ -32,7 +32,6 @@
 import java.util.Vector;
 import sun.awt.CausedFocusEvent;
 import sun.awt.AWTAccessor;
-import sun.misc.ManagedLocalsThread;
 
 class WPrintDialogPeer extends WWindowPeer implements DialogPeer {
 
@@ -78,7 +77,7 @@
             }
             ((WPrintDialog)target).setVisible(false);
         };
-        new ManagedLocalsThread(runnable).start();
+        new Thread(null, runnable, "PrintDialog", 0, false).start();
     }
 
     synchronized void setHWnd(long hwnd) {
--- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WToolkit.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WToolkit.java	Wed Jul 05 21:37:42 2017 +0200
@@ -52,7 +52,6 @@
 import sun.java2d.d3d.D3DRenderQueue;
 import sun.java2d.opengl.OGLRenderQueue;
 
-import sun.misc.ManagedLocalsThread;
 import sun.print.PrintJob2D;
 
 import java.awt.dnd.DragSource;
@@ -256,7 +255,7 @@
                 (PrivilegedAction<ThreadGroup>) ThreadGroupUtils::getRootThreadGroup);
         if (!startToolkitThread(this, rootTG)) {
             String name = "AWT-Windows";
-            Thread toolkitThread = new ManagedLocalsThread(rootTG, this, name);
+            Thread toolkitThread = new Thread(rootTG, this, name, 0, false);
             toolkitThread.setDaemon(true);
             toolkitThread.start();
         }
@@ -283,8 +282,9 @@
 
     private void registerShutdownHook() {
         AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
-            Thread shutdown = new ManagedLocalsThread(
-                    ThreadGroupUtils.getRootThreadGroup(), this::shutdown);
+            Thread shutdown = new Thread(
+                    ThreadGroupUtils.getRootThreadGroup(), this::shutdown,
+                    "ToolkitShutdown", 0, false);
             shutdown.setContextClassLoader(null);
             Runtime.getRuntime().addShutdownHook(shutdown);
             return null;
--- a/jdk/src/java.desktop/windows/classes/sun/java2d/d3d/D3DScreenUpdateManager.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/windows/classes/sun/java2d/d3d/D3DScreenUpdateManager.java	Wed Jul 05 21:37:42 2017 +0200
@@ -49,7 +49,6 @@
 import sun.java2d.windows.GDIWindowSurfaceData;
 import sun.java2d.d3d.D3DSurfaceData.D3DWindowSurfaceData;
 import sun.java2d.windows.WindowsFlags;
-import sun.misc.ManagedLocalsThread;
 
 /**
  * This class handles rendering to the screen with the D3D pipeline.
@@ -99,8 +98,9 @@
                 done = true;
                 wakeUpUpdateThread();
             };
-            Thread shutdown = new ManagedLocalsThread(
-                    ThreadGroupUtils.getRootThreadGroup(), shutdownRunnable);
+            Thread shutdown = new Thread(
+                    ThreadGroupUtils.getRootThreadGroup(), shutdownRunnable,
+                    "ScreenUpdater", 0, false);
             shutdown.setContextClassLoader(null);
             try {
                 Runtime.getRuntime().addShutdownHook(shutdown);
@@ -348,8 +348,9 @@
         if (screenUpdater == null) {
             screenUpdater = AccessController.doPrivileged((PrivilegedAction<Thread>) () -> {
                 String name = "D3D Screen Updater";
-                Thread t = new ManagedLocalsThread(
-                        ThreadGroupUtils.getRootThreadGroup(), this, name);
+                Thread t = new Thread(
+                        ThreadGroupUtils.getRootThreadGroup(), this, name,
+                        0, false);
                 // REMIND: should it be higher?
                 t.setPriority(Thread.NORM_PRIORITY + 2);
                 t.setDaemon(true);
--- a/jdk/src/java.desktop/windows/classes/sun/print/PrintServiceLookupProvider.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/windows/classes/sun/print/PrintServiceLookupProvider.java	Wed Jul 05 21:37:42 2017 +0200
@@ -25,8 +25,6 @@
 
 package sun.print;
 
-import sun.misc.ManagedLocalsThread;
-
 import java.io.BufferedReader;
 import java.io.InputStream;
 import java.io.InputStreamReader;
@@ -99,7 +97,8 @@
                 return;
             }
             // start the printer listener thread
-            Thread thr = new ManagedLocalsThread(new PrinterChangeListener());
+            Thread thr = new Thread(null, new PrinterChangeListener(),
+                                    "PrinterListener", 0, false);
             thr.setDaemon(true);
             thr.start();
         } /* else condition ought to never happen! */
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Button.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Button.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -187,7 +187,7 @@
 AwtButton::NotifyListeners()
 {
     DoCallback("handleAction", "(JI)V", ::JVM_CurrentTimeMillis(NULL, 0),
-               (jint)AwtComponent::GetJavaModifiers());
+               (jint)AwtComponent::GetActionModifiers());
 }
 
 MsgRouting
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Component.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Component.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -60,6 +60,7 @@
 #include <java_awt_Insets.h>
 #include <sun_awt_windows_WPanelPeer.h>
 #include <java_awt_event_InputEvent.h>
+#include <java_awt_event_ActionEvent.h>
 #include <java_awt_event_InputMethodEvent.h>
 #include <sun_awt_windows_WInputMethod.h>
 #include <java_awt_event_MouseEvent.h>
@@ -2587,6 +2588,27 @@
     return java_awt_event_KeyEvent_KEY_LOCATION_LEFT;
 }
 
+/* Returns Java ActionEvent modifieres.
+ * When creating ActionEvent, modifiers provided by ActionEvent
+ * class should be set.
+ */
+jint
+AwtComponent::GetActionModifiers()
+{
+    jint modifiers = GetJavaModifiers();
+
+    if (modifiers & java_awt_event_InputEvent_CTRL_DOWN_MASK) {
+        modifiers |= java_awt_event_ActionEvent_CTRL_MASK;
+    }
+    if (modifiers & java_awt_event_InputEvent_SHIFT_DOWN_MASK) {
+        modifiers |= java_awt_event_ActionEvent_SHIFT_MASK;
+    }
+    if (modifiers & java_awt_event_InputEvent_ALT_DOWN_MASK) {
+        modifiers |= java_awt_event_ActionEvent_ALT_MASK;
+    }
+    return modifiers;
+}
+
 /* Returns Java extended InputEvent modifieres.
  * Since ::GetKeyState returns current state and Java modifiers represent
  * state before event, modifier on changed key are inverted.
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Component.h	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Component.h	Wed Jul 05 21:37:42 2017 +0200
@@ -438,6 +438,7 @@
     static void InitDynamicKeyMapTable();
     static void BuildDynamicKeyMapTable();
     static jint GetJavaModifiers();
+    static jint GetActionModifiers();
     static jint GetButton(int mouseButton);
     static UINT GetButtonMK(int mouseButton);
     static UINT WindowsKeyToJavaKey(UINT windowsKey, UINT modifiers, UINT character, BOOL isDeadKey);
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_List.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_List.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -536,7 +536,7 @@
             else if (notifyCode == LBN_DBLCLK) {
                 DoCallback("handleAction", "(IJI)V", nCurrentSelection,
                            ::JVM_CurrentTimeMillis(NULL, 0),
-                           (jint)AwtComponent::GetJavaModifiers());
+                           (jint)AwtComponent::GetActionModifiers());
             }
         }
     }
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_List.h	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_List.h	Wed Jul 05 21:37:42 2017 +0200
@@ -56,6 +56,7 @@
     }
     INLINE void Deselect(int pos) {
         if (isMultiSelect) {
+            SendListMessage(LB_SETCARETINDEX, pos, FALSE);
             SendListMessage(LB_SETSEL, FALSE, pos);
         }
         else {
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_MenuItem.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_MenuItem.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -667,7 +667,7 @@
         DoCallback("handleAction", "(Z)V", ((nState & MF_CHECKED) == 0));
     } else {
         DoCallback("handleAction", "(JI)V", ::JVM_CurrentTimeMillis(NULL, 0),
-                   (jint)AwtComponent::GetJavaModifiers());
+                   (jint)AwtComponent::GetActionModifiers());
     }
 }
 
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_TrayIcon.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_TrayIcon.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -409,7 +409,7 @@
         MSG msg;
         AwtComponent::InitMessage(&msg, lastMessage, flags, MAKELPARAM(x, y), x, y);
         SendActionEvent(java_awt_event_ActionEvent_ACTION_PERFORMED, ::JVM_CurrentTimeMillis(NULL, 0),
-                        AwtComponent::GetJavaModifiers(), &msg);
+                        AwtComponent::GetActionModifiers(), &msg);
     }
     return mrConsume;
 }
@@ -425,7 +425,7 @@
         MSG msg;
         AwtComponent::InitMessage(&msg, lastMessage, flags, MAKELPARAM(x, y), x, y);
         SendActionEvent(java_awt_event_ActionEvent_ACTION_PERFORMED, ::JVM_CurrentTimeMillis(NULL, 0),
-                        AwtComponent::GetJavaModifiers(), &msg);
+                        AwtComponent::GetActionModifiers(), &msg);
     }
     lastKeySelectTime = now;
 
@@ -442,7 +442,7 @@
         MSG msg;
         AwtComponent::InitMessage(&msg, lastMessage, flags, MAKELPARAM(x, y), x, y);
         SendActionEvent(java_awt_event_ActionEvent_ACTION_PERFORMED, ::JVM_CurrentTimeMillis(NULL, 0),
-                        AwtComponent::GetJavaModifiers(), &msg);
+                        AwtComponent::GetActionModifiers(), &msg);
     }
     return mrConsume;
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/BinaryRepresentationWriter.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,34 @@
+/*
+ * 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
+ * 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 sun.net.httpclient.hpack;
+
+import java.nio.ByteBuffer;
+
+interface BinaryRepresentationWriter {
+
+    boolean write(HeaderTable table, ByteBuffer destination);
+
+    BinaryRepresentationWriter reset();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/BulkSizeUpdateWriter.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,78 @@
+/*
+ * 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 sun.net.httpclient.hpack;
+
+import java.nio.ByteBuffer;
+import java.util.Iterator;
+
+import static java.util.Objects.requireNonNull;
+
+final class BulkSizeUpdateWriter implements BinaryRepresentationWriter {
+
+    private final SizeUpdateWriter writer = new SizeUpdateWriter();
+    private Iterator<Integer> maxSizes;
+    private boolean writing;
+    private boolean configured;
+
+    BulkSizeUpdateWriter maxHeaderTableSizes(Iterable<Integer> sizes) {
+        if (configured) {
+            throw new IllegalStateException("Already configured");
+        }
+        requireNonNull(sizes, "sizes");
+        maxSizes = sizes.iterator();
+        configured = true;
+        return this;
+    }
+
+    @Override
+    public boolean write(HeaderTable table, ByteBuffer destination) {
+        if (!configured) {
+            throw new IllegalStateException("Configure first");
+        }
+        while (true) {
+            if (writing) {
+                if (!writer.write(table, destination)) {
+                    return false;
+                }
+                writing = false;
+            } else if (maxSizes.hasNext()) {
+                writing = true;
+                writer.reset();
+                writer.maxHeaderTableSize(maxSizes.next());
+            } else {
+                configured = false;
+                return true;
+            }
+        }
+    }
+
+    @Override
+    public BulkSizeUpdateWriter reset() {
+        maxSizes = null;
+        writing = false;
+        configured = false;
+        return this;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/Decoder.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,506 @@
+/*
+ * 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
+ * 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 sun.net.httpclient.hpack;
+
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.net.ProtocolException;
+import java.nio.ByteBuffer;
+
+import static java.lang.String.format;
+import static java.util.Objects.requireNonNull;
+
+/**
+ * Decodes headers from their binary representation.
+ *
+ * <p>Typical lifecycle looks like this:
+ *
+ * <p> {@link #Decoder(int) new Decoder}
+ * ({@link #setMaxCapacity(int) setMaxCapacity}?
+ * {@link #decode(ByteBuffer, boolean, DecodingCallback) decode})*
+ *
+ * @apiNote
+ *
+ * <p> The design intentions behind Decoder were to facilitate flexible and
+ * incremental style of processing.
+ *
+ * <p> {@code Decoder} does not require a complete header block in a single
+ * {@code ByteBuffer}. The header block can be spread across many buffers of any
+ * size and decoded one-by-one the way it makes most sense for the user. This
+ * way also allows not to limit the size of the header block.
+ *
+ * <p> Headers are delivered to the {@linkplain DecodingCallback callback} as
+ * soon as they become decoded. Using the callback also gives the user a freedom
+ * to decide how headers are processed. The callback does not limit the number
+ * of headers decoded during single decoding operation.
+ *
+ * @since 9
+ */
+public final class Decoder {
+
+    private static final State[] states = new State[256];
+
+    static {
+        // To be able to do a quick lookup, each of 256 possibilities are mapped
+        // to corresponding states.
+        //
+        // We can safely do this since patterns 1, 01, 001, 0001, 0000 are
+        // Huffman prefixes and therefore are inherently not ambiguous.
+        //
+        // I do it mainly for better debugging (to not go each time step by step
+        // through if...else tree). As for performance win for the decoding, I
+        // believe is negligible.
+        for (int i = 0; i < states.length; i++) {
+            if ((i & 0b1000_0000) == 0b1000_0000) {
+                states[i] = State.INDEXED;
+            } else if ((i & 0b1100_0000) == 0b0100_0000) {
+                states[i] = State.LITERAL_WITH_INDEXING;
+            } else if ((i & 0b1110_0000) == 0b0010_0000) {
+                states[i] = State.SIZE_UPDATE;
+            } else if ((i & 0b1111_0000) == 0b0001_0000) {
+                states[i] = State.LITERAL_NEVER_INDEXED;
+            } else if ((i & 0b1111_0000) == 0b0000_0000) {
+                states[i] = State.LITERAL;
+            } else {
+                throw new InternalError(String.valueOf(i));
+            }
+        }
+    }
+
+    private final HeaderTable table;
+
+    private State state = State.READY;
+    private final IntegerReader integerReader;
+    private final StringReader stringReader;
+    private final StringBuilder name;
+    private final StringBuilder value;
+    private int intValue;
+    private boolean firstValueRead;
+    private boolean firstValueIndex;
+    private boolean nameHuffmanEncoded;
+    private boolean valueHuffmanEncoded;
+    private int capacity;
+
+    /**
+     * Constructs a {@code Decoder} with the specified initial capacity of the
+     * header table.
+     *
+     * <p> The value has to be agreed between decoder and encoder out-of-band,
+     * e.g. by a protocol that uses HPACK (see <a
+     * href="https://tools.ietf.org/html/rfc7541#section-4.2">4.2. Maximum Table
+     * Size</a>).
+     *
+     * @param capacity
+     *         a non-negative integer
+     *
+     * @throws IllegalArgumentException
+     *         if capacity is negative
+     */
+    public Decoder(int capacity) {
+        setMaxCapacity(capacity);
+        table = new HeaderTable(capacity);
+        integerReader = new IntegerReader();
+        stringReader = new StringReader();
+        name = new StringBuilder(512);
+        value = new StringBuilder(1024);
+    }
+
+    /**
+     * Sets a maximum capacity of the header table.
+     *
+     * <p> The value has to be agreed between decoder and encoder out-of-band,
+     * e.g. by a protocol that uses HPACK (see <a
+     * href="https://tools.ietf.org/html/rfc7541#section-4.2">4.2. Maximum Table
+     * Size</a>).
+     *
+     * @param capacity
+     *         a non-negative integer
+     *
+     * @throws IllegalArgumentException
+     *         if capacity is negative
+     */
+    public void setMaxCapacity(int capacity) {
+        if (capacity < 0) {
+            throw new IllegalArgumentException("capacity >= 0: " + capacity);
+        }
+        // FIXME: await capacity update if less than what was prior to it
+        this.capacity = capacity;
+    }
+
+    /**
+     * Decodes a header block from the given buffer to the given callback.
+     *
+     * <p> Suppose a header block is represented by a sequence of {@code
+     * ByteBuffer}s in the form of {@code Iterator<ByteBuffer>}. And the
+     * consumer of decoded headers is represented by the callback. Then to
+     * decode the header block, the following approach might be used:
+     *
+     * <pre>{@code
+     * while (buffers.hasNext()) {
+     *     ByteBuffer input = buffers.next();
+     *     decoder.decode(input, callback, !buffers.hasNext());
+     * }
+     * }</pre>
+     *
+     * <p> The decoder reads as much as possible of the header block from the
+     * given buffer, starting at the buffer's position, and increments its
+     * position to reflect the bytes read. The buffer's mark and limit will not
+     * be modified.
+     *
+     * <p> Once the method is invoked with {@code endOfHeaderBlock == true}, the
+     * current header block is deemed ended, and inconsistencies, if any, are
+     * reported immediately by throwing an {@code UncheckedIOException}.
+     *
+     * <p> Each callback method is called only after the implementation has
+     * processed the corresponding bytes. If the bytes revealed a decoding
+     * error, the callback method is not called.
+     *
+     * <p> In addition to exceptions thrown directly by the method, any
+     * exceptions thrown from the {@code callback} will bubble up.
+     *
+     * @apiNote The method asks for {@code endOfHeaderBlock} flag instead of
+     * returning it for two reasons. The first one is that the user of the
+     * decoder always knows which chunk is the last. The second one is to throw
+     * the most detailed exception possible, which might be useful for
+     * diagnosing issues.
+     *
+     * @implNote This implementation is not atomic in respect to decoding
+     * errors. In other words, if the decoding operation has thrown a decoding
+     * error, the decoder is no longer usable.
+     *
+     * @param headerBlock
+     *         the chunk of the header block, may be empty
+     * @param endOfHeaderBlock
+     *         true if the chunk is the final (or the only one) in the sequence
+     *
+     * @param consumer
+     *         the callback
+     * @throws UncheckedIOException
+     *         in case of a decoding error
+     * @throws NullPointerException
+     *         if either headerBlock or consumer are null
+     */
+    public void decode(ByteBuffer headerBlock, boolean endOfHeaderBlock,
+                       DecodingCallback consumer) {
+        requireNonNull(headerBlock, "headerBlock");
+        requireNonNull(consumer, "consumer");
+        while (headerBlock.hasRemaining()) {
+            proceed(headerBlock, consumer);
+        }
+        if (endOfHeaderBlock && state != State.READY) {
+            throw new UncheckedIOException(
+                    new ProtocolException("Unexpected end of header block"));
+        }
+    }
+
+    private void proceed(ByteBuffer input, DecodingCallback action) {
+        switch (state) {
+            case READY:
+                resumeReady(input);
+                break;
+            case INDEXED:
+                resumeIndexed(input, action);
+                break;
+            case LITERAL:
+                resumeLiteral(input, action);
+                break;
+            case LITERAL_WITH_INDEXING:
+                resumeLiteralWithIndexing(input, action);
+                break;
+            case LITERAL_NEVER_INDEXED:
+                resumeLiteralNeverIndexed(input, action);
+                break;
+            case SIZE_UPDATE:
+                resumeSizeUpdate(input, action);
+                break;
+            default:
+                throw new InternalError(
+                        "Unexpected decoder state: " + String.valueOf(state));
+        }
+    }
+
+    private void resumeReady(ByteBuffer input) {
+        int b = input.get(input.position()) & 0xff; // absolute read
+        State s = states[b];
+        switch (s) {
+            case INDEXED:
+                integerReader.configure(7);
+                state = State.INDEXED;
+                firstValueIndex = true;
+                break;
+            case LITERAL:
+                state = State.LITERAL;
+                firstValueIndex = (b & 0b0000_1111) != 0;
+                if (firstValueIndex) {
+                    integerReader.configure(4);
+                }
+                break;
+            case LITERAL_WITH_INDEXING:
+                state = State.LITERAL_WITH_INDEXING;
+                firstValueIndex = (b & 0b0011_1111) != 0;
+                if (firstValueIndex) {
+                    integerReader.configure(6);
+                }
+                break;
+            case LITERAL_NEVER_INDEXED:
+                state = State.LITERAL_NEVER_INDEXED;
+                firstValueIndex = (b & 0b0000_1111) != 0;
+                if (firstValueIndex) {
+                    integerReader.configure(4);
+                }
+                break;
+            case SIZE_UPDATE:
+                integerReader.configure(5);
+                state = State.SIZE_UPDATE;
+                firstValueIndex = true;
+                break;
+            default:
+                throw new InternalError(String.valueOf(s));
+        }
+        if (!firstValueIndex) {
+            input.get(); // advance, next stop: "String Literal"
+        }
+    }
+
+    //              0   1   2   3   4   5   6   7
+    //            +---+---+---+---+---+---+---+---+
+    //            | 1 |        Index (7+)         |
+    //            +---+---------------------------+
+    //
+    private void resumeIndexed(ByteBuffer input, DecodingCallback action) {
+        if (!integerReader.read(input)) {
+            return;
+        }
+        intValue = integerReader.get();
+        integerReader.reset();
+        try {
+            HeaderTable.HeaderField f = table.get(intValue);
+            action.onIndexed(intValue, f.name, f.value);
+        } finally {
+            state = State.READY;
+        }
+    }
+
+    //              0   1   2   3   4   5   6   7
+    //            +---+---+---+---+---+---+---+---+
+    //            | 0 | 0 | 0 | 0 |  Index (4+)   |
+    //            +---+---+-----------------------+
+    //            | H |     Value Length (7+)     |
+    //            +---+---------------------------+
+    //            | Value String (Length octets)  |
+    //            +-------------------------------+
+    //
+    //              0   1   2   3   4   5   6   7
+    //            +---+---+---+---+---+---+---+---+
+    //            | 0 | 0 | 0 | 0 |       0       |
+    //            +---+---+-----------------------+
+    //            | H |     Name Length (7+)      |
+    //            +---+---------------------------+
+    //            |  Name String (Length octets)  |
+    //            +---+---------------------------+
+    //            | H |     Value Length (7+)     |
+    //            +---+---------------------------+
+    //            | Value String (Length octets)  |
+    //            +-------------------------------+
+    //
+    private void resumeLiteral(ByteBuffer input, DecodingCallback action) {
+        if (!completeReading(input)) {
+            return;
+        }
+        try {
+            if (firstValueIndex) {
+                HeaderTable.HeaderField f = table.get(intValue);
+                action.onLiteral(intValue, f.name, value, valueHuffmanEncoded);
+            } else {
+                action.onLiteral(name, nameHuffmanEncoded, value, valueHuffmanEncoded);
+            }
+        } finally {
+            cleanUpAfterReading();
+        }
+    }
+
+    //
+    //              0   1   2   3   4   5   6   7
+    //            +---+---+---+---+---+---+---+---+
+    //            | 0 | 1 |      Index (6+)       |
+    //            +---+---+-----------------------+
+    //            | H |     Value Length (7+)     |
+    //            +---+---------------------------+
+    //            | Value String (Length octets)  |
+    //            +-------------------------------+
+    //
+    //              0   1   2   3   4   5   6   7
+    //            +---+---+---+---+---+---+---+---+
+    //            | 0 | 1 |           0           |
+    //            +---+---+-----------------------+
+    //            | H |     Name Length (7+)      |
+    //            +---+---------------------------+
+    //            |  Name String (Length octets)  |
+    //            +---+---------------------------+
+    //            | H |     Value Length (7+)     |
+    //            +---+---------------------------+
+    //            | Value String (Length octets)  |
+    //            +-------------------------------+
+    //
+    private void resumeLiteralWithIndexing(ByteBuffer input, DecodingCallback action) {
+        if (!completeReading(input)) {
+            return;
+        }
+        try {
+            //
+            // 1. (name, value) will be stored in the table as strings
+            // 2. Most likely the callback will also create strings from them
+            // ------------------------------------------------------------------------
+            //    Let's create those string beforehand (and only once!) to benefit everyone
+            //
+            String n;
+            String v = value.toString();
+            if (firstValueIndex) {
+                HeaderTable.HeaderField f = table.get(intValue);
+                n = f.name;
+                action.onLiteralWithIndexing(intValue, n, v, valueHuffmanEncoded);
+            } else {
+                n = name.toString();
+                action.onLiteralWithIndexing(n, nameHuffmanEncoded, v, valueHuffmanEncoded);
+            }
+            table.put(n, v);
+        } catch (IllegalArgumentException | IllegalStateException e) {
+            throw new UncheckedIOException(
+                    (IOException) new ProtocolException().initCause(e));
+        } finally {
+            cleanUpAfterReading();
+        }
+    }
+
+    //              0   1   2   3   4   5   6   7
+    //            +---+---+---+---+---+---+---+---+
+    //            | 0 | 0 | 0 | 1 |  Index (4+)   |
+    //            +---+---+-----------------------+
+    //            | H |     Value Length (7+)     |
+    //            +---+---------------------------+
+    //            | Value String (Length octets)  |
+    //            +-------------------------------+
+    //
+    //              0   1   2   3   4   5   6   7
+    //            +---+---+---+---+---+---+---+---+
+    //            | 0 | 0 | 0 | 1 |       0       |
+    //            +---+---+-----------------------+
+    //            | H |     Name Length (7+)      |
+    //            +---+---------------------------+
+    //            |  Name String (Length octets)  |
+    //            +---+---------------------------+
+    //            | H |     Value Length (7+)     |
+    //            +---+---------------------------+
+    //            | Value String (Length octets)  |
+    //            +-------------------------------+
+    //
+    private void resumeLiteralNeverIndexed(ByteBuffer input, DecodingCallback action) {
+        if (!completeReading(input)) {
+            return;
+        }
+        try {
+            if (firstValueIndex) {
+                HeaderTable.HeaderField f = table.get(intValue);
+                action.onLiteralNeverIndexed(intValue, f.name, value, valueHuffmanEncoded);
+            } else {
+                action.onLiteralNeverIndexed(name, nameHuffmanEncoded, value, valueHuffmanEncoded);
+            }
+        } finally {
+            cleanUpAfterReading();
+        }
+    }
+
+    //              0   1   2   3   4   5   6   7
+    //            +---+---+---+---+---+---+---+---+
+    //            | 0 | 0 | 1 |   Max size (5+)   |
+    //            +---+---------------------------+
+    //
+    private void resumeSizeUpdate(ByteBuffer input, DecodingCallback action) {
+        if (!integerReader.read(input)) {
+            return;
+        }
+        intValue = integerReader.get();
+        assert intValue >= 0;
+        if (intValue > capacity) {
+            throw new UncheckedIOException(new ProtocolException(
+                    format("Received capacity exceeds expected: " +
+                            "capacity=%s, expected=%s", intValue, capacity)));
+        }
+        integerReader.reset();
+        try {
+            action.onSizeUpdate(intValue);
+            table.setMaxSize(intValue);
+        } finally {
+            state = State.READY;
+        }
+    }
+
+    private boolean completeReading(ByteBuffer input) {
+        if (!firstValueRead) {
+            if (firstValueIndex) {
+                if (!integerReader.read(input)) {
+                    return false;
+                }
+                intValue = integerReader.get();
+                integerReader.reset();
+            } else {
+                if (!stringReader.read(input, name)) {
+                    return false;
+                }
+                nameHuffmanEncoded = stringReader.isHuffmanEncoded();
+                stringReader.reset();
+            }
+            firstValueRead = true;
+            return false;
+        } else {
+            if (!stringReader.read(input, value)) {
+                return false;
+            }
+        }
+        valueHuffmanEncoded = stringReader.isHuffmanEncoded();
+        stringReader.reset();
+        return true;
+    }
+
+    private void cleanUpAfterReading() {
+        name.setLength(0);
+        value.setLength(0);
+        firstValueRead = false;
+        state = State.READY;
+    }
+
+    private enum State {
+        READY,
+        INDEXED,
+        LITERAL_NEVER_INDEXED,
+        LITERAL,
+        LITERAL_WITH_INDEXING,
+        SIZE_UPDATE
+    }
+
+    HeaderTable getTable() {
+        return table;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/DecodingCallback.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,284 @@
+/*
+ * 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
+ * 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 sun.net.httpclient.hpack;
+
+import java.nio.ByteBuffer;
+
+/**
+ * Delivers results of the {@link Decoder#decode(ByteBuffer, boolean,
+ * DecodingCallback) decoding operation}.
+ *
+ * <p> Methods of the callback are never called by a decoder with any of the
+ * arguments being {@code null}.
+ *
+ * @apiNote
+ *
+ * <p> The callback provides methods for all possible <a
+ * href="https://tools.ietf.org/html/rfc7541#section-6">binary
+ * representations</a>. This could be useful for implementing an intermediary,
+ * logging, debugging, etc.
+ *
+ * <p> The callback is an interface in order to interoperate with lambdas (in
+ * the most common use case):
+ * <pre>{@code
+ *     DecodingCallback callback = (name, value) -> System.out.println(name + ", " + value);
+ * }</pre>
+ *
+ * <p> Names and values are {@link CharSequence}s rather than {@link String}s in
+ * order to allow users to decide whether or not they need to create objects. A
+ * {@code CharSequence} might be used in-place, for example, to be appended to
+ * an {@link Appendable} (e.g. {@link StringBuilder}) and then discarded.
+ *
+ * <p> That said, if a passed {@code CharSequence} needs to outlast the method
+ * call, it needs to be copied.
+ *
+ * @since 9
+ */
+@FunctionalInterface
+public interface DecodingCallback {
+
+    /**
+     * A method the more specific methods of the callback forward their calls
+     * to.
+     *
+     * @param name
+     *         header name
+     * @param value
+     *         header value
+     */
+    void onDecoded(CharSequence name, CharSequence value);
+
+    /**
+     * A more finer-grained version of {@link #onDecoded(CharSequence,
+     * CharSequence)} that also reports on value sensitivity.
+     *
+     * <p> Value sensitivity must be considered, for example, when implementing
+     * an intermediary. A {@code value} is sensitive if it was represented as <a
+     * href="https://tools.ietf.org/html/rfc7541#section-6.2.3">Literal Header
+     * Field Never Indexed</a>.
+     *
+     * <p> It is required that intermediaries MUST use the {@linkplain
+     * Encoder#header(CharSequence, CharSequence, boolean) same representation}
+     * for encoding this header field in order to protect its value which is not
+     * to be put at risk by compressing it.
+     *
+     * @implSpec
+     *
+     * <p> The default implementation invokes {@code onDecoded(name, value)}.
+     *
+     * @param name
+     *         header name
+     * @param value
+     *         header value
+     * @param sensitive
+     *         whether or not the value is sensitive
+     *
+     * @see #onLiteralNeverIndexed(int, CharSequence, CharSequence, boolean)
+     * @see #onLiteralNeverIndexed(CharSequence, boolean, CharSequence, boolean)
+     */
+    default void onDecoded(CharSequence name, CharSequence value,
+                           boolean sensitive) {
+        onDecoded(name, value);
+    }
+
+    /**
+     * An <a href="https://tools.ietf.org/html/rfc7541#section-6.1">Indexed
+     * Header Field</a> decoded.
+     *
+     * @implSpec
+     *
+     * <p> The default implementation invokes
+     * {@code onDecoded(name, value, false)}.
+     *
+     * @param index
+     *         index of an entry in the table
+     * @param name
+     *         header name
+     * @param value
+     *         header value
+     */
+    default void onIndexed(int index, CharSequence name, CharSequence value) {
+        onDecoded(name, value, false);
+    }
+
+    /**
+     * A <a href="https://tools.ietf.org/html/rfc7541#section-6.2.2">Literal
+     * Header Field without Indexing</a> decoded, where a {@code name} was
+     * referred by an {@code index}.
+     *
+     * @implSpec
+     *
+     * <p> The default implementation invokes
+     * {@code onDecoded(name, value, false)}.
+     *
+     * @param index
+     *         index of an entry in the table
+     * @param name
+     *         header name
+     * @param value
+     *         header value
+     * @param valueHuffman
+     *         if the {@code value} was Huffman encoded
+     */
+    default void onLiteral(int index, CharSequence name,
+                           CharSequence value, boolean valueHuffman) {
+        onDecoded(name, value, false);
+    }
+
+    /**
+     * A <a href="https://tools.ietf.org/html/rfc7541#section-6.2.2">Literal
+     * Header Field without Indexing</a> decoded, where both a {@code name} and
+     * a {@code value} were literal.
+     *
+     * @implSpec
+     *
+     * <p> The default implementation invokes
+     * {@code onDecoded(name, value, false)}.
+     *
+     * @param name
+     *         header name
+     * @param nameHuffman
+     *         if the {@code name} was Huffman encoded
+     * @param value
+     *         header value
+     * @param valueHuffman
+     *         if the {@code value} was Huffman encoded
+     */
+    default void onLiteral(CharSequence name, boolean nameHuffman,
+                           CharSequence value, boolean valueHuffman) {
+        onDecoded(name, value, false);
+    }
+
+    /**
+     * A <a href="https://tools.ietf.org/html/rfc7541#section-6.2.3">Literal
+     * Header Field Never Indexed</a> decoded, where a {@code name}
+     * was referred by an {@code index}.
+     *
+     * @implSpec
+     *
+     * <p> The default implementation invokes
+     * {@code onDecoded(name, value, true)}.
+     *
+     * @param index
+     *         index of an entry in the table
+     * @param name
+     *         header name
+     * @param value
+     *         header value
+     * @param valueHuffman
+     *         if the {@code value} was Huffman encoded
+     */
+    default void onLiteralNeverIndexed(int index, CharSequence name,
+                                       CharSequence value,
+                                       boolean valueHuffman) {
+        onDecoded(name, value, true);
+    }
+
+    /**
+     * A <a href="https://tools.ietf.org/html/rfc7541#section-6.2.3">Literal
+     * Header Field Never Indexed</a> decoded, where both a {@code
+     * name} and a {@code value} were literal.
+     *
+     * @implSpec
+     *
+     * <p> The default implementation invokes
+     * {@code onDecoded(name, value, true)}.
+     *
+     * @param name
+     *         header name
+     * @param nameHuffman
+     *         if the {@code name} was Huffman encoded
+     * @param value
+     *         header value
+     * @param valueHuffman
+     *         if the {@code value} was Huffman encoded
+     */
+    default void onLiteralNeverIndexed(CharSequence name, boolean nameHuffman,
+                                       CharSequence value, boolean valueHuffman) {
+        onDecoded(name, value, true);
+    }
+
+    /**
+     * A <a href="https://tools.ietf.org/html/rfc7541#section-6.2.1">Literal
+     * Header Field with Incremental Indexing</a> decoded, where a {@code name}
+     * was referred by an {@code index}.
+     *
+     * @implSpec
+     *
+     * <p> The default implementation invokes
+     * {@code onDecoded(name, value, false)}.
+     *
+     * @param index
+     *         index of an entry in the table
+     * @param name
+     *         header name
+     * @param value
+     *         header value
+     * @param valueHuffman
+     *         if the {@code value} was Huffman encoded
+     */
+    default void onLiteralWithIndexing(int index,
+                                       CharSequence name,
+                                       CharSequence value, boolean valueHuffman) {
+        onDecoded(name, value, false);
+    }
+
+    /**
+     * A <a href="https://tools.ietf.org/html/rfc7541#section-6.2.1">Literal
+     * Header Field with Incremental Indexing</a> decoded, where both a {@code
+     * name} and a {@code value} were literal.
+     *
+     * @implSpec
+     *
+     * <p> The default implementation invokes
+     * {@code onDecoded(name, value, false)}.
+     *
+     * @param name
+     *         header name
+     * @param nameHuffman
+     *         if the {@code name} was Huffman encoded
+     * @param value
+     *         header value
+     * @param valueHuffman
+     *         if the {@code value} was Huffman encoded
+     */
+    default void onLiteralWithIndexing(CharSequence name, boolean nameHuffman,
+                                       CharSequence value, boolean valueHuffman) {
+        onDecoded(name, value, false);
+    }
+
+    /**
+     * A <a href="https://tools.ietf.org/html/rfc7541#section-6.3">Dynamic Table
+     * Size Update</a> decoded.
+     *
+     * @implSpec
+     *
+     * <p> The default implementation does nothing.
+     *
+     * @param capacity
+     *         new capacity of the header table
+     */
+    default void onSizeUpdate(int capacity) { }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/Encoder.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,429 @@
+/*
+ * 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
+ * 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 sun.net.httpclient.hpack;
+
+import java.nio.ByteBuffer;
+import java.nio.ReadOnlyBufferException;
+import java.util.LinkedList;
+import java.util.List;
+
+import static java.lang.String.format;
+import static java.util.Objects.requireNonNull;
+
+/**
+ * Encodes headers to their binary representation.
+ *
+ * <p>Typical lifecycle looks like this:
+ *
+ * <p> {@link #Encoder(int) new Encoder}
+ * ({@link #setMaxCapacity(int) setMaxCapacity}?
+ * {@link #encode(ByteBuffer) encode})*
+ *
+ * <p> Suppose headers are represented by {@code Map<String, List<String>>}. A
+ * supplier and a consumer of {@link ByteBuffer}s in forms of {@code
+ * Supplier<ByteBuffer>} and {@code Consumer<ByteBuffer>} respectively. Then to
+ * encode headers, the following approach might be used:
+ *
+ * <pre>{@code
+ *     for (Map.Entry<String, List<String>> h : headers.entrySet()) {
+ *         String name = h.getKey();
+ *         for (String value : h.getValue()) {
+ *             encoder.header(name, value);        // Set up header
+ *             boolean encoded;
+ *             do {
+ *                 ByteBuffer b = buffersSupplier.get();
+ *                 encoded = encoder.encode(b);    // Encode the header
+ *                 buffersConsumer.accept(b);
+ *             } while (!encoded);
+ *         }
+ *     }
+ * }</pre>
+ *
+ * <p> Though the specification <a
+ * href="https://tools.ietf.org/html/rfc7541#section-2"> does not define</a> how
+ * an encoder is to be implemented, a default implementation is provided by the
+ * method {@link #header(CharSequence, CharSequence, boolean)}.
+ *
+ * <p> To provide a custom encoding implementation, {@code Encoder} has to be
+ * extended. A subclass then can access methods for encoding using specific
+ * representations (e.g. {@link #literal(int, CharSequence, boolean) literal},
+ * {@link #indexed(int) indexed}, etc.)
+ *
+ * @apiNote
+ *
+ * <p> An Encoder provides an incremental way of encoding headers.
+ * {@link #encode(ByteBuffer)} takes a buffer a returns a boolean indicating
+ * whether, or not, the buffer was sufficiently sized to hold the
+ * remaining of the encoded representation.
+ *
+ * <p> This way, there's no need to provide a buffer of a specific size, or to
+ * resize (and copy) the buffer on demand, when the remaining encoded
+ * representation will not fit in the buffer's remaining space. Instead, an
+ * array of existing buffers can be used, prepended with a frame that encloses
+ * the resulting header block afterwards.
+ *
+ * <p> Splitting the encoding operation into header set up and header encoding,
+ * separates long lived arguments ({@code name}, {@code value}, {@code
+ * sensitivity}, etc.) from the short lived ones (e.g. {@code buffer}),
+ * simplifying each operation itself.
+ *
+ * @implNote
+ *
+ * <p> The default implementation does not use dynamic table. It reports to a
+ * coupled Decoder a size update with the value of {@code 0}, and never changes
+ * it afterwards.
+ *
+ * @since 9
+ */
+public class Encoder {
+
+    // TODO: enum: no huffman/smart huffman/always huffman
+    private static final boolean DEFAULT_HUFFMAN = true;
+
+    private final IndexedWriter indexedWriter = new IndexedWriter();
+    private final LiteralWriter literalWriter = new LiteralWriter();
+    private final LiteralNeverIndexedWriter literalNeverIndexedWriter
+            = new LiteralNeverIndexedWriter();
+    private final LiteralWithIndexingWriter literalWithIndexingWriter
+            = new LiteralWithIndexingWriter();
+    private final SizeUpdateWriter sizeUpdateWriter = new SizeUpdateWriter();
+    private final BulkSizeUpdateWriter bulkSizeUpdateWriter
+            = new BulkSizeUpdateWriter();
+
+    private BinaryRepresentationWriter writer;
+    private final HeaderTable headerTable;
+
+    private boolean encoding;
+
+    private int maxCapacity;
+    private int currCapacity;
+    private int lastCapacity;
+    private long minCapacity;
+    private boolean capacityUpdate;
+    private boolean configuredCapacityUpdate;
+
+    /**
+     * Constructs an {@code Encoder} with the specified maximum capacity of the
+     * header table.
+     *
+     * <p> The value has to be agreed between decoder and encoder out-of-band,
+     * e.g. by a protocol that uses HPACK (see <a
+     * href="https://tools.ietf.org/html/rfc7541#section-4.2">4.2. Maximum Table
+     * Size</a>).
+     *
+     * @param maxCapacity
+     *         a non-negative integer
+     *
+     * @throws IllegalArgumentException
+     *         if maxCapacity is negative
+     */
+    public Encoder(int maxCapacity) {
+        if (maxCapacity < 0) {
+            throw new IllegalArgumentException("maxCapacity >= 0: " + maxCapacity);
+        }
+        // Initial maximum capacity update mechanics
+        minCapacity = Long.MAX_VALUE;
+        currCapacity = -1;
+        setMaxCapacity(maxCapacity);
+        headerTable = new HeaderTable(lastCapacity);
+    }
+
+    /**
+     * Sets up the given header {@code (name, value)}.
+     *
+     * <p> Fixates {@code name} and {@code value} for the duration of encoding.
+     *
+     * @param name
+     *         the name
+     * @param value
+     *         the value
+     *
+     * @throws NullPointerException
+     *         if any of the arguments are {@code null}
+     * @throws IllegalStateException
+     *         if the encoder hasn't fully encoded the previous header, or
+     *         hasn't yet started to encode it
+     * @see #header(CharSequence, CharSequence, boolean)
+     */
+    public void header(CharSequence name, CharSequence value)
+            throws IllegalStateException {
+        header(name, value, false);
+    }
+
+    /**
+     * Sets up the given header {@code (name, value)} with possibly sensitive
+     * value.
+     *
+     * <p> Fixates {@code name} and {@code value} for the duration of encoding.
+     *
+     * @param name
+     *         the name
+     * @param value
+     *         the value
+     * @param sensitive
+     *         whether or not the value is sensitive
+     *
+     * @throws NullPointerException
+     *         if any of the arguments are {@code null}
+     * @throws IllegalStateException
+     *         if the encoder hasn't fully encoded the previous header, or
+     *         hasn't yet started to encode it
+     * @see #header(CharSequence, CharSequence)
+     * @see DecodingCallback#onDecoded(CharSequence, CharSequence, boolean)
+     */
+    public void header(CharSequence name, CharSequence value,
+                       boolean sensitive) throws IllegalStateException {
+        // Arguably a good balance between complexity of implementation and
+        // efficiency of encoding
+        requireNonNull(name, "name");
+        requireNonNull(value, "value");
+        HeaderTable t = getHeaderTable();
+        int index = t.indexOf(name, value);
+        if (index > 0) {
+            indexed(index);
+        } else if (index < 0) {
+            if (sensitive) {
+                literalNeverIndexed(-index, value, DEFAULT_HUFFMAN);
+            } else {
+                literal(-index, value, DEFAULT_HUFFMAN);
+            }
+        } else {
+            if (sensitive) {
+                literalNeverIndexed(name, DEFAULT_HUFFMAN, value, DEFAULT_HUFFMAN);
+            } else {
+                literal(name, DEFAULT_HUFFMAN, value, DEFAULT_HUFFMAN);
+            }
+        }
+    }
+
+    /**
+     * Sets a maximum capacity of the header table.
+     *
+     * <p> The value has to be agreed between decoder and encoder out-of-band,
+     * e.g. by a protocol that uses HPACK (see <a
+     * href="https://tools.ietf.org/html/rfc7541#section-4.2">4.2. Maximum Table
+     * Size</a>).
+     *
+     * <p> May be called any number of times after or before a complete header
+     * has been encoded.
+     *
+     * <p> If the encoder decides to change the actual capacity, an update will
+     * be encoded before a new encoding operation starts.
+     *
+     * @param capacity
+     *         a non-negative integer
+     *
+     * @throws IllegalArgumentException
+     *         if capacity is negative
+     * @throws IllegalStateException
+     *         if the encoder hasn't fully encoded the previous header, or
+     *         hasn't yet started to encode it
+     */
+    public void setMaxCapacity(int capacity) {
+        checkEncoding();
+        if (capacity < 0) {
+            throw new IllegalArgumentException("capacity >= 0: " + capacity);
+        }
+        int calculated = calculateCapacity(capacity);
+        if (calculated < 0 || calculated > capacity) {
+            throw new IllegalArgumentException(
+                    format("0 <= calculated <= capacity: calculated=%s, capacity=%s",
+                            calculated, capacity));
+        }
+        capacityUpdate = true;
+        // maxCapacity needs to be updated unconditionally, so the encoder
+        // always has the newest one (in case it decides to update it later
+        // unsolicitedly)
+        // Suppose maxCapacity = 4096, and the encoder has decided to use only
+        // 2048. It later can choose anything else from the region [0, 4096].
+        maxCapacity = capacity;
+        lastCapacity = calculated;
+        minCapacity = Math.min(minCapacity, lastCapacity);
+    }
+
+    protected int calculateCapacity(int maxCapacity) {
+        // Default implementation of the Encoder won't add anything to the
+        // table, therefore no need for a table space
+        return 0;
+    }
+
+    /**
+     * Encodes the {@linkplain #header(CharSequence, CharSequence) set up}
+     * header into the given buffer.
+     *
+     * <p> The encoder writes as much as possible of the header's binary
+     * representation into the given buffer, starting at the buffer's position,
+     * and increments its position to reflect the bytes written. The buffer's
+     * mark and limit will not be modified.
+     *
+     * <p> Once the method has returned {@code true}, the current header is
+     * deemed encoded. A new header may be set up.
+     *
+     * @param headerBlock
+     *         the buffer to encode the header into, may be empty
+     *
+     * @return {@code true} if the current header has been fully encoded,
+     *         {@code false} otherwise
+     *
+     * @throws NullPointerException
+     *         if the buffer is {@code null}
+     * @throws ReadOnlyBufferException
+     *         if this buffer is read-only
+     * @throws IllegalStateException
+     *         if there is no set up header
+     */
+    public final boolean encode(ByteBuffer headerBlock) {
+        if (!encoding) {
+            throw new IllegalStateException("A header hasn't been set up");
+        }
+        if (!prependWithCapacityUpdate(headerBlock)) {
+            return false;
+        }
+        boolean done = writer.write(headerTable, headerBlock);
+        if (done) {
+            writer.reset(); // FIXME: WHY?
+            encoding = false;
+        }
+        return done;
+    }
+
+    private boolean prependWithCapacityUpdate(ByteBuffer headerBlock) {
+        if (capacityUpdate) {
+            if (!configuredCapacityUpdate) {
+                List<Integer> sizes = new LinkedList<>();
+                if (minCapacity < currCapacity) {
+                    sizes.add((int) minCapacity);
+                    if (minCapacity != lastCapacity) {
+                        sizes.add(lastCapacity);
+                    }
+                } else if (lastCapacity != currCapacity) {
+                    sizes.add(lastCapacity);
+                }
+                bulkSizeUpdateWriter.maxHeaderTableSizes(sizes);
+                configuredCapacityUpdate = true;
+            }
+            boolean done = bulkSizeUpdateWriter.write(headerTable, headerBlock);
+            if (done) {
+                minCapacity = lastCapacity;
+                currCapacity = lastCapacity;
+                bulkSizeUpdateWriter.reset();
+                capacityUpdate = false;
+                configuredCapacityUpdate = false;
+            }
+            return done;
+        }
+        return true;
+    }
+
+    protected final void indexed(int index) throws IndexOutOfBoundsException {
+        checkEncoding();
+        encoding = true;
+        writer = indexedWriter.index(index);
+    }
+
+    protected final void literal(int index, CharSequence value,
+                                 boolean useHuffman)
+            throws IndexOutOfBoundsException {
+        checkEncoding();
+        encoding = true;
+        writer = literalWriter
+                .index(index).value(value, useHuffman);
+    }
+
+    protected final void literal(CharSequence name, boolean nameHuffman,
+                                 CharSequence value, boolean valueHuffman) {
+        checkEncoding();
+        encoding = true;
+        writer = literalWriter
+                .name(name, nameHuffman).value(value, valueHuffman);
+    }
+
+    protected final void literalNeverIndexed(int index,
+                                             CharSequence value,
+                                             boolean valueHuffman)
+            throws IndexOutOfBoundsException {
+        checkEncoding();
+        encoding = true;
+        writer = literalNeverIndexedWriter
+                .index(index).value(value, valueHuffman);
+    }
+
+    protected final void literalNeverIndexed(CharSequence name,
+                                             boolean nameHuffman,
+                                             CharSequence value,
+                                             boolean valueHuffman) {
+        checkEncoding();
+        encoding = true;
+        writer = literalNeverIndexedWriter
+                .name(name, nameHuffman).value(value, valueHuffman);
+    }
+
+    protected final void literalWithIndexing(int index,
+                                             CharSequence value,
+                                             boolean valueHuffman)
+            throws IndexOutOfBoundsException {
+        checkEncoding();
+        encoding = true;
+        writer = literalWithIndexingWriter
+                .index(index).value(value, valueHuffman);
+    }
+
+    protected final void literalWithIndexing(CharSequence name,
+                                             boolean nameHuffman,
+                                             CharSequence value,
+                                             boolean valueHuffman) {
+        checkEncoding();
+        encoding = true;
+        writer = literalWithIndexingWriter
+                .name(name, nameHuffman).value(value, valueHuffman);
+    }
+
+    protected final void sizeUpdate(int capacity)
+            throws IllegalArgumentException {
+        checkEncoding();
+        // Ensure subclass follows the contract
+        if (capacity > this.maxCapacity) {
+            throw new IllegalArgumentException(
+                    format("capacity <= maxCapacity: capacity=%s, maxCapacity=%s",
+                            capacity, maxCapacity));
+        }
+        writer = sizeUpdateWriter.maxHeaderTableSize(capacity);
+    }
+
+    protected final int getMaxCapacity() {
+        return maxCapacity;
+    }
+
+    protected final HeaderTable getHeaderTable() {
+        return headerTable;
+    }
+
+    protected final void checkEncoding() {
+        if (encoding) {
+            throw new IllegalStateException(
+                    "Previous encoding operation hasn't finished yet");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/HeaderTable.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,511 @@
+/*
+ * 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
+ * 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 sun.net.httpclient.hpack;
+
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.NoSuchElementException;
+
+import static java.lang.String.format;
+
+//
+// Header Table combined from two tables: static and dynamic.
+//
+// There is a single address space for index values. Index-aware methods
+// correspond to the table as a whole. Size-aware methods only to the dynamic
+// part of it.
+//
+final class HeaderTable {
+
+    private static final HeaderField[] staticTable = {
+            null, // To make index 1-based, instead of 0-based
+            new HeaderField(":authority"),
+            new HeaderField(":method", "GET"),
+            new HeaderField(":method", "POST"),
+            new HeaderField(":path", "/"),
+            new HeaderField(":path", "/index.html"),
+            new HeaderField(":scheme", "http"),
+            new HeaderField(":scheme", "https"),
+            new HeaderField(":status", "200"),
+            new HeaderField(":status", "204"),
+            new HeaderField(":status", "206"),
+            new HeaderField(":status", "304"),
+            new HeaderField(":status", "400"),
+            new HeaderField(":status", "404"),
+            new HeaderField(":status", "500"),
+            new HeaderField("accept-charset"),
+            new HeaderField("accept-encoding", "gzip, deflate"),
+            new HeaderField("accept-language"),
+            new HeaderField("accept-ranges"),
+            new HeaderField("accept"),
+            new HeaderField("access-control-allow-origin"),
+            new HeaderField("age"),
+            new HeaderField("allow"),
+            new HeaderField("authorization"),
+            new HeaderField("cache-control"),
+            new HeaderField("content-disposition"),
+            new HeaderField("content-encoding"),
+            new HeaderField("content-language"),
+            new HeaderField("content-length"),
+            new HeaderField("content-location"),
+            new HeaderField("content-range"),
+            new HeaderField("content-type"),
+            new HeaderField("cookie"),
+            new HeaderField("date"),
+            new HeaderField("etag"),
+            new HeaderField("expect"),
+            new HeaderField("expires"),
+            new HeaderField("from"),
+            new HeaderField("host"),
+            new HeaderField("if-match"),
+            new HeaderField("if-modified-since"),
+            new HeaderField("if-none-match"),
+            new HeaderField("if-range"),
+            new HeaderField("if-unmodified-since"),
+            new HeaderField("last-modified"),
+            new HeaderField("link"),
+            new HeaderField("location"),
+            new HeaderField("max-forwards"),
+            new HeaderField("proxy-authenticate"),
+            new HeaderField("proxy-authorization"),
+            new HeaderField("range"),
+            new HeaderField("referer"),
+            new HeaderField("refresh"),
+            new HeaderField("retry-after"),
+            new HeaderField("server"),
+            new HeaderField("set-cookie"),
+            new HeaderField("strict-transport-security"),
+            new HeaderField("transfer-encoding"),
+            new HeaderField("user-agent"),
+            new HeaderField("vary"),
+            new HeaderField("via"),
+            new HeaderField("www-authenticate")
+    };
+
+    private static final int STATIC_TABLE_LENGTH = staticTable.length - 1;
+    private static final int ENTRY_SIZE = 32;
+    private static final Map<String, LinkedHashMap<String, Integer>> staticIndexes;
+
+    static {
+        staticIndexes = new HashMap<>(STATIC_TABLE_LENGTH);
+        for (int i = 1; i <= STATIC_TABLE_LENGTH; i++) {
+            HeaderField f = staticTable[i];
+            Map<String, Integer> values = staticIndexes
+                    .computeIfAbsent(f.name, k -> new LinkedHashMap<>());
+            values.put(f.value, i);
+        }
+    }
+
+    private final Table dynamicTable = new Table(0);
+    private int maxSize;
+    private int size;
+
+    public HeaderTable(int maxSize) {
+        setMaxSize(maxSize);
+    }
+
+    //
+    // The method returns:
+    //
+    // * a positive integer i where i (i = [1..Integer.MAX_VALUE]) is an
+    // index of an entry with a header (n, v), where n.equals(name) &&
+    // v.equals(value)
+    //
+    // * a negative integer j where j (j = [-Integer.MAX_VALUE..-1]) is an
+    // index of an entry with a header (n, v), where n.equals(name)
+    //
+    // * 0 if there's no entry e such that e.getName().equals(name)
+    //
+    // The rationale behind this design is to allow to pack more useful data
+    // into a single invocation, facilitating a single pass where possible
+    // (the idea is the same as in java.util.Arrays.binarySearch(int[], int)).
+    //
+    public int indexOf(CharSequence name, CharSequence value) {
+        // Invoking toString() will possibly allocate Strings for the sake of
+        // the search, which doesn't feel right.
+        String n = name.toString();
+        String v = value.toString();
+
+        // 1. Try exact match in the static region
+        Map<String, Integer> values = staticIndexes.get(n);
+        if (values != null) {
+            Integer idx = values.get(v);
+            if (idx != null) {
+                return idx;
+            }
+        }
+        // 2. Try exact match in the dynamic region
+        int didx = dynamicTable.indexOf(n, v);
+        if (didx > 0) {
+            return STATIC_TABLE_LENGTH + didx;
+        } else if (didx < 0) {
+            if (values != null) {
+                // 3. Return name match from the static region
+                return -values.values().iterator().next(); // Iterator allocation
+            } else {
+                // 4. Return name match from the dynamic region
+                return -STATIC_TABLE_LENGTH + didx;
+            }
+        } else {
+            if (values != null) {
+                // 3. Return name match from the static region
+                return -values.values().iterator().next(); // Iterator allocation
+            } else {
+                return 0;
+            }
+        }
+    }
+
+    public int size() {
+        return size;
+    }
+
+    public int maxSize() {
+        return maxSize;
+    }
+
+    public int length() {
+        return STATIC_TABLE_LENGTH + dynamicTable.size();
+    }
+
+    HeaderField get(int index) {
+        checkIndex(index);
+        if (index <= STATIC_TABLE_LENGTH) {
+            return staticTable[index];
+        } else {
+            return dynamicTable.get(index - STATIC_TABLE_LENGTH);
+        }
+    }
+
+    void put(CharSequence name, CharSequence value) {
+        // Invoking toString() will possibly allocate Strings. But that's
+        // unavoidable at this stage. If a CharSequence is going to be stored in
+        // the table, it must not be mutable (e.g. for the sake of hashing).
+        put(new HeaderField(name.toString(), value.toString()));
+    }
+
+    private void put(HeaderField h) {
+        int entrySize = sizeOf(h);
+        while (entrySize > maxSize - size && size != 0) {
+            evictEntry();
+        }
+        if (entrySize > maxSize - size) {
+            return;
+        }
+        size += entrySize;
+        dynamicTable.add(h);
+    }
+
+    void setMaxSize(int maxSize) {
+        if (maxSize < 0) {
+            throw new IllegalArgumentException
+                    ("maxSize >= 0: maxSize=" + maxSize);
+        }
+        while (maxSize < size && size != 0) {
+            evictEntry();
+        }
+        this.maxSize = maxSize;
+        int upperBound = (maxSize / ENTRY_SIZE) + 1;
+        this.dynamicTable.setCapacity(upperBound);
+    }
+
+    HeaderField evictEntry() {
+        HeaderField f = dynamicTable.remove();
+        size -= sizeOf(f);
+        return f;
+    }
+
+    @Override
+    public String toString() {
+        double used = maxSize == 0 ? 0 : 100 * (((double) size) / maxSize);
+        return format("entries: %d; used %s/%s (%.1f%%)", dynamicTable.size(),
+                size, maxSize, used);
+    }
+
+    int checkIndex(int index) {
+        if (index < 1 || index > STATIC_TABLE_LENGTH + dynamicTable.size()) {
+            throw new IllegalArgumentException(
+                    format("1 <= index <= length(): index=%s, length()=%s",
+                            index, length()));
+        }
+        return index;
+    }
+
+    int sizeOf(HeaderField f) {
+        return f.name.length() + f.value.length() + ENTRY_SIZE;
+    }
+
+    //
+    // Diagnostic information in the form used in the RFC 7541
+    //
+    String getStateString() {
+        if (size == 0) {
+            return "empty.";
+        }
+
+        StringBuilder b = new StringBuilder();
+        for (int i = 1, size = dynamicTable.size(); i <= size; i++) {
+            HeaderField e = dynamicTable.get(i);
+            b.append(format("[%3d] (s = %3d) %s: %s\n", i,
+                    sizeOf(e), e.name, e.value));
+        }
+        b.append(format("      Table size:%4s", this.size));
+        return b.toString();
+    }
+
+    // Convert to a Value Object (JDK-8046159)?
+    static final class HeaderField {
+
+        final String name;
+        final String value;
+
+        public HeaderField(String name) {
+            this(name, "");
+        }
+
+        public HeaderField(String name, String value) {
+            this.name = name;
+            this.value = value;
+        }
+
+        @Override
+        public String toString() {
+            return value.isEmpty() ? name : name + ": " + value;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) {
+                return true;
+            }
+            if (o == null || getClass() != o.getClass()) {
+                return false;
+            }
+            HeaderField that = (HeaderField) o;
+            return name.equals(that.name) && value.equals(that.value);
+        }
+
+        @Override
+        public int hashCode() {
+            return 31 * (name.hashCode()) + value.hashCode();
+        }
+    }
+
+    //
+    // In order to be able to find an index of an entry with the given contents
+    // in the dynamic table an effective inverse mapping is needed. Here's a
+    // simple idea behind such a mapping.
+    //
+    // # The problem:
+    //
+    // We have a queue with an O(1) lookup by index:
+    //
+    //     get: index -> x
+    //
+    // What we also want is an O(1) reverse lookup:
+    //
+    //     indexOf: x -> index
+    //
+    // # Solution:
+    //
+    // Let's store an inverse mapping as a Map<X, Integer>. This have a problem
+    // that when a new element is added to the queue all indexes in the map
+    // becomes invalid. Namely, each i becomes shifted by 1 to the right:
+    //
+    //     i -> i + 1
+    //
+    // And the new element is assigned with an index of 1. This would seem to
+    // require a pass through the map incrementing all indexes (map values) by
+    // 1, which is O(n).
+    //
+    // The good news is we can do much better then this!
+    //
+    // Let's create a single field of type long, called 'counter'. Then each
+    // time a new element 'x' is added to the queue, a value of this field gets
+    // incremented. Then the resulting value of the 'counter_x' is then put as a
+    // value under key 'x' to the map:
+    //
+    //    map.put(x, counter_x)
+    //
+    // It gives us a map that maps an element to a value the counter had at the
+    // time the element had been added.
+    //
+    // In order to retrieve an index of any element 'x' in the queue (at any
+    // given time) we simply need to subtract the value (the snapshot of the
+    // counter at the time when the 'x' was added) from the current value of the
+    // counter. This operation basically answers the question:
+    //
+    //     How many elements ago 'x' was the tail of the queue?
+    //
+    // Which is the same as its index in the queue now. Given, of course, it's
+    // still in the queue.
+    //
+    // I'm pretty sure in a real life long overflow will never happen, so it's
+    // not too practical to add recalibrating code, but a pedantic person might
+    // want to do so:
+    //
+    //     if (counter == Long.MAX_VALUE) {
+    //         recalibrate();
+    //     }
+    //
+    // Where 'recalibrate()' goes through the table doing this:
+    //
+    //  value -= counter
+    //
+    // That's given, of course, the size of the table itself is less than
+    // Long.MAX_VALUE :-)
+    //
+    private static final class Table {
+
+        private final Map<String, Map<String, Long>> map;
+        private final CircularBuffer<HeaderField> buffer;
+        private long counter = 1;
+
+        Table(int capacity) {
+            buffer = new CircularBuffer<>(capacity);
+            map = new HashMap<>(capacity);
+        }
+
+        void add(HeaderField f) {
+            buffer.add(f);
+            Map<String, Long> values = map.computeIfAbsent(f.name, k -> new HashMap<>());
+            values.put(f.value, counter++);
+        }
+
+        HeaderField get(int index) {
+            return buffer.get(index - 1);
+        }
+
+        int indexOf(String name, String value) {
+            Map<String, Long> values = map.get(name);
+            if (values == null) {
+                return 0;
+            }
+            Long index = values.get(value);
+            if (index != null) {
+                return (int) (counter - index);
+            } else {
+                assert !values.isEmpty();
+                Long any = values.values().iterator().next(); // Iterator allocation
+                return -(int) (counter - any);
+            }
+        }
+
+        HeaderField remove() {
+            HeaderField f = buffer.remove();
+            Map<String, Long> values = map.get(f.name);
+            Long index = values.remove(f.value);
+            assert index != null;
+            if (values.isEmpty()) {
+                map.remove(f.name);
+            }
+            return f;
+        }
+
+        int size() {
+            return buffer.size;
+        }
+
+        public void setCapacity(int capacity) {
+            buffer.resize(capacity);
+        }
+    }
+
+    //                    head
+    //                    v
+    // [ ][ ][A][B][C][D][ ][ ][ ]
+    //        ^
+    //        tail
+    //
+    //       |<- size ->| (4)
+    // |<------ capacity ------->| (9)
+    //
+    static final class CircularBuffer<E> {
+
+        int tail, head, size, capacity;
+        Object[] elements;
+
+        CircularBuffer(int capacity) {
+            this.capacity = capacity;
+            elements = new Object[capacity];
+        }
+
+        void add(E elem) {
+            if (size == capacity) {
+                throw new IllegalStateException(
+                        format("No room for '%s': capacity=%s", elem, capacity));
+            }
+            elements[head] = elem;
+            head = (head + 1) % capacity;
+            size++;
+        }
+
+        @SuppressWarnings("unchecked")
+        E remove() {
+            if (size == 0) {
+                throw new NoSuchElementException("Empty");
+            }
+            E elem = (E) elements[tail];
+            elements[tail] = null;
+            tail = (tail + 1) % capacity;
+            size--;
+            return elem;
+        }
+
+        @SuppressWarnings("unchecked")
+        E get(int index) {
+            if (index < 0 || index >= size) {
+                throw new IndexOutOfBoundsException(
+                        format("0 <= index <= capacity: index=%s, capacity=%s",
+                                index, capacity));
+            }
+            int idx = (tail + (size - index - 1)) % capacity;
+            return (E) elements[idx];
+        }
+
+        public void resize(int newCapacity) {
+            if (newCapacity < size) {
+                throw new IllegalStateException(
+                        format("newCapacity >= size: newCapacity=%s, size=%s",
+                                newCapacity, size));
+            }
+
+            Object[] newElements = new Object[newCapacity];
+
+            if (tail < head || size == 0) {
+                System.arraycopy(elements, tail, newElements, 0, size);
+            } else {
+                System.arraycopy(elements, tail, newElements, 0, elements.length - tail);
+                System.arraycopy(elements, 0, newElements, elements.length - tail, head);
+            }
+
+            elements = newElements;
+            tail = 0;
+            head = size;
+            this.capacity = newCapacity;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/Huffman.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,676 @@
+/*
+ * 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
+ * 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 sun.net.httpclient.hpack;
+
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.nio.ByteBuffer;
+
+import static java.lang.String.format;
+
+/**
+ * Huffman coding table.
+ *
+ * <p> Instances of this class are safe for use by multiple threads.
+ *
+ * @since 9
+ */
+public final class Huffman {
+
+    // TODO: check if reset is done in both reader and writer
+
+    static final class Reader {
+
+        private Node curr; // position in the trie
+        private int len;   // length of the path from the root to 'curr'
+        private int p;     // byte probe
+
+        {
+            reset();
+        }
+
+        public void read(ByteBuffer source, Appendable destination,
+                         boolean isLast) {
+            read(source, destination, true, isLast);
+        }
+
+        // Takes 'isLast' rather than returns whether the reading is done or
+        // not, for more informative exceptions.
+        void read(ByteBuffer source, Appendable destination, boolean reportEOS,
+                  boolean isLast) {
+
+            Node c = curr;
+            int l = len;
+            /*
+               Since ByteBuffer is itself stateful, its position is
+               remembered here NOT as a part of Reader's state,
+               but to set it back in the case of a failure
+             */
+            int pos = source.position();
+
+            while (source.hasRemaining()) {
+                int d = source.get();
+                for (; p != 0; p >>= 1) {
+                    c = c.getChild(p & d);
+                    l++;
+                    if (c.isLeaf()) {
+                        if (reportEOS && c.isEOSPath) {
+                            throw new IllegalArgumentException("Encountered EOS");
+                        }
+                        try {
+                            destination.append(c.getChar());
+                        } catch (RuntimeException | Error e) {
+                            source.position(pos);
+                            throw e;
+                        } catch (IOException e) {
+                            source.position(pos);
+                            throw new UncheckedIOException(e);
+                        }
+                        c = INSTANCE.root;
+                        l = 0;
+                    }
+                    curr = c;
+                    len = l;
+                }
+                resetProbe();
+                pos++;
+            }
+            if (!isLast) {
+                return; // it's too early to jump to any conclusions, let's wait
+            }
+            if (c.isLeaf()) {
+                return; // it's perfectly ok, no extra padding bits
+            }
+            if (c.isEOSPath && len <= 7) {
+                return; // it's ok, some extra padding bits
+            }
+            if (c.isEOSPath) {
+                throw new IllegalArgumentException(
+                        "Padding is too long (len=" + len + ") " +
+                                "or unexpected end of data");
+            }
+            throw new IllegalArgumentException(
+                    "Not a EOS prefix padding or unexpected end of data");
+        }
+
+        public void reset() {
+            curr = INSTANCE.root;
+            len = 0;
+            resetProbe();
+        }
+
+        private void resetProbe() {
+            p = 0x80;
+        }
+    }
+
+    static final class Writer {
+
+        private int pos;       // position in 'source'
+        private int avail = 8; // number of least significant bits available in 'curr'
+        private int curr;      // next byte to put to the destination
+        private int rem;       // number of least significant bits in 'code' yet to be processed
+        private int code;      // current code being written
+
+        private CharSequence source;
+        private int end;
+
+        public Writer from(CharSequence input, int start, int end) {
+            if (start < 0 || end < 0 || end > input.length() || start > end) {
+                throw new IndexOutOfBoundsException(
+                        String.format("input.length()=%s, start=%s, end=%s",
+                                input.length(), start, end));
+            }
+            pos = start;
+            this.end = end;
+            this.source = input;
+            return this;
+        }
+
+        public boolean write(ByteBuffer destination) {
+            for (; pos < end; pos++) {
+                if (rem == 0) {
+                    Code desc = INSTANCE.codeOf(source.charAt(pos));
+                    rem = desc.length;
+                    code = desc.code;
+                }
+                while (rem > 0) {
+                    if (rem < avail) {
+                        curr |= (code << (avail - rem));
+                        avail -= rem;
+                        rem = 0;
+                    } else {
+                        int c = (curr | (code >>> (rem - avail)));
+                        if (destination.hasRemaining()) {
+                            destination.put((byte) c);
+                        } else {
+                            return false;
+                        }
+                        curr = c;
+                        code <<= (32 - rem + avail);  // throw written bits off the cliff (is this Sparta?)
+                        code >>>= (32 - rem + avail); // return to the position
+                        rem -= avail;
+                        curr = 0;
+                        avail = 8;
+                    }
+                }
+            }
+
+            if (avail < 8) { // have to pad
+                if (destination.hasRemaining()) {
+                    destination.put((byte) (curr | (INSTANCE.EOS.code >>> (INSTANCE.EOS.length - avail))));
+                    avail = 8;
+                } else {
+                    return false;
+                }
+            }
+
+            return true;
+        }
+
+        public Writer reset() {
+            source = null;
+            end = -1;
+            pos = -1;
+            avail = 8;
+            curr = 0;
+            code = 0;
+            return this;
+        }
+    }
+
+    /**
+     * Shared instance.
+     */
+    public static final Huffman INSTANCE = new Huffman();
+
+    private final Code EOS = new Code(0x3fffffff, 30);
+    private final Code[] codes = new Code[257];
+    private final Node root = new Node() {
+        @Override
+        public String toString() { return "root"; }
+    };
+
+    // TODO: consider builder and immutable trie
+    private Huffman() {
+        // @formatter:off
+        addChar(0,   0x1ff8,     13);
+        addChar(1,   0x7fffd8,   23);
+        addChar(2,   0xfffffe2,  28);
+        addChar(3,   0xfffffe3,  28);
+        addChar(4,   0xfffffe4,  28);
+        addChar(5,   0xfffffe5,  28);
+        addChar(6,   0xfffffe6,  28);
+        addChar(7,   0xfffffe7,  28);
+        addChar(8,   0xfffffe8,  28);
+        addChar(9,   0xffffea,   24);
+        addChar(10,  0x3ffffffc, 30);
+        addChar(11,  0xfffffe9,  28);
+        addChar(12,  0xfffffea,  28);
+        addChar(13,  0x3ffffffd, 30);
+        addChar(14,  0xfffffeb,  28);
+        addChar(15,  0xfffffec,  28);
+        addChar(16,  0xfffffed,  28);
+        addChar(17,  0xfffffee,  28);
+        addChar(18,  0xfffffef,  28);
+        addChar(19,  0xffffff0,  28);
+        addChar(20,  0xffffff1,  28);
+        addChar(21,  0xffffff2,  28);
+        addChar(22,  0x3ffffffe, 30);
+        addChar(23,  0xffffff3,  28);
+        addChar(24,  0xffffff4,  28);
+        addChar(25,  0xffffff5,  28);
+        addChar(26,  0xffffff6,  28);
+        addChar(27,  0xffffff7,  28);
+        addChar(28,  0xffffff8,  28);
+        addChar(29,  0xffffff9,  28);
+        addChar(30,  0xffffffa,  28);
+        addChar(31,  0xffffffb,  28);
+        addChar(32,  0x14,        6);
+        addChar(33,  0x3f8,      10);
+        addChar(34,  0x3f9,      10);
+        addChar(35,  0xffa,      12);
+        addChar(36,  0x1ff9,     13);
+        addChar(37,  0x15,        6);
+        addChar(38,  0xf8,        8);
+        addChar(39,  0x7fa,      11);
+        addChar(40,  0x3fa,      10);
+        addChar(41,  0x3fb,      10);
+        addChar(42,  0xf9,        8);
+        addChar(43,  0x7fb,      11);
+        addChar(44,  0xfa,        8);
+        addChar(45,  0x16,        6);
+        addChar(46,  0x17,        6);
+        addChar(47,  0x18,        6);
+        addChar(48,  0x0,         5);
+        addChar(49,  0x1,         5);
+        addChar(50,  0x2,         5);
+        addChar(51,  0x19,        6);
+        addChar(52,  0x1a,        6);
+        addChar(53,  0x1b,        6);
+        addChar(54,  0x1c,        6);
+        addChar(55,  0x1d,        6);
+        addChar(56,  0x1e,        6);
+        addChar(57,  0x1f,        6);
+        addChar(58,  0x5c,        7);
+        addChar(59,  0xfb,        8);
+        addChar(60,  0x7ffc,     15);
+        addChar(61,  0x20,        6);
+        addChar(62,  0xffb,      12);
+        addChar(63,  0x3fc,      10);
+        addChar(64,  0x1ffa,     13);
+        addChar(65,  0x21,        6);
+        addChar(66,  0x5d,        7);
+        addChar(67,  0x5e,        7);
+        addChar(68,  0x5f,        7);
+        addChar(69,  0x60,        7);
+        addChar(70,  0x61,        7);
+        addChar(71,  0x62,        7);
+        addChar(72,  0x63,        7);
+        addChar(73,  0x64,        7);
+        addChar(74,  0x65,        7);
+        addChar(75,  0x66,        7);
+        addChar(76,  0x67,        7);
+        addChar(77,  0x68,        7);
+        addChar(78,  0x69,        7);
+        addChar(79,  0x6a,        7);
+        addChar(80,  0x6b,        7);
+        addChar(81,  0x6c,        7);
+        addChar(82,  0x6d,        7);
+        addChar(83,  0x6e,        7);
+        addChar(84,  0x6f,        7);
+        addChar(85,  0x70,        7);
+        addChar(86,  0x71,        7);
+        addChar(87,  0x72,        7);
+        addChar(88,  0xfc,        8);
+        addChar(89,  0x73,        7);
+        addChar(90,  0xfd,        8);
+        addChar(91,  0x1ffb,     13);
+        addChar(92,  0x7fff0,    19);
+        addChar(93,  0x1ffc,     13);
+        addChar(94,  0x3ffc,     14);
+        addChar(95,  0x22,        6);
+        addChar(96,  0x7ffd,     15);
+        addChar(97,  0x3,         5);
+        addChar(98,  0x23,        6);
+        addChar(99,  0x4,         5);
+        addChar(100, 0x24,        6);
+        addChar(101, 0x5,         5);
+        addChar(102, 0x25,        6);
+        addChar(103, 0x26,        6);
+        addChar(104, 0x27,        6);
+        addChar(105, 0x6,         5);
+        addChar(106, 0x74,        7);
+        addChar(107, 0x75,        7);
+        addChar(108, 0x28,        6);
+        addChar(109, 0x29,        6);
+        addChar(110, 0x2a,        6);
+        addChar(111, 0x7,         5);
+        addChar(112, 0x2b,        6);
+        addChar(113, 0x76,        7);
+        addChar(114, 0x2c,        6);
+        addChar(115, 0x8,         5);
+        addChar(116, 0x9,         5);
+        addChar(117, 0x2d,        6);
+        addChar(118, 0x77,        7);
+        addChar(119, 0x78,        7);
+        addChar(120, 0x79,        7);
+        addChar(121, 0x7a,        7);
+        addChar(122, 0x7b,        7);
+        addChar(123, 0x7ffe,     15);
+        addChar(124, 0x7fc,      11);
+        addChar(125, 0x3ffd,     14);
+        addChar(126, 0x1ffd,     13);
+        addChar(127, 0xffffffc,  28);
+        addChar(128, 0xfffe6,    20);
+        addChar(129, 0x3fffd2,   22);
+        addChar(130, 0xfffe7,    20);
+        addChar(131, 0xfffe8,    20);
+        addChar(132, 0x3fffd3,   22);
+        addChar(133, 0x3fffd4,   22);
+        addChar(134, 0x3fffd5,   22);
+        addChar(135, 0x7fffd9,   23);
+        addChar(136, 0x3fffd6,   22);
+        addChar(137, 0x7fffda,   23);
+        addChar(138, 0x7fffdb,   23);
+        addChar(139, 0x7fffdc,   23);
+        addChar(140, 0x7fffdd,   23);
+        addChar(141, 0x7fffde,   23);
+        addChar(142, 0xffffeb,   24);
+        addChar(143, 0x7fffdf,   23);
+        addChar(144, 0xffffec,   24);
+        addChar(145, 0xffffed,   24);
+        addChar(146, 0x3fffd7,   22);
+        addChar(147, 0x7fffe0,   23);
+        addChar(148, 0xffffee,   24);
+        addChar(149, 0x7fffe1,   23);
+        addChar(150, 0x7fffe2,   23);
+        addChar(151, 0x7fffe3,   23);
+        addChar(152, 0x7fffe4,   23);
+        addChar(153, 0x1fffdc,   21);
+        addChar(154, 0x3fffd8,   22);
+        addChar(155, 0x7fffe5,   23);
+        addChar(156, 0x3fffd9,   22);
+        addChar(157, 0x7fffe6,   23);
+        addChar(158, 0x7fffe7,   23);
+        addChar(159, 0xffffef,   24);
+        addChar(160, 0x3fffda,   22);
+        addChar(161, 0x1fffdd,   21);
+        addChar(162, 0xfffe9,    20);
+        addChar(163, 0x3fffdb,   22);
+        addChar(164, 0x3fffdc,   22);
+        addChar(165, 0x7fffe8,   23);
+        addChar(166, 0x7fffe9,   23);
+        addChar(167, 0x1fffde,   21);
+        addChar(168, 0x7fffea,   23);
+        addChar(169, 0x3fffdd,   22);
+        addChar(170, 0x3fffde,   22);
+        addChar(171, 0xfffff0,   24);
+        addChar(172, 0x1fffdf,   21);
+        addChar(173, 0x3fffdf,   22);
+        addChar(174, 0x7fffeb,   23);
+        addChar(175, 0x7fffec,   23);
+        addChar(176, 0x1fffe0,   21);
+        addChar(177, 0x1fffe1,   21);
+        addChar(178, 0x3fffe0,   22);
+        addChar(179, 0x1fffe2,   21);
+        addChar(180, 0x7fffed,   23);
+        addChar(181, 0x3fffe1,   22);
+        addChar(182, 0x7fffee,   23);
+        addChar(183, 0x7fffef,   23);
+        addChar(184, 0xfffea,    20);
+        addChar(185, 0x3fffe2,   22);
+        addChar(186, 0x3fffe3,   22);
+        addChar(187, 0x3fffe4,   22);
+        addChar(188, 0x7ffff0,   23);
+        addChar(189, 0x3fffe5,   22);
+        addChar(190, 0x3fffe6,   22);
+        addChar(191, 0x7ffff1,   23);
+        addChar(192, 0x3ffffe0,  26);
+        addChar(193, 0x3ffffe1,  26);
+        addChar(194, 0xfffeb,    20);
+        addChar(195, 0x7fff1,    19);
+        addChar(196, 0x3fffe7,   22);
+        addChar(197, 0x7ffff2,   23);
+        addChar(198, 0x3fffe8,   22);
+        addChar(199, 0x1ffffec,  25);
+        addChar(200, 0x3ffffe2,  26);
+        addChar(201, 0x3ffffe3,  26);
+        addChar(202, 0x3ffffe4,  26);
+        addChar(203, 0x7ffffde,  27);
+        addChar(204, 0x7ffffdf,  27);
+        addChar(205, 0x3ffffe5,  26);
+        addChar(206, 0xfffff1,   24);
+        addChar(207, 0x1ffffed,  25);
+        addChar(208, 0x7fff2,    19);
+        addChar(209, 0x1fffe3,   21);
+        addChar(210, 0x3ffffe6,  26);
+        addChar(211, 0x7ffffe0,  27);
+        addChar(212, 0x7ffffe1,  27);
+        addChar(213, 0x3ffffe7,  26);
+        addChar(214, 0x7ffffe2,  27);
+        addChar(215, 0xfffff2,   24);
+        addChar(216, 0x1fffe4,   21);
+        addChar(217, 0x1fffe5,   21);
+        addChar(218, 0x3ffffe8,  26);
+        addChar(219, 0x3ffffe9,  26);
+        addChar(220, 0xffffffd,  28);
+        addChar(221, 0x7ffffe3,  27);
+        addChar(222, 0x7ffffe4,  27);
+        addChar(223, 0x7ffffe5,  27);
+        addChar(224, 0xfffec,    20);
+        addChar(225, 0xfffff3,   24);
+        addChar(226, 0xfffed,    20);
+        addChar(227, 0x1fffe6,   21);
+        addChar(228, 0x3fffe9,   22);
+        addChar(229, 0x1fffe7,   21);
+        addChar(230, 0x1fffe8,   21);
+        addChar(231, 0x7ffff3,   23);
+        addChar(232, 0x3fffea,   22);
+        addChar(233, 0x3fffeb,   22);
+        addChar(234, 0x1ffffee,  25);
+        addChar(235, 0x1ffffef,  25);
+        addChar(236, 0xfffff4,   24);
+        addChar(237, 0xfffff5,   24);
+        addChar(238, 0x3ffffea,  26);
+        addChar(239, 0x7ffff4,   23);
+        addChar(240, 0x3ffffeb,  26);
+        addChar(241, 0x7ffffe6,  27);
+        addChar(242, 0x3ffffec,  26);
+        addChar(243, 0x3ffffed,  26);
+        addChar(244, 0x7ffffe7,  27);
+        addChar(245, 0x7ffffe8,  27);
+        addChar(246, 0x7ffffe9,  27);
+        addChar(247, 0x7ffffea,  27);
+        addChar(248, 0x7ffffeb,  27);
+        addChar(249, 0xffffffe,  28);
+        addChar(250, 0x7ffffec,  27);
+        addChar(251, 0x7ffffed,  27);
+        addChar(252, 0x7ffffee,  27);
+        addChar(253, 0x7ffffef,  27);
+        addChar(254, 0x7fffff0,  27);
+        addChar(255, 0x3ffffee,  26);
+        addEOS (256, EOS.code,   EOS.length);
+        // @formatter:on
+    }
+
+
+    /**
+     * Calculates the number of bytes required to represent the given {@code
+     * CharSequence} with the Huffman coding.
+     *
+     * @param value
+     *         characters
+     *
+     * @return number of bytes
+     *
+     * @throws NullPointerException
+     *         if the value is null
+     */
+    public int lengthOf(CharSequence value) {
+        return lengthOf(value, 0, value.length());
+    }
+
+    /**
+     * Calculates the number of bytes required to represent a subsequence of the
+     * given {@code CharSequence} with the Huffman coding.
+     *
+     * @param value
+     *         characters
+     * @param start
+     *         the start index, inclusive
+     * @param end
+     *         the end index, exclusive
+     *
+     * @return number of bytes
+     *
+     * @throws NullPointerException
+     *         if the value is null
+     * @throws IndexOutOfBoundsException
+     *         if any invocation of {@code value.charAt(i)}, where {@code start
+     *         <= i < end} would throw an IndexOutOfBoundsException
+     */
+    public int lengthOf(CharSequence value, int start, int end) {
+        int len = 0;
+        for (int i = start; i < end; i++) {
+            char c = value.charAt(i);
+            len += INSTANCE.codeOf(c).length;
+        }
+        // Integer division with ceiling, assumption:
+        assert (len / 8 + (len % 8 != 0 ? 1 : 0)) == (len + 7) / 8 : len;
+        return (len + 7) / 8;
+    }
+
+    private void addChar(int c, int code, int bitLength) {
+        addLeaf(c, code, bitLength, false);
+        codes[c] = new Code(code, bitLength);
+    }
+
+    private void addEOS(int c, int code, int bitLength) {
+        addLeaf(c, code, bitLength, true);
+        codes[c] = new Code(code, bitLength);
+    }
+
+    private void addLeaf(int c, int code, int bitLength, boolean isEOS) {
+        if (bitLength < 1) {
+            throw new IllegalArgumentException("bitLength < 1");
+        }
+        Node curr = root;
+        for (int p = 1 << bitLength - 1; p != 0 && !curr.isLeaf(); p = p >> 1) {
+            curr.isEOSPath |= isEOS; // If it's already true, it can't become false
+            curr = curr.addChildIfAbsent(p & code);
+        }
+        curr.isEOSPath |= isEOS; // The last one needs to have this property as well
+        if (curr.isLeaf()) {
+            throw new IllegalStateException("Specified code is already taken");
+        }
+        curr.setChar((char) c);
+    }
+
+    private Code codeOf(char c) {
+        if (c > 255) {
+            throw new IllegalArgumentException("char=" + ((int) c));
+        }
+        return codes[c];
+    }
+
+    //
+    // For debugging/testing purposes
+    //
+    Node getRoot() {
+        return root;
+    }
+
+    //
+    // Guarantees:
+    //
+    //  if (isLeaf() == true) => getChar() is a legal call
+    //  if (isLeaf() == false) => getChild(i) is a legal call (though it can
+    //                                                           return null)
+    //
+    static class Node {
+
+        Node left;
+        Node right;
+        boolean isEOSPath;
+
+        boolean charIsSet;
+        char c;
+
+        Node getChild(int selector) {
+            if (isLeaf()) {
+                throw new IllegalStateException("This is a leaf node");
+            }
+            Node result = selector == 0 ? left : right;
+            if (result == null) {
+                throw new IllegalStateException(format(
+                        "Node doesn't have a child (selector=%s)", selector));
+            }
+            return result;
+        }
+
+        boolean isLeaf() {
+            return charIsSet;
+        }
+
+        char getChar() {
+            if (!isLeaf()) {
+                throw new IllegalStateException("This node is not a leaf node");
+            }
+            return c;
+        }
+
+        void setChar(char c) {
+            if (charIsSet) {
+                throw new IllegalStateException(
+                        "This node has been taken already");
+            }
+            if (left != null || right != null) {
+                throw new IllegalStateException("The node cannot be made "
+                        + "a leaf as it's already has a child");
+            }
+            this.c = c;
+            charIsSet = true;
+        }
+
+        Node addChildIfAbsent(int i) {
+            if (charIsSet) {
+                throw new IllegalStateException("The node cannot have a child "
+                        + "as it's already a leaf node");
+            }
+            Node child;
+            if (i == 0) {
+                if ((child = left) == null) {
+                    child = left = new Node();
+                }
+            } else {
+                if ((child = right) == null) {
+                    child = right = new Node();
+                }
+            }
+            return child;
+        }
+
+        @Override
+        public String toString() {
+            if (isLeaf()) {
+                if (isEOSPath) {
+                    return "EOS";
+                } else {
+                    return format("char: (%3s) '%s'", (int) c, c);
+                }
+            }
+            return "/\\";
+        }
+    }
+
+    // TODO: value-based class?
+    // FIXME: can we re-use Node instead of this class?
+    private static final class Code {
+
+        final int code;
+        final int length;
+
+        private Code(int code, int length) {
+            this.code = code;
+            this.length = length;
+        }
+
+        public int getCode() {
+            return code;
+        }
+
+        public int getLength() {
+            return length;
+        }
+
+        @Override
+        public String toString() {
+            long p = 1 << length;
+            return Long.toBinaryString(code + p).substring(1)
+                    + ", length=" + length;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/ISO_8859_1.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,103 @@
+/*
+ * 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
+ * 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 sun.net.httpclient.hpack;
+
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.nio.ByteBuffer;
+
+//
+// Custom implementation of ISO/IEC 8859-1:1998
+//
+// The rationale behind this is not to deal with CharsetEncoder/CharsetDecoder,
+// basically because it would require wrapping every single CharSequence into a
+// CharBuffer and then copying it back.
+//
+// But why not to give a CharBuffer instead of Appendable? Because I can choose
+// an Appendable (e.g. StringBuilder) that adjusts its length when needed and
+// therefore not to deal with pre-sized CharBuffers or copying.
+//
+// The encoding is simple and well known: 1 byte <-> 1 char
+//
+final class ISO_8859_1 {
+
+    private ISO_8859_1() { }
+
+    public static final class Reader {
+
+        public void read(ByteBuffer source, Appendable destination) {
+            for (int i = 0, len = source.remaining(); i < len; i++) {
+                char c = (char) (source.get() & 0xff);
+                try {
+                    destination.append(c);
+                } catch (IOException e) {
+                    throw new UncheckedIOException
+                            ("Error appending to the destination", e);
+                }
+            }
+        }
+
+        public Reader reset() {
+            return this;
+        }
+    }
+
+    public static final class Writer {
+
+        private CharSequence source;
+        private int pos;
+        private int end;
+
+        public Writer configure(CharSequence source, int start, int end) {
+            this.source = source;
+            this.pos = start;
+            this.end = end;
+            return this;
+        }
+
+        public boolean write(ByteBuffer destination) {
+            for (; pos < end; pos++) {
+                char c = source.charAt(pos);
+                if (c > '\u00FF') {
+                    throw new IllegalArgumentException(
+                            "Illegal ISO-8859-1 char: " + (int) c);
+                }
+                if (destination.hasRemaining()) {
+                    destination.put((byte) c);
+                } else {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        public Writer reset() {
+            source = null;
+            pos = -1;
+            end = -1;
+            return this;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/IndexNameValueWriter.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,101 @@
+/*
+ * 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
+ * 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 sun.net.httpclient.hpack;
+
+import java.nio.ByteBuffer;
+
+abstract class IndexNameValueWriter implements BinaryRepresentationWriter {
+
+    private final int pattern;
+    private final int prefix;
+    private final IntegerWriter intWriter = new IntegerWriter();
+    private final StringWriter nameWriter = new StringWriter();
+    private final StringWriter valueWriter = new StringWriter();
+
+    protected boolean indexedRepresentation;
+
+    private static final int NEW               = 0;
+    private static final int NAME_PART_WRITTEN = 1;
+    private static final int VALUE_WRITTEN     = 2;
+
+    private int state = NEW;
+
+    protected IndexNameValueWriter(int pattern, int prefix) {
+        this.pattern = pattern;
+        this.prefix = prefix;
+    }
+
+    IndexNameValueWriter index(int index) {
+        indexedRepresentation = true;
+        intWriter.configure(index, prefix, pattern);
+        return this;
+    }
+
+    IndexNameValueWriter name(CharSequence name, boolean useHuffman) {
+        indexedRepresentation = false;
+        intWriter.configure(0, prefix, pattern);
+        nameWriter.configure(name, useHuffman);
+        return this;
+    }
+
+    IndexNameValueWriter value(CharSequence value, boolean useHuffman) {
+        valueWriter.configure(value, useHuffman);
+        return this;
+    }
+
+    @Override
+    public boolean write(HeaderTable table, ByteBuffer destination) {
+        if (state < NAME_PART_WRITTEN) {
+            if (indexedRepresentation) {
+                if (!intWriter.write(destination)) {
+                    return false;
+                }
+            } else {
+                if (!intWriter.write(destination) || !nameWriter.write(destination)) {
+                    return false;
+                }
+            }
+            state = NAME_PART_WRITTEN;
+        }
+        if (state < VALUE_WRITTEN) {
+            if (!valueWriter.write(destination)) {
+                return false;
+            }
+            state = VALUE_WRITTEN;
+        }
+        return state == VALUE_WRITTEN;
+    }
+
+    @Override
+    public IndexNameValueWriter reset() {
+        intWriter.reset();
+        if (!indexedRepresentation) {
+            nameWriter.reset();
+        }
+        valueWriter.reset();
+        state = NEW;
+        return this;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/IndexedWriter.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,50 @@
+/*
+ * 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
+ * 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 sun.net.httpclient.hpack;
+
+import java.nio.ByteBuffer;
+
+final class IndexedWriter implements BinaryRepresentationWriter {
+
+    private final IntegerWriter intWriter = new IntegerWriter();
+
+    IndexedWriter() { }
+
+    IndexedWriter index(int index) {
+        intWriter.configure(index, 7, 0b1000_0000);
+        return this;
+    }
+
+    @Override
+    public boolean write(HeaderTable table, ByteBuffer destination) {
+        return intWriter.write(destination);
+    }
+
+    @Override
+    public BinaryRepresentationWriter reset() {
+        intWriter.reset();
+        return this;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/IntegerReader.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,142 @@
+/*
+ * 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
+ * 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 sun.net.httpclient.hpack;
+
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+
+import static java.lang.String.format;
+
+final class IntegerReader {
+
+    private static final int NEW             = 0;
+    private static final int CONFIGURED      = 1;
+    private static final int FIRST_BYTE_READ = 2;
+    private static final int DONE            = 4;
+
+    private int state = NEW;
+
+    private int N;
+    private int maxValue;
+    private int value;
+    private long r;
+    private long b = 1;
+
+    public IntegerReader configure(int N) {
+        return configure(N, Integer.MAX_VALUE);
+    }
+
+    //
+    // Why is it important to configure 'maxValue' here. After all we can wait
+    // for the integer to be fully read and then check it. Can't we?
+    //
+    // Two reasons.
+    //
+    // 1. Value wraps around long won't be unnoticed.
+    // 2. It can spit out an exception as soon as it becomes clear there's
+    // an overflow. Therefore, no need to wait for the value to be fully read.
+    //
+    public IntegerReader configure(int N, int maxValue) {
+        if (state != NEW) {
+            throw new IllegalStateException("Already configured");
+        }
+        checkPrefix(N);
+        if (maxValue < 0) {
+            throw new IllegalArgumentException(
+                    "maxValue >= 0: maxValue=" + maxValue);
+        }
+        this.maxValue = maxValue;
+        this.N = N;
+        state = CONFIGURED;
+        return this;
+    }
+
+    public boolean read(ByteBuffer input) {
+        if (state == NEW) {
+            throw new IllegalStateException("Configure first");
+        }
+        if (state == DONE) {
+            return true;
+        }
+        if (!input.hasRemaining()) {
+            return false;
+        }
+        if (state == CONFIGURED) {
+            int max = (2 << (N - 1)) - 1;
+            int n = input.get() & max;
+            if (n != max) {
+                value = n;
+                state = DONE;
+                return true;
+            } else {
+                r = max;
+            }
+            state = FIRST_BYTE_READ;
+        }
+        if (state == FIRST_BYTE_READ) {
+            // variable-length quantity (VLQ)
+            byte i;
+            do {
+                if (!input.hasRemaining()) {
+                    return false;
+                }
+                i = input.get();
+                long increment = b * (i & 127);
+                if (r + increment > maxValue) {
+                    throw new IllegalArgumentException(format(
+                            "Integer overflow: maxValue=%,d, value=%,d",
+                            maxValue, r + increment));
+                }
+                r += increment;
+                b *= 128;
+            } while ((128 & i) == 128);
+
+            value = (int) r;
+            state = DONE;
+            return true;
+        }
+        throw new InternalError(Arrays.toString(
+                new Object[]{state, N, maxValue, value, r, b}));
+    }
+
+    public int get() throws IllegalStateException {
+        if (state != DONE) {
+            throw new IllegalStateException("Has not been fully read yet");
+        }
+        return value;
+    }
+
+    private static void checkPrefix(int N) {
+        if (N < 1 || N > 8) {
+            throw new IllegalArgumentException("1 <= N <= 8: N= " + N);
+        }
+    }
+
+    public IntegerReader reset() {
+        b = 1;
+        state = NEW;
+        return this;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/IntegerWriter.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,117 @@
+/*
+ * 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
+ * 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 sun.net.httpclient.hpack;
+
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+
+final class IntegerWriter {
+
+    private static final int NEW                = 0;
+    private static final int CONFIGURED         = 1;
+    private static final int FIRST_BYTE_WRITTEN = 2;
+    private static final int DONE               = 4;
+
+    private int state = NEW;
+
+    private int payload;
+    private int N;
+    private int value;
+
+    //
+    //      0   1   2   3   4   5   6   7
+    //    +---+---+---+---+---+---+---+---+
+    //    |   |   |   |   |   |   |   |   |
+    //    +---+---+---+-------------------+
+    //    |<--------->|<----------------->|
+    //       payload           N=5
+    //
+    // payload is the contents of the left-hand side part of the octet;
+    //         it is truncated to fit into 8-N bits, where 1 <= N <= 8;
+    //
+    public IntegerWriter configure(int value, int N, int payload) {
+        if (state != NEW) {
+            throw new IllegalStateException("Already configured");
+        }
+        if (value < 0) {
+            throw new IllegalArgumentException("value >= 0: value=" + value);
+        }
+        checkPrefix(N);
+        this.value = value;
+        this.N = N;
+        this.payload = payload & 0xFF & (0xFFFFFFFF << N);
+        state = CONFIGURED;
+        return this;
+    }
+
+    public boolean write(ByteBuffer output) {
+        if (state == NEW) {
+            throw new IllegalStateException("Configure first");
+        }
+        if (state == DONE) {
+            return true;
+        }
+
+        if (!output.hasRemaining()) {
+            return false;
+        }
+        if (state == CONFIGURED) {
+            int max = (2 << (N - 1)) - 1;
+            if (value < max) {
+                output.put((byte) (payload | value));
+                state = DONE;
+                return true;
+            }
+            output.put((byte) (payload | max));
+            value -= max;
+            state = FIRST_BYTE_WRITTEN;
+        }
+        if (state == FIRST_BYTE_WRITTEN) {
+            while (value >= 128 && output.hasRemaining()) {
+                output.put((byte) (value % 128 + 128));
+                value /= 128;
+            }
+            if (!output.hasRemaining()) {
+                return false;
+            }
+            output.put((byte) value);
+            state = DONE;
+            return true;
+        }
+        throw new InternalError(Arrays.toString(
+                new Object[]{state, payload, N, value}));
+    }
+
+    private static void checkPrefix(int N) {
+        if (N < 1 || N > 8) {
+            throw new IllegalArgumentException("1 <= N <= 8: N= " + N);
+        }
+    }
+
+    public IntegerWriter reset() {
+        state = NEW;
+        return this;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/LiteralNeverIndexedWriter.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.net.httpclient.hpack;
+
+final class LiteralNeverIndexedWriter extends IndexNameValueWriter {
+
+    LiteralNeverIndexedWriter() {
+        super(0b0001_0000, 4);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/LiteralWithIndexingWriter.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.net.httpclient.hpack;
+
+import java.nio.ByteBuffer;
+
+final class LiteralWithIndexingWriter extends IndexNameValueWriter {
+
+    private boolean tableUpdated;
+
+    private CharSequence name;
+    private CharSequence value;
+    private int index;
+
+    LiteralWithIndexingWriter() {
+        super(0b0100_0000, 6);
+    }
+
+    @Override
+    LiteralWithIndexingWriter index(int index) {
+        super.index(index);
+        this.index = index;
+        return this;
+    }
+
+    @Override
+    LiteralWithIndexingWriter name(CharSequence name, boolean useHuffman) {
+        super.name(name, useHuffman);
+        this.name = name;
+        return this;
+    }
+
+    @Override
+    LiteralWithIndexingWriter value(CharSequence value, boolean useHuffman) {
+        super.value(value, useHuffman);
+        this.value = value;
+        return this;
+    }
+
+    @Override
+    public boolean write(HeaderTable table, ByteBuffer destination) {
+        if (!tableUpdated) {
+            CharSequence n;
+            if (indexedRepresentation) {
+                n = table.get(index).name;
+            } else {
+                n = name;
+            }
+            table.put(n, value);
+            tableUpdated = true;
+        }
+        return super.write(table, destination);
+    }
+
+    @Override
+    public IndexNameValueWriter reset() {
+        tableUpdated = false;
+        name = null;
+        value = null;
+        index = -1;
+        return super.reset();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/LiteralWriter.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.net.httpclient.hpack;
+
+final class LiteralWriter extends IndexNameValueWriter {
+
+    LiteralWriter() {
+        super(0b0000_0000, 4);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/SizeUpdateWriter.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,59 @@
+/*
+ * 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
+ * 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 sun.net.httpclient.hpack;
+
+import java.nio.ByteBuffer;
+
+final class SizeUpdateWriter implements BinaryRepresentationWriter {
+
+    private final IntegerWriter intWriter = new IntegerWriter();
+    private int maxSize;
+    private boolean tableUpdated;
+
+    SizeUpdateWriter() { }
+
+    SizeUpdateWriter maxHeaderTableSize(int size) {
+        intWriter.configure(size, 5, 0b0010_0000);
+        this.maxSize = size;
+        return this;
+    }
+
+    @Override
+    public boolean write(HeaderTable table, ByteBuffer destination) {
+        if (!tableUpdated) {
+            table.setMaxSize(maxSize);
+            tableUpdated = true;
+        }
+        return intWriter.write(destination);
+    }
+
+    @Override
+    public BinaryRepresentationWriter reset() {
+        intWriter.reset();
+        maxSize = -1;
+        tableUpdated = false;
+        return this;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/StringReader.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,111 @@
+/*
+ * 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
+ * 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 sun.net.httpclient.hpack;
+
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+
+//
+//          0   1   2   3   4   5   6   7
+//        +---+---+---+---+---+---+---+---+
+//        | H |    String Length (7+)     |
+//        +---+---------------------------+
+//        |  String Data (Length octets)  |
+//        +-------------------------------+
+//
+final class StringReader {
+
+    private static final int NEW             = 0;
+    private static final int FIRST_BYTE_READ = 1;
+    private static final int LENGTH_READ     = 2;
+    private static final int DONE            = 4;
+
+    private final IntegerReader intReader = new IntegerReader();
+    private final Huffman.Reader huffmanReader = new Huffman.Reader();
+    private final ISO_8859_1.Reader plainReader = new ISO_8859_1.Reader();
+
+    private int state = NEW;
+
+    private boolean huffman;
+    private int remainingLength;
+
+    boolean read(ByteBuffer input, Appendable output) {
+        if (state == DONE) {
+            return true;
+        }
+        if (!input.hasRemaining()) {
+            return false;
+        }
+        if (state == NEW) {
+            int p = input.position();
+            huffman = (input.get(p) & 0b10000000) != 0;
+            state = FIRST_BYTE_READ;
+            intReader.configure(7);
+        }
+        if (state == FIRST_BYTE_READ) {
+            boolean lengthRead = intReader.read(input);
+            if (!lengthRead) {
+                return false;
+            }
+            remainingLength = intReader.get();
+            state = LENGTH_READ;
+        }
+        if (state == LENGTH_READ) {
+            boolean isLast = input.remaining() >= remainingLength;
+            int oldLimit = input.limit();
+            if (isLast) {
+                input.limit(input.position() + remainingLength);
+            }
+            if (huffman) {
+                huffmanReader.read(input, output, isLast);
+            } else {
+                plainReader.read(input, output);
+            }
+            if (isLast) {
+                input.limit(oldLimit);
+            }
+            return isLast;
+        }
+        throw new InternalError(Arrays.toString(
+                new Object[]{state, huffman, remainingLength}));
+    }
+
+    boolean isHuffmanEncoded() {
+        if (state < FIRST_BYTE_READ) {
+            throw new IllegalStateException("Has not been fully read yet");
+        }
+        return huffman;
+    }
+
+    void reset() {
+        if (huffman) {
+            huffmanReader.reset();
+        } else {
+            plainReader.reset();
+        }
+        intReader.reset();
+        state = NEW;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/StringWriter.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,126 @@
+/*
+ * 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
+ * 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 sun.net.httpclient.hpack;
+
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+
+//
+//          0   1   2   3   4   5   6   7
+//        +---+---+---+---+---+---+---+---+
+//        | H |    String Length (7+)     |
+//        +---+---------------------------+
+//        |  String Data (Length octets)  |
+//        +-------------------------------+
+//
+// StringWriter does not require a notion of endOfInput (isLast) in 'write'
+// methods due to the nature of string representation in HPACK. Namely, the
+// length of the string is put before string's contents. Therefore the length is
+// always known beforehand.
+//
+// Expected use:
+//
+//     configure write* (reset configure write*)*
+//
+final class StringWriter {
+
+    private static final int NEW            = 0;
+    private static final int CONFIGURED     = 1;
+    private static final int LENGTH_WRITTEN = 2;
+    private static final int DONE           = 4;
+
+    private final IntegerWriter intWriter = new IntegerWriter();
+    private final Huffman.Writer huffmanWriter = new Huffman.Writer();
+    private final ISO_8859_1.Writer plainWriter = new ISO_8859_1.Writer();
+
+    private int state = NEW;
+    private boolean huffman;
+
+    StringWriter configure(CharSequence input, boolean huffman) {
+        return configure(input, 0, input.length(), huffman);
+    }
+
+    StringWriter configure(CharSequence input, int start, int end,
+                           boolean huffman) {
+        if (start < 0 || end < 0 || end > input.length() || start > end) {
+            throw new IndexOutOfBoundsException(
+                    String.format("input.length()=%s, start=%s, end=%s",
+                            input.length(), start, end));
+        }
+        if (!huffman) {
+            plainWriter.configure(input, start, end);
+            intWriter.configure(end - start, 7, 0b0000_0000);
+        } else {
+            huffmanWriter.from(input, start, end);
+            intWriter.configure(Huffman.INSTANCE.lengthOf(input, start, end),
+                    7, 0b1000_0000);
+        }
+
+        this.huffman = huffman;
+        state = CONFIGURED;
+        return this;
+    }
+
+    boolean write(ByteBuffer output) {
+        if (state == DONE) {
+            return true;
+        }
+        if (state == NEW) {
+            throw new IllegalStateException("Configure first");
+        }
+        if (!output.hasRemaining()) {
+            return false;
+        }
+        if (state == CONFIGURED) {
+            if (intWriter.write(output)) {
+                state = LENGTH_WRITTEN;
+            } else {
+                return false;
+            }
+        }
+        if (state == LENGTH_WRITTEN) {
+            boolean written = huffman
+                    ? huffmanWriter.write(output)
+                    : plainWriter.write(output);
+            if (written) {
+                state = DONE;
+                return true;
+            } else {
+                return false;
+            }
+        }
+        throw new InternalError(Arrays.toString(new Object[]{state, huffman}));
+    }
+
+    void reset() {
+        intWriter.reset();
+        if (huffman) {
+            huffmanWriter.reset();
+        } else {
+            plainWriter.reset();
+        }
+        state = NEW;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/package-info.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,34 @@
+/*
+ * 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
+ * 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.
+ */
+/**
+ * HPACK (Header Compression for HTTP/2) implementation conforming to
+ * <a href="https://tools.ietf.org/html/rfc7541">RFC&nbsp;7541</a>.
+ *
+ * <p> Headers can be decoded and encoded by {@link sun.net.httpclient.hpack.Decoder}
+ * and {@link sun.net.httpclient.hpack.Encoder} respectively.
+ *
+ * <p> Instances of these classes are not safe for use by multiple threads.
+ */
+package sun.net.httpclient.hpack;
--- a/jdk/src/java.logging/share/classes/java/util/logging/LogManager.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.logging/share/classes/java/util/logging/LogManager.java	Wed Jul 05 21:37:42 2017 +0200
@@ -42,7 +42,6 @@
 import java.util.stream.Stream;
 import jdk.internal.misc.JavaAWTAccess;
 import jdk.internal.misc.SharedSecrets;
-import sun.misc.ManagedLocalsThread;
 import sun.util.logging.internal.LoggingProviderImpl;
 
 /**
@@ -254,9 +253,10 @@
 
     // This private class is used as a shutdown hook.
     // It does a "reset" to close all open handlers.
-    private class Cleaner extends ManagedLocalsThread {
+    private class Cleaner extends Thread {
 
         private Cleaner() {
+            super(null, null, "Logging-Cleaner", 0, false);
             /* Set context class loader to null in order to avoid
              * keeping a strong reference to an application classloader.
              */
--- a/jdk/src/java.logging/share/classes/module-info.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.logging/share/classes/module-info.java	Wed Jul 05 21:37:42 2017 +0200
@@ -24,8 +24,6 @@
  */
 
 module java.logging {
-    // 8153158
-    requires jdk.unsupported;
     exports java.util.logging;
     provides jdk.internal.logger.DefaultLoggerFinder with
         sun.util.logging.internal.LoggingProviderImpl;
--- a/jdk/src/java.management/share/classes/com/sun/jmx/remote/internal/ClientCommunicatorAdmin.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.management/share/classes/com/sun/jmx/remote/internal/ClientCommunicatorAdmin.java	Wed Jul 05 21:37:42 2017 +0200
@@ -30,7 +30,6 @@
 
 import com.sun.jmx.remote.util.ClassLogger;
 import com.sun.jmx.remote.util.EnvHelp;
-import sun.misc.ManagedLocalsThread;
 
 public abstract class ClientCommunicatorAdmin {
     private static volatile long threadNo = 1;
@@ -41,10 +40,11 @@
         if (period > 0) {
             checker = new Checker();
 
-            Thread t = new ManagedLocalsThread(
-                checker,
-                "JMX client heartbeat " +  (++threadNo)
-            );
+            Thread t = new Thread(null,
+                                  checker,
+                                  "JMX client heartbeat " +  (++threadNo),
+                                  0,
+                                  false);
 
             t.setDaemon(true);
             t.start();
--- a/jdk/src/java.management/share/classes/com/sun/jmx/remote/internal/ClientNotifForwarder.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.management/share/classes/com/sun/jmx/remote/internal/ClientNotifForwarder.java	Wed Jul 05 21:37:42 2017 +0200
@@ -52,7 +52,6 @@
 import com.sun.jmx.remote.util.ClassLogger;
 import com.sun.jmx.remote.util.EnvHelp;
 import java.rmi.UnmarshalException;
-import sun.misc.ManagedLocalsThread;
 
 
 public abstract class ClientNotifForwarder {
@@ -91,7 +90,8 @@
                 throw new IllegalArgumentException("More than one command");
             this.command = command;
             if (thread == null) {
-                thread = new ManagedLocalsThread(
+                thread = new Thread(
+                    null,
                     ()-> {
                         while (true) {
                             Runnable r;
@@ -107,7 +107,9 @@
                             r.run();
                         }
                     },
-                    "ClientNotifForwarder-" + ++threadId
+                    "ClientNotifForwarder-" + ++threadId,
+                    0,
+                    false
                 );
                 thread.setDaemon(true);
                 thread.start();
--- a/jdk/src/java.management/share/classes/com/sun/jmx/remote/internal/ServerCommunicatorAdmin.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.management/share/classes/com/sun/jmx/remote/internal/ServerCommunicatorAdmin.java	Wed Jul 05 21:37:42 2017 +0200
@@ -27,7 +27,6 @@
 
 
 import com.sun.jmx.remote.util.ClassLogger;
-import sun.misc.ManagedLocalsThread;
 
 public abstract class ServerCommunicatorAdmin {
     public ServerCommunicatorAdmin(long timeout) {
@@ -42,7 +41,11 @@
         timestamp = 0;
         if (timeout < Long.MAX_VALUE) {
             Runnable timeoutTask = new Timeout();
-            final Thread t = new ManagedLocalsThread(timeoutTask);
+            final Thread t = new Thread(null,
+                                        timeoutTask,
+                                        "JMX-Server-Admin-Timeout",
+                                        0,
+                                        false);
             t.setName("JMX server connection timeout " + t.getId());
             // If you change this name you will need to change a unit test
             // (NoServerTimeoutTest)
--- a/jdk/src/java.management/share/classes/javax/management/monitor/Monitor.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.management/share/classes/javax/management/monitor/Monitor.java	Wed Jul 05 21:37:42 2017 +0200
@@ -61,7 +61,6 @@
 import javax.management.ObjectName;
 import javax.management.ReflectionException;
 import static javax.management.monitor.MonitorNotification.*;
-import sun.misc.ManagedLocalsThread;
 
 /**
  * Defines the part common to all monitor MBeans.
@@ -1637,10 +1636,12 @@
         }
 
         public Thread newThread(Runnable r) {
-            Thread t = new ManagedLocalsThread(
+            Thread t = new Thread(
                 group,
                 r,
-                namePrefix + threadNumber.getAndIncrement() + nameSuffix
+                namePrefix + threadNumber.getAndIncrement() + nameSuffix,
+                0,
+                false
             );
 
             t.setDaemon(true);
--- a/jdk/src/java.management/share/classes/javax/management/remote/rmi/RMIConnectorServer.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.management/share/classes/javax/management/remote/rmi/RMIConnectorServer.java	Wed Jul 05 21:37:42 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.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -45,6 +45,7 @@
 
 import javax.management.InstanceNotFoundException;
 import javax.management.MBeanServer;
+import javax.management.remote.JMXAuthenticator;
 
 import javax.management.remote.JMXConnectionNotification;
 import javax.management.remote.JMXConnector;
@@ -100,6 +101,21 @@
         "jmx.remote.rmi.server.socket.factory";
 
     /**
+    * Name of the attribute that specifies a list of class names acceptable
+    * as parameters to the {@link RMIServer#newClient(java.lang.Object) RMIServer.newClient()}
+    * remote method call.
+    * <p>
+    * This list of classes should correspond to the transitive closure of the
+    * credentials class (or classes) used by the installed {@linkplain JMXAuthenticator}
+    * associated with the {@linkplain RMIServer} implementation.
+    * <p>
+    * If the attribute is not set, or is null, then any class is
+    * deemed acceptable.
+    */
+    public static final String CREDENTIAL_TYPES =
+            "jmx.remote.rmi.server.credential.types";
+
+    /**
      * <p>Makes an <code>RMIConnectorServer</code>.
      * This is equivalent to calling {@link #RMIConnectorServer(
      * JMXServiceURL,Map,RMIServerImpl,MBeanServer)
--- a/jdk/src/java.management/share/classes/javax/management/remote/rmi/RMIJRMPServerImpl.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.management/share/classes/javax/management/remote/rmi/RMIJRMPServerImpl.java	Wed Jul 05 21:37:42 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2007, 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
@@ -39,6 +39,13 @@
 
 import com.sun.jmx.remote.internal.RMIExporter;
 import com.sun.jmx.remote.util.EnvHelp;
+import java.io.ObjectStreamClass;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import sun.reflect.misc.ReflectUtil;
+import sun.rmi.server.DeserializationChecker;
 import sun.rmi.server.UnicastServerRef;
 import sun.rmi.server.UnicastServerRef2;
 
@@ -52,6 +59,9 @@
  * @since 1.5
  */
 public class RMIJRMPServerImpl extends RMIServerImpl {
+
+    private final ExportedWrapper exportedWrapper;
+
     /**
      * <p>Creates a new {@link RMIServer} object that will be exported
      * on the given port using the given socket factories.</p>
@@ -89,10 +99,31 @@
         this.csf = csf;
         this.ssf = ssf;
         this.env = (env == null) ? Collections.<String, Object>emptyMap() : env;
+
+        String[] credentialsTypes
+                = (String[]) this.env.get(RMIConnectorServer.CREDENTIAL_TYPES);
+        List<String> types = null;
+        if (credentialsTypes != null) {
+            types = new ArrayList<>();
+            for (String type : credentialsTypes) {
+                if (type == null) {
+                    throw new IllegalArgumentException("A credential type is null.");
+                }
+                ReflectUtil.checkPackageAccess(type);
+                types.add(type);
+            }
+        }
+        exportedWrapper = types != null ?
+                new ExportedWrapper(this, types) :
+                null;
     }
 
     protected void export() throws IOException {
-        export(this);
+        if (exportedWrapper != null) {
+            export(exportedWrapper);
+        } else {
+            export(this);
+        }
     }
 
     private void export(Remote obj) throws RemoteException {
@@ -142,7 +173,11 @@
      *            RMIJRMPServerImpl has not been exported yet.
      */
     public Remote toStub() throws IOException {
-        return RemoteObject.toStub(this);
+        if (exportedWrapper != null) {
+            return RemoteObject.toStub(exportedWrapper);
+        } else {
+            return RemoteObject.toStub(this);
+        }
     }
 
     /**
@@ -189,11 +224,56 @@
      * server failed.
      */
     protected void closeServer() throws IOException {
-        unexport(this, true);
+        if (exportedWrapper != null) {
+            unexport(exportedWrapper, true);
+        } else {
+            unexport(this, true);
+        }
     }
 
     private final int port;
     private final RMIClientSocketFactory csf;
     private final RMIServerSocketFactory ssf;
     private final Map<String, ?> env;
+
+    private static class ExportedWrapper implements RMIServer, DeserializationChecker {
+        private final RMIServer impl;
+        private final List<String> allowedTypes;
+
+        private ExportedWrapper(RMIServer impl, List<String> credentialsTypes) {
+            this.impl = impl;
+            allowedTypes = credentialsTypes;
+        }
+
+        @Override
+        public String getVersion() throws RemoteException {
+            return impl.getVersion();
+        }
+
+        @Override
+        public RMIConnection newClient(Object credentials) throws IOException {
+            return impl.newClient(credentials);
+        }
+
+        @Override
+        public void check(Method method, ObjectStreamClass descriptor,
+                int paramIndex, int callID) {
+            String type = descriptor.getName();
+            if (!allowedTypes.contains(type)) {
+                throw new ClassCastException("Unsupported type: " + type);
+            }
+        }
+
+        @Override
+        public void checkProxyClass(Method method, String[] ifaces,
+                int paramIndex, int callID) {
+            if (ifaces != null && ifaces.length > 0) {
+                for (String iface : ifaces) {
+                    if (!allowedTypes.contains(iface)) {
+                        throw new ClassCastException("Unsupported type: " + iface);
+                    }
+                }
+            }
+        }
+    }
 }
--- a/jdk/src/java.management/share/classes/module-info.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.management/share/classes/module-info.java	Wed Jul 05 21:37:42 2017 +0200
@@ -27,8 +27,6 @@
     requires public java.rmi;
     requires java.logging;
     requires java.naming;
-    // 8147553
-    requires jdk.unsupported;
 
     exports java.lang.management;
     exports javax.management;
--- a/jdk/src/java.management/share/classes/sun/management/jdp/JdpController.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.management/share/classes/sun/management/jdp/JdpController.java	Wed Jul 05 21:37:42 2017 +0200
@@ -34,7 +34,6 @@
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 import sun.management.VMManagement;
-import sun.misc.ManagedLocalsThread;
 
 /**
  * JdpController is responsible to create and manage a broadcast loop.
@@ -219,7 +218,7 @@
 
         controller = new JDPControllerRunner(bcast, packet, pause);
 
-        Thread t = new ManagedLocalsThread(controller, "JDP broadcaster");
+        Thread t = new Thread(null, controller, "JDP broadcaster", 0, false);
         t.setDaemon(true);
         t.start();
     }
--- a/jdk/src/java.management/share/classes/sun/management/jmxremote/ConnectorBootstrap.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.management/share/classes/sun/management/jmxremote/ConnectorBootstrap.java	Wed Jul 05 21:37:42 2017 +0200
@@ -510,6 +510,9 @@
         // This RMI server should not keep the VM alive
         Map<String, Object> env = new HashMap<>();
         env.put(RMIExporter.EXPORTER_ATTRIBUTE, new PermanentExporter());
+        env.put(RMIConnectorServer.CREDENTIAL_TYPES, new String[]{
+            String[].class.getName(), String.class.getName()
+        });
 
         // The local connector server need only be available via the
         // loopback connection.
@@ -740,6 +743,9 @@
         PermanentExporter exporter = new PermanentExporter();
 
         env.put(RMIExporter.EXPORTER_ATTRIBUTE, exporter);
+        env.put(RMIConnectorServer.CREDENTIAL_TYPES, new String[]{
+            String[].class.getName(), String.class.getName()
+        });
 
         boolean useSocketFactory = bindAddress != null && !useSsl;
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.rmi/share/classes/sun/rmi/server/DeserializationChecker.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,93 @@
+/*
+ * 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 sun.rmi.server;
+
+import java.io.ObjectStreamClass;
+import java.lang.reflect.Method;
+
+/**
+ * Implementing this interface to have a deserialization control when RMI
+ * dispatches a remote request. If an exported object implements this interface,
+ * RMI dispatching mechanism will call the method {@code check} every time
+ * deserialising a remote object for invoking a method of the exported object.
+ *
+ * @author sjiang
+ */
+public interface DeserializationChecker {
+    /**
+     * Will be called to check a descriptor.
+     * This method may be called 2 times, the first time is when a descriptor is read
+     * from the stream, the second is just before creating an object described
+     * by this descriptor.
+     *
+     * @param method the method invoked from a remote request.
+     * @param descriptor The descriptor of the class of any object deserialised
+     *  while deserialising the parameter. The first descriptor will be that of
+     *  the top level object (the concrete class of the parameter itself);
+     *  Subsequent calls with the same {@code method}, {@code paramIndex} and
+     *  {@code callID} will correspond to objects contained in the parameter.
+     * @param paramIndex an index indicates the position of a parameter in the
+     * method. This index will be reused for deserialising all
+     * objects contained in the parameter object. For example, the parameter
+     * being deserialised is a {@code List}, all deserialisation calls for its
+     * elements will have same index.
+     * @param callID a unique ID identifying one
+     * time method invocation, the same ID is used for deserialization call of
+     * all parameters within the method.
+     */
+    public void check(Method method,
+            ObjectStreamClass descriptor,
+            int paramIndex,
+            int callID);
+
+    /**
+     * Will be called to validate a Proxy interfaces from a remote user before loading it.
+     * @param method the method invoked from a remote request.
+     * @param ifaces a string table of all interfaces implemented by the proxy to be checked.
+     * @param paramIndex an index indicates the position of a parameter in the
+     * method. This index will be reused for deserialising all
+     * objects contained in the parameter object. For example, the parameter
+     * being deserialised is a {@code List}, all deserialisation calls for its
+     * elements will have same index.
+     * @param callID a unique ID identifying one
+     * time method invocation, the same ID is used for deserialization call of
+     * all parameters within the method.
+     */
+    public void checkProxyClass(Method method,
+            String[] ifaces,
+            int paramIndex,
+            int callID);
+
+    /**
+     * Inform of the completion of parameter deserialisation for a method invocation.
+     * This is useful if the last parameter is a complex  object, like a {@code List}
+     * which elements are complex object too.
+     *
+     * The default implementation does nothing.
+     * @param callID the ID identifying a method invocation.
+     */
+    public default void end(int callID) {}
+}
--- a/jdk/src/java.rmi/share/classes/sun/rmi/server/MarshalInputStream.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.rmi/share/classes/sun/rmi/server/MarshalInputStream.java	Wed Jul 05 21:37:42 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2013, 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
@@ -30,13 +30,13 @@
 import java.io.ObjectInputStream;
 import java.io.ObjectStreamClass;
 import java.io.StreamCorruptedException;
-import java.net.URL;
 import java.util.*;
 import java.security.AccessControlException;
 import java.security.Permission;
-
 import java.rmi.server.RMIClassLoader;
 import java.security.PrivilegedAction;
+import jdk.internal.misc.ObjectStreamClassValidator;
+import jdk.internal.misc.SharedSecrets;
 
 /**
  * MarshalInputStream is an extension of ObjectInputStream.  When resolving
@@ -54,6 +54,11 @@
  * @author      Peter Jones
  */
 public class MarshalInputStream extends ObjectInputStream {
+    interface StreamChecker extends ObjectStreamClassValidator {
+        void checkProxyInterfaceNames(String[] ifaces);
+    }
+
+    private volatile StreamChecker streamChecker = null;
 
     /**
      * Value of "java.rmi.server.useCodebaseOnly" property,
@@ -123,7 +128,7 @@
         throws IOException, StreamCorruptedException
     {
         super(in);
-    }
+                    }
 
     /**
      * Returns a callback previously registered via the setDoneCallback
@@ -240,6 +245,11 @@
     protected Class<?> resolveProxyClass(String[] interfaces)
         throws IOException, ClassNotFoundException
     {
+        StreamChecker checker = streamChecker;
+        if (checker != null) {
+            checker.checkProxyInterfaceNames(interfaces);
+        }
+
         /*
          * Always read annotation written by MarshalOutputStream.
          */
@@ -319,4 +329,28 @@
     void useCodebaseOnly() {
         useCodebaseOnly = true;
     }
+
+    synchronized void setStreamChecker(StreamChecker checker) {
+        streamChecker = checker;
+        SharedSecrets.getJavaObjectInputStreamAccess().setValidator(this, checker);
+    }
+    @Override
+    protected ObjectStreamClass readClassDescriptor() throws IOException,
+            ClassNotFoundException {
+        ObjectStreamClass descriptor = super.readClassDescriptor();
+
+        validateDesc(descriptor);
+
+        return descriptor;
+    }
+
+    private void validateDesc(ObjectStreamClass descriptor) {
+        StreamChecker checker;
+        synchronized (this) {
+            checker = streamChecker;
+        }
+        if (checker != null) {
+            checker.validateDescriptor(descriptor);
+        }
+    }
 }
--- a/jdk/src/java.rmi/share/classes/sun/rmi/server/UnicastServerRef.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.rmi/share/classes/sun/rmi/server/UnicastServerRef.java	Wed Jul 05 21:37:42 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2013, 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
@@ -28,7 +28,7 @@
 import java.io.IOException;
 import java.io.ObjectInput;
 import java.io.ObjectOutput;
-import java.io.PrintStream;
+import java.io.ObjectStreamClass;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.rmi.MarshalException;
@@ -52,6 +52,7 @@
 import java.util.HashMap;
 import java.util.Map;
 import java.util.WeakHashMap;
+import java.util.concurrent.atomic.AtomicInteger;
 import sun.rmi.runtime.Log;
 import sun.rmi.transport.LiveRef;
 import sun.rmi.transport.Target;
@@ -116,6 +117,8 @@
     private static final Map<Class<?>,?> withoutSkeletons =
         Collections.synchronizedMap(new WeakHashMap<Class<?>,Void>());
 
+    private final AtomicInteger methodCallIDCount = new AtomicInteger(0);
+
     /**
      * Create a new (empty) Unicast server remote reference.
      */
@@ -297,14 +300,11 @@
             logCall(obj, method);
 
             // unmarshal parameters
-            Class<?>[] types = method.getParameterTypes();
-            Object[] params = new Object[types.length];
+            Object[] params = null;
 
             try {
                 unmarshalCustomCallData(in);
-                for (int i = 0; i < types.length; i++) {
-                    params[i] = unmarshalValue(types[i], in);
-                }
+                params = unmarshalParameters(obj, method, marshalStream);
             } catch (java.io.IOException e) {
                 throw new UnmarshalException(
                     "error unmarshalling arguments", e);
@@ -565,4 +565,85 @@
             return map;
         }
     }
+
+    /**
+     * Unmarshal parameters for the given method of the given instance over
+     * the given marshalinputstream. Perform any necessary checks.
+     */
+    private Object[] unmarshalParameters(Object obj, Method method, MarshalInputStream in)
+    throws IOException, ClassNotFoundException {
+        return (obj instanceof DeserializationChecker) ?
+            unmarshalParametersChecked((DeserializationChecker)obj, method, in) :
+            unmarshalParametersUnchecked(method, in);
+    }
+
+    /**
+     * Unmarshal parameters for the given method of the given instance over
+     * the given marshalinputstream. Do not perform any additional checks.
+     */
+    private Object[] unmarshalParametersUnchecked(Method method, ObjectInput in)
+    throws IOException, ClassNotFoundException {
+        Class<?>[] types = method.getParameterTypes();
+        Object[] params = new Object[types.length];
+        for (int i = 0; i < types.length; i++) {
+            params[i] = unmarshalValue(types[i], in);
+        }
+        return params;
+    }
+
+    /**
+     * Unmarshal parameters for the given method of the given instance over
+     * the given marshalinputstream. Do perform all additional checks.
+     */
+    private Object[] unmarshalParametersChecked(
+        DeserializationChecker checker,
+        Method method, MarshalInputStream in)
+    throws IOException, ClassNotFoundException {
+        int callID = methodCallIDCount.getAndIncrement();
+        MyChecker myChecker = new MyChecker(checker, method, callID);
+        in.setStreamChecker(myChecker);
+        try {
+            Class<?>[] types = method.getParameterTypes();
+            Object[] values = new Object[types.length];
+            for (int i = 0; i < types.length; i++) {
+                myChecker.setIndex(i);
+                values[i] = unmarshalValue(types[i], in);
+            }
+            myChecker.end(callID);
+            return values;
+        } finally {
+            in.setStreamChecker(null);
+        }
+    }
+
+    private static class MyChecker implements MarshalInputStream.StreamChecker {
+        private final DeserializationChecker descriptorCheck;
+        private final Method method;
+        private final int callID;
+        private int parameterIndex;
+
+        MyChecker(DeserializationChecker descriptorCheck, Method method, int callID) {
+            this.descriptorCheck = descriptorCheck;
+            this.method = method;
+            this.callID = callID;
+        }
+
+        @Override
+        public void validateDescriptor(ObjectStreamClass descriptor) {
+            descriptorCheck.check(method, descriptor, parameterIndex, callID);
+        }
+
+        @Override
+        public void checkProxyInterfaceNames(String[] ifaces) {
+            descriptorCheck.checkProxyClass(method, ifaces, parameterIndex, callID);
+        }
+
+        void setIndex(int parameterIndex) {
+            this.parameterIndex = parameterIndex;
+        }
+
+        void end(int callId) {
+            descriptorCheck.end(callId);
+        }
+    }
 }
--- a/jdk/src/java.security.jgss/share/classes/sun/security/jgss/SunProvider.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.security.jgss/share/classes/sun/security/jgss/SunProvider.java	Wed Jul 05 21:37:42 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
@@ -97,8 +97,6 @@
         }
     }
 
-    public static final SunProvider INSTANCE = new SunProvider();
-
     public SunProvider() {
         /* We are the Sun JGSS provider */
         super("SunJGSS", 9.0d, INFO);
--- a/jdk/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/GSSNameElement.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/GSSNameElement.java	Wed Jul 05 21:37:42 2017 +0200
@@ -159,7 +159,9 @@
             int atPos = krbName.lastIndexOf('@');
             if (atPos != -1) {
                 String atRealm = krbName.substring(atPos);
-                if (nameType.equals(GSSUtil.NT_GSS_KRB5_PRINCIPAL)
+                // getNativeNameType() can modify NT_GSS_KRB5_PRINCIPAL to null
+                if ((nameType == null
+                            || nameType.equals(GSSUtil.NT_GSS_KRB5_PRINCIPAL))
                         && new String(nameBytes).endsWith(atRealm)) {
                     // Created from Kerberos name with realm, no need to check
                 } else {
--- a/jdk/src/java.security.jgss/windows/classes/sun/security/krb5/internal/tools/Klist.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.security.jgss/windows/classes/sun/security/krb5/internal/tools/Klist.java	Wed Jul 05 21:37:42 2017 +0200
@@ -134,7 +134,7 @@
         Character arg;
         for (int i = 0; i < args.length; i++) {
             if ((args[i].length() >= 2) && (args[i].startsWith("-"))) {
-                arg = new Character(args[i].charAt(1));
+                arg = Character.valueOf(args[i].charAt(1));
                 switch (arg.charValue()) {
                 case 'c':
                     action = 'c';
--- a/jdk/src/java.sql.rowset/share/classes/com/sun/rowset/CachedRowSetImpl.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/java.sql.rowset/share/classes/com/sun/rowset/CachedRowSetImpl.java	Wed Jul 05 21:37:42 2017 +0200
@@ -1963,7 +1963,7 @@
             return (float)0;
         }
         try {
-            return ((new Float(value.toString())).floatValue());
+            return Float.parseFloat(value.toString());
         } catch (NumberFormatException ex) {
             throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.floatfail").toString(),
                   new Object[] {value.toString().trim(), columnIndex}));
@@ -2007,7 +2007,7 @@
             return (double)0;
         }
         try {
-            return ((new Double(value.toString().trim())).doubleValue());
+            return Double.parseDouble(value.toString().trim());
         } catch (NumberFormatException ex) {
             throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.doublefail").toString(),
                   new Object[] {value.toString().trim(), columnIndex}));
@@ -4017,9 +4017,9 @@
                     return new BigDecimal(srcObj.toString().trim());
                 case java.sql.Types.REAL:
                 case java.sql.Types.FLOAT:
-                    return new Float(srcObj.toString().trim());
+                    return Float.valueOf(srcObj.toString().trim());
                 case java.sql.Types.DOUBLE:
-                    return new Double(srcObj.toString().trim());
+                    return Double.valueOf(srcObj.toString().trim());
                 case java.sql.Types.CHAR:
                 case java.sql.Types.VARCHAR:
                 case java.sql.Types.LONGVARCHAR:
--- a/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/Translator.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/Translator.java	Wed Jul 05 21:37:42 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.
  * 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,13 +26,11 @@
 
 package com.sun.java.accessibility.util;
 
-import java.lang.*;
+import com.sun.java.accessibility.util.internal.*;
 import java.beans.*;
 import java.util.*;
 import java.awt.*;
 import java.awt.event.*;
-import java.awt.image.*;
-import java.security.AccessControlException;
 // Do not import Swing classes.  This module is intended to work
 // with both Swing and AWT.
 // import javax.swing.*;
@@ -77,12 +75,26 @@
         if (c == null) {
             return null;
         }
-        try {
-            t = Class.forName("com.sun.java.accessibility.util.internal."
-                              + c.getSimpleName()
-                              + "Translator");
+        switch (c.getSimpleName()) {
+            case "Button":
+                t = ButtonTranslator.class;
+                break;
+            case "Checkbox":
+                t = CheckboxTranslator.class;
+                break;
+            case "Label":
+                t = LabelTranslator.class;
+                break;
+            case "List":
+                t = ListTranslator.class;
+                break;
+            case "TextComponent":
+                t = TextComponentTranslator.class;
+                break;
+        }
+        if (t != null) {
             return t;
-        } catch (Exception e) {
+        } else {
             return getTranslatorClass(c.getSuperclass());
         }
     }
@@ -106,10 +118,6 @@
         if (o instanceof Accessible) {
             a = (Accessible)o;
         } else {
-            // About to "newInstance" an object of a class of a restricted package
-            // so ensure the caller is allowed access to that package.
-            String pkg = "com.sun.java.accessibility.util.internal";
-            System.getSecurityManager().checkPackageAccess(pkg);
             Class<?> translatorClass = getTranslatorClass(o.getClass());
             if (translatorClass != null) {
                 try {
--- a/jdk/src/jdk.accessibility/windows/native/jaccesswalker/jaccesswalker.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/jdk.accessibility/windows/native/jaccesswalker/jaccesswalker.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2015, 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
@@ -543,7 +543,7 @@
     } else {
         char s[LINE_BUFSIZE];
         sprintf( s,
-            "ERROR calling GetAccessibleContextInfo; vmID = %X, context = %X",
+            "ERROR calling GetAccessibleContextInfo; vmID = %X, context = %p",
             vmID, context );
 
         TVITEM tvi;
--- a/jdk/src/jdk.accessibility/windows/native/libwindowsaccessbridge/WinAccessBridge.cpp	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/jdk.accessibility/windows/native/libwindowsaccessbridge/WinAccessBridge.cpp	Wed Jul 05 21:37:42 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2015, 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
@@ -1125,7 +1125,7 @@
 
     PrintDebugString("WinAccessBridge::getAccessibleContextWithFocus(%p, %X, )", window, vmID);
     // find vmID, etc. from HWND; ask that VM for the AC w/Focus
-        HWND pkgVMID = (HWND)ABLongToHandle( pkg->rVMID ) ;
+    HWND pkgVMID;
     if (getAccessibleContextFromHWND(window, (long *)&(pkgVMID), &(pkg->rAccessibleContext)) == TRUE) {
         HWND destABWindow = javaVMs->findAccessBridgeWindow((long)pkgVMID);     // ineffecient [[[FIXME]]]
         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
--- a/jdk/src/jdk.crypto.pkcs11/share/classes/module-info.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/jdk.crypto.pkcs11/share/classes/module-info.java	Wed Jul 05 21:37:42 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
@@ -26,8 +26,6 @@
 module jdk.crypto.pkcs11 {
     // Depends on SunEC provider for EC related functionality
     requires jdk.crypto.ec;
-    // 8153371
-    requires jdk.unsupported;
     provides java.security.Provider with sun.security.pkcs11.SunPKCS11;
 }
 
--- a/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/SunPKCS11.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/SunPKCS11.java	Wed Jul 05 21:37:42 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
@@ -42,7 +42,6 @@
 import javax.security.auth.callback.PasswordCallback;
 import javax.security.auth.callback.TextOutputCallback;
 
-import sun.misc.ManagedLocalsThread;
 import sun.security.util.Debug;
 import sun.security.util.ResourcesMgr;
 
@@ -816,7 +815,7 @@
             return;
         }
         final TokenPoller poller = new TokenPoller(this);
-        Thread t = new ManagedLocalsThread(poller, "Poller " + getName());
+        Thread t = new Thread(null, poller, "Poller " + getName(), 0, false);
         t.setDaemon(true);
         t.setPriority(Thread.MIN_PRIORITY);
         t.start();
--- a/jdk/src/jdk.httpserver/share/classes/module-info.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/jdk.httpserver/share/classes/module-info.java	Wed Jul 05 21:37:42 2017 +0200
@@ -25,8 +25,7 @@
 
 module jdk.httpserver {
     requires java.logging;
-    // 8153372
-    requires jdk.unsupported;
+
     exports com.sun.net.httpserver;
     exports com.sun.net.httpserver.spi;
     uses com.sun.net.httpserver.spi.HttpServerProvider;
--- a/jdk/src/jdk.httpserver/share/classes/sun/net/httpserver/ServerImpl.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/jdk.httpserver/share/classes/sun/net/httpserver/ServerImpl.java	Wed Jul 05 21:37:42 2017 +0200
@@ -36,7 +36,6 @@
 import com.sun.net.httpserver.*;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
-import sun.misc.ManagedLocalsThread;
 import sun.net.httpserver.HttpConnection.State;
 
 /**
@@ -143,7 +142,7 @@
         if (executor == null) {
             executor = new DefaultExecutor();
         }
-        dispatcherThread = new ManagedLocalsThread(dispatcher);
+        dispatcherThread = new Thread(null, dispatcher, "HTTP-Dispatcher", 0, false);
         started = true;
         dispatcherThread.start();
     }
--- a/jdk/src/jdk.jcmd/share/classes/sun/tools/jstat/ExpressionExecuter.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/jdk.jcmd/share/classes/sun/tools/jstat/ExpressionExecuter.java	Wed Jul 05 21:37:42 2017 +0200
@@ -83,14 +83,14 @@
         if (op == null) {
             return evaluate(l);
         } else {
-            Double lval = new Double(((Number)evaluate(l)).doubleValue());
-            Double rval = new Double(((Number)evaluate(r)).doubleValue());
-            double result = op.eval(lval.doubleValue(), rval.doubleValue());
+            double lval = ((Number)evaluate(l)).doubleValue();
+            double rval = ((Number)evaluate(r)).doubleValue();
+            double result = op.eval(lval, rval);
             if (debug) {
                 System.out.println("Performed Operation: " + lval + op + rval
                                    + " = " + result);
             }
-            return new Double(result);
+            return Double.valueOf(result);
         }
     }
 }
--- a/jdk/src/jdk.jcmd/share/classes/sun/tools/jstat/ExpressionResolver.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/jdk.jcmd/share/classes/sun/tools/jstat/ExpressionResolver.java	Wed Jul 05 21:37:42 2017 +0200
@@ -71,7 +71,7 @@
             if (m == null) {
                 System.err.println("Warning: Unresolved Symbol: "
                                    + id.getName() + " substituted NaN");
-                return new Literal(new Double(Double.NaN));
+                return new Literal(Double.valueOf(Double.NaN));
             }
             if (m.getVariability() == Variability.CONSTANT) {
                 if (debug) {
@@ -105,7 +105,7 @@
                 Literal rl = (Literal)r;
                 boolean warn = false;
 
-                Double nan = new Double(Double.NaN);
+                Double nan = Double.valueOf(Double.NaN);
                 if (ll.getValue() instanceof String) {
                     warn = true; ll.setValue(nan);
                 }
@@ -129,7 +129,7 @@
                                        + " (right = " + rn.doubleValue() + ")"
                                        + " to literal value " + result);
                 }
-                return new Literal(new Double(result));
+                return new Literal(Double.valueOf(result));
             }
         }
 
--- a/jdk/src/jdk.jcmd/share/classes/sun/tools/jstat/Parser.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/jdk.jcmd/share/classes/sun/tools/jstat/Parser.java	Wed Jul 05 21:37:42 2017 +0200
@@ -324,7 +324,7 @@
         case StreamTokenizer.TT_NUMBER:
             double literal = lookahead.nval;
             matchNumber();
-            e = new Literal(new Double(literal));
+            e = new Literal(Double.valueOf(literal));
             log(pdebug, "Parsed: number -> " + literal);
             break;
         default:
@@ -360,7 +360,7 @@
             e1.setOperator(op);
             e1.setRight(e);
             log(pdebug, "Parsed: unary -> " + e1);
-            e1.setLeft(new Literal(new Double(0)));
+            e1.setLeft(new Literal(Double.valueOf(0)));
             e = e1;
         }
     }
--- a/jdk/src/jdk.jdi/share/classes/com/sun/jdi/VirtualMachineManager.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/jdk.jdi/share/classes/com/sun/jdi/VirtualMachineManager.java	Wed Jul 05 21:37:42 2017 +0200
@@ -257,11 +257,11 @@
  * delegate to the {@link com.sun.jdi.connect.spi.TransportService#description()
  * description()} method of the underlying transport service. Both
  * the AttachingConnector and the ListeningConnector will have two
- * Connector {@link com.sun.jdi.connect.Connector$Argument Arguments}.
- * A {@link com.sun.jdi.connect.Connector$StringArgument StringArgument}
+ * Connector {@link com.sun.jdi.connect.Connector.Argument Arguments}.
+ * A {@link com.sun.jdi.connect.Connector.StringArgument StringArgument}
  * named {@code address} is the connector argument to specify the
  * address to attach too, or to listen on. A
- * {@link com.sun.jdi.connect.Connector$IntegerArgument IntegerArgument}
+ * {@link com.sun.jdi.connect.Connector.IntegerArgument IntegerArgument}
  * named {@code timeout} is the connector argument to specify the
  * timeout when attaching, or accepting. The timeout connector may be
  * ignored depending on if the transport service supports an attach
--- a/jdk/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/Commands.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/Commands.java	Wed Jul 05 21:37:42 2017 +0200
@@ -478,7 +478,7 @@
             ThreadGroupReference tg = it.nextThreadGroup();
             ++cnt;
             MessageOutput.println("thread group number description name",
-                                  new Object [] { new Integer (cnt),
+                                  new Object [] { Integer.valueOf(cnt),
                                                   Env.description(tg),
                                                   tg.name()});
         }
@@ -1014,7 +1014,7 @@
         return MessageOutput.format("locationString",
                                     new Object [] {loc.declaringType().name(),
                                                    loc.method().name(),
-                                                   new Integer (loc.lineNumber()),
+                                                   Integer.valueOf(loc.lineNumber()),
                                                    Long.valueOf(loc.codeIndex())});
     }
 
@@ -1467,7 +1467,7 @@
                 MessageOutput.println("Line number information not available for");
             } else if (Env.sourceLine(loc, lineno) == null) {
                 MessageOutput.println("is an invalid line number for",
-                                      new Object [] {new Integer (lineno),
+                                      new Object [] {Integer.valueOf(lineno),
                                                      refType.name()});
             } else {
                 for (int i = startLine; i <= endLine; i++) {
@@ -1477,11 +1477,11 @@
                     }
                     if (i == lineno) {
                         MessageOutput.println("source line number current line and line",
-                                              new Object [] {new Integer (i),
+                                              new Object [] {Integer.valueOf(i),
                                                              sourceLine});
                     } else {
                         MessageOutput.println("source line number and line",
-                                              new Object [] {new Integer (i),
+                                              new Object [] {Integer.valueOf(i),
                                                              sourceLine});
                     }
                 }
@@ -1725,7 +1725,7 @@
                 } else {
                     MessageOutput.println("Owned by:",
                                           new Object [] {owner.name(),
-                                                         new Integer (object.entryCount())});
+                                                         Integer.valueOf(object.entryCount())});
                 }
                 List<ThreadReference> waiters = object.waitingThreads();
                 if (waiters.size() == 0) {
--- a/jdk/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/MessageOutput.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/MessageOutput.java	Wed Jul 05 21:37:42 2017 +0200
@@ -198,7 +198,7 @@
                 (MessageOutput.format("jdb prompt thread name and current stack frame",
                                       new Object [] {
                                           threadInfo.getThread().name(),
-                                          new Integer (threadInfo.getCurrentFrameIndex() + 1)}));
+                                          Integer.valueOf(threadInfo.getCurrentFrameIndex() + 1)}));
         }
         System.out.flush();
     }
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jimage/ExtractedImage.java	Thu Apr 21 12:57:17 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,78 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package jdk.tools.jimage;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.function.Consumer;
-import jdk.tools.jlink.internal.ImageFileCreator;
-import jdk.tools.jlink.internal.Archive;
-import jdk.tools.jlink.internal.ImagePluginStack;
-import jdk.tools.jlink.internal.DirArchive;
-/**
- *
- * Support for extracted image.
- */
-public final class ExtractedImage {
-
-    private Set<Archive> archives = new HashSet<>();
-    private final ImagePluginStack plugins;
-
-    ExtractedImage(Path dirPath, ImagePluginStack plugins, PrintWriter log,
-            boolean verbose) throws IOException {
-        if (!Files.isDirectory(dirPath)) {
-            throw new IOException("Not a directory");
-        }
-        Consumer<String> cons = (String t) -> {
-            if (verbose) {
-                log.println(t);
-            }
-        };
-        this.plugins = plugins;
-        Files.walk(dirPath, 1).forEach((p) -> {
-            if (!dirPath.equals(p)) {
-                if (Files.isDirectory(p)) {
-                    Archive a = new DirArchive(p, cons);
-                    archives.add(a);
-                }
-            }
-        });
-        archives = Collections.unmodifiableSet(archives);
-    }
-
-    void recreateJImage(Path path) throws IOException {
-        ImageFileCreator.recreateJimage(path, archives, plugins);
-    }
-
-    private static String getPathName(Path path) {
-        return path.toString().replace(File.separatorChar, '/');
-    }
-}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jimage/JImageTask.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jimage/JImageTask.java	Wed Jul 05 21:37:42 2017 +0200
@@ -32,7 +32,6 @@
 import java.nio.ByteOrder;
 import java.nio.channels.FileChannel;
 import java.nio.file.Files;
-import java.nio.file.Path;
 import static java.nio.file.StandardOpenOption.READ;
 import static java.nio.file.StandardOpenOption.WRITE;
 import java.util.LinkedList;
@@ -44,8 +43,6 @@
 import static jdk.internal.jimage.ImageHeader.MINOR_VERSION;
 import jdk.internal.jimage.ImageLocation;
 import jdk.tools.jlink.internal.ImageResourcesTree;
-import jdk.tools.jlink.internal.ImagePluginConfiguration;
-import jdk.tools.jlink.internal.ImagePluginStack;
 import jdk.tools.jlink.internal.TaskHelper;
 import jdk.tools.jlink.internal.TaskHelper.BadArgs;
 import static jdk.tools.jlink.internal.TaskHelper.JIMAGE_BUNDLE;
@@ -97,7 +94,6 @@
         EXTRACT,
         INFO,
         LIST,
-        RECREATE,
         SET,
         VERIFY
     };
@@ -152,21 +148,28 @@
             setLog(new PrintWriter(System.out));
         }
 
+        if (args.length == 0) {
+            log.println(taskHelper.getMessage("main.usage.summary", PROGNAME));
+            return EXIT_ABNORMAL;
+        }
+
         try {
             List<String> unhandled = optionsHelper.handleOptions(this, args);
             if(!unhandled.isEmpty()) {
-                options.task = Enum.valueOf(Task.class, unhandled.get(0).toUpperCase());
+                try {
+                    options.task = Enum.valueOf(Task.class, unhandled.get(0).toUpperCase());
+                } catch (IllegalArgumentException ex) {
+                    throw taskHelper.newBadArgs("err.not.a.task", unhandled.get(0));
+                }
                 for(int i = 1; i < unhandled.size(); i++) {
                     options.jimages.add(new File(unhandled.get(i)));
                 }
+            } else {
+                throw taskHelper.newBadArgs("err.not.a.task", "<unspecified>");
             }
             if (options.help) {
                 optionsHelper.showHelp(PROGNAME);
             }
-            if(optionsHelper.listPlugins()) {
-                optionsHelper.listPlugins(true);
-                return EXIT_OK;
-            }
             if (options.version || options.fullVersion) {
                 taskHelper.showVersion(options.fullVersion);
             }
@@ -186,49 +189,19 @@
         }
     }
 
-    private void recreate() throws Exception, BadArgs {
-        File directory = new File(options.directory);
-        if (!directory.isDirectory()) {
-            throw taskHelper.newBadArgs("err.not.a.dir", directory.getAbsolutePath());
-        }
-        Path dirPath = directory.toPath();
-        if (options.jimages.isEmpty()) {
-            throw taskHelper.newBadArgs("err.jimage.not.specified");
-        } else if (options.jimages.size() != 1) {
-            throw taskHelper.newBadArgs("err.only.one.jimage");
-        }
-
-        Path jimage = options.jimages.get(0).toPath();
-
-        if (jimage.toFile().createNewFile()) {
-            ImagePluginStack pc = ImagePluginConfiguration.parseConfiguration(taskHelper.
-                    getPluginsConfig(null, false));
-            ExtractedImage img = new ExtractedImage(dirPath, pc, log, options.verbose);
-            img.recreateJImage(jimage);
-        } else {
-            throw taskHelper.newBadArgs("err.jimage.already.exists", jimage.getFileName());
-        }
-    }
-
-    private void title(File file, BasicImageReader reader) {
-        log.println("jimage: " + file.getName());
-    }
-
     private void listTitle(File file, BasicImageReader reader) {
-        title(file, reader);
-
-        if (options.verbose) {
-            log.print(pad("Offset", OFFSET_WIDTH + 1));
-            log.print(pad("Size", SIZE_WIDTH + 1));
-            log.print(pad("Compressed", COMPRESSEDSIZE_WIDTH + 1));
-            log.println(" Entry");
-        }
+        log.println("jimage: " + file);
     }
 
     private interface JImageAction {
         public void apply(File file, BasicImageReader reader) throws IOException, BadArgs;
     }
 
+    private interface ModuleAction {
+         public void apply(BasicImageReader reader,
+                 String oldModule, String newModule) throws IOException, BadArgs;
+    }
+
     private interface ResourceAction {
         public void apply(BasicImageReader reader, String name,
                 ImageLocation location) throws IOException, BadArgs;
@@ -254,23 +227,32 @@
         }
     }
 
-    private static final int NUMBER_WIDTH = 12;
-    private static final int OFFSET_WIDTH = NUMBER_WIDTH;
-    private static final int SIZE_WIDTH = NUMBER_WIDTH;
-    private static final int COMPRESSEDSIZE_WIDTH = NUMBER_WIDTH;
+    private static final int OFFSET_WIDTH = 12;
+    private static final int SIZE_WIDTH = 10;
+    private static final int COMPRESSEDSIZE_WIDTH = 10;
+
+    private String trimModule(String name) {
+        int offset = name.indexOf('/', 1);
 
-    private void print(String entry, ImageLocation location) {
+        if (offset != -1 && offset + 1 < name.length()) {
+            return name.substring(offset + 1);
+        }
+
+        return name;
+    }
+
+    private void print(String name, ImageLocation location) {
         log.print(pad(location.getContentOffset(), OFFSET_WIDTH) + " ");
         log.print(pad(location.getUncompressedSize(), SIZE_WIDTH) + " ");
         log.print(pad(location.getCompressedSize(), COMPRESSEDSIZE_WIDTH) + " ");
-        log.println(entry);
+        log.println(trimModule(name));
     }
 
-    private void print(BasicImageReader reader, String entry) {
+    private void print(BasicImageReader reader, String name) {
         if (options.verbose) {
-            print(entry, reader.findLocation(entry));
+            print(name, reader.findLocation(name));
         } else {
-            log.println(entry);
+            log.println("    " + trimModule(name));
         }
     }
 
@@ -289,6 +271,18 @@
         log.println(" Index Size:     " + header.getIndexSize());
     }
 
+    private void listModule(BasicImageReader reader, String oldModule, String newModule) {
+        log.println();
+        log.println("Module: " + newModule);
+
+        if (options.verbose) {
+            log.print(pad("Offset", OFFSET_WIDTH) + " ");
+            log.print(pad("Size", SIZE_WIDTH) + " ");
+            log.print(pad("Compressed", COMPRESSEDSIZE_WIDTH) + " ");
+            log.println("Entry");
+        }
+    }
+
     private void list(BasicImageReader reader, String name, ImageLocation location) {
         print(reader, name);
     }
@@ -338,7 +332,12 @@
     }
 
     private void iterate(JImageAction jimageAction,
+            ModuleAction moduleAction,
             ResourceAction resourceAction) throws IOException, BadArgs {
+        if (options.jimages.isEmpty()) {
+            throw taskHelper.newBadArgs("err.no.jimage");
+        }
+
         for (File file : options.jimages) {
             if (!file.exists() || !file.isFile()) {
                 throw taskHelper.newBadArgs("err.not.a.jimage", file.getName());
@@ -351,9 +350,23 @@
 
                 if (resourceAction != null) {
                     String[] entryNames = reader.getEntryNames();
+                    String oldModule = "";
 
                     for (String name : entryNames) {
                         if (!ImageResourcesTree.isTreeInfoResource(name)) {
+                            if (moduleAction != null) {
+                                int offset = name.indexOf('/', 1);
+
+                                String newModule = offset != -1 ?
+                                        name.substring(1, offset) :
+                                        "<unknown>";
+
+                                if (!oldModule.equals(newModule)) {
+                                    moduleAction.apply(reader, oldModule, newModule);
+                                    oldModule = newModule;
+                                }
+                            }
+
                             ImageLocation location = reader.findLocation(name);
                             resourceAction.apply(reader, name, location);
                         }
@@ -366,22 +379,19 @@
     private boolean run() throws Exception, BadArgs {
         switch (options.task) {
             case EXTRACT:
-                iterate(null, this::extract);
+                iterate(null, null, this::extract);
                 break;
             case INFO:
-                iterate(this::info, null);
+                iterate(this::info, null, null);
                 break;
             case LIST:
-                iterate(this::listTitle, this::list);
-                break;
-            case RECREATE:
-                recreate();
+                iterate(this::listTitle, this::listModule, this::list);
                 break;
             case SET:
-                iterate(this::set, null);
+                iterate(this::set, null, null);
                 break;
             case VERIFY:
-                iterate(this::title, this::verify);
+                iterate(this::listTitle, null, this::verify);
                 break;
             default:
                 throw taskHelper.newBadArgs("err.invalid.task", options.task.name()).showUsage(true);
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jimage/resources/jimage.properties	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jimage/resources/jimage.properties	Wed Jul 05 21:37:42 2017 +0200
@@ -1,30 +1,25 @@
 main.usage.summary=\
-Usage: {0} <extract|info|list|recreate|set|verify> <options> jimage...\n\
+Usage: {0} <extract|info|list|set|verify> <options> jimage...\n\
 use --help for a list of possible options
 
 main.usage=\
-Usage: {0} <extract|info|list|recreate|set|verify> <options> jimage...\n\
+Usage: {0} <extract|info|list|set|verify> <options> jimage...\n\
 \n\
 \  extract  - Extract all jimage entries into separate files into the directory\n\
 \             specified by --dir=<directory> (default='.')\n\
 \  info     - Prints information specified in the jimage header.\n\
 \  list     - Prints the names of all the entries in the jimage.  When used with\n\
 \             --verbose will also print entry attributes ex. size and offset.\n\
-\  recreate - Reconstructs a jimage from an extracted directory (--dir)\n\
 \  set      - sets the value of specific jimage header entries\n\
 \  verify   - Reports errors on any .class entries that don't verify as classes.\n\
 \n\
 Possible options include:
 
-main.extended.help=\
-jimage recreate is extensible by the main of plugins. Following plugins have been discovered \
-thanks to ServiceLoader and can be used when re-creating a jimage.
-
 error.prefix=Error:
 warn.prefix=Warning:
 
 main.opt.dir=\
-\  --dir                                Target directory for extract/recreate
+\  --dir                                Target directory for extract
 
 main.opt.flags=\
 \  --flags=value                        Set the jimage flags to value
@@ -38,14 +33,8 @@
 main.opt.version=\
 \  --version                            Version information
 
-main.opt.configuration=\
-\  --configuration <path>               Path to properties file containing defaults\
-\ options for recreate
-
 main.command.files=\
 \  @<filename>                          Read options from file
-
-err.cannot.create.dir=cannot create directory: {0}
 err.cannot.read.file=cannot read file: {0}
 err.cannot.update.file=cannot update file: {0}
 err.file.not.found=cannot find file: {0}
@@ -53,12 +42,11 @@
 err.flags.not.int=--flags value not integer: {0}
 err.internal.error=internal error: {0} {1} {2}
 err.invalid.arg.for.option=invalid argument for option: {0}
-err.invalid.task=task must be extract|recreate|info|list|verify: {0}
-err.jimage.already.exists=jimage already exists: {0}
-err.jimage.not.specified=no jimage specified
+err.invalid.task=task must be extract|info|list|verify: {0}
 err.missing.arg=no value given for {0}
 err.not.a.dir=not a directory: {0}
 err.not.a.jimage=not a jimage file: {0}
-err.only.one.jimage=only one jimage should be specified
+err.no.jimage=no jimage provided
+err.not.a.task=not a valid task: {0}
 err.option.unsupported={0} not supported: {1}
 err.unknown.option=unknown option: {0}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/Pool.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/Pool.java	Wed Jul 05 21:37:42 2017 +0200
@@ -226,7 +226,7 @@
      * <li>For jimage content: /{module name}/{package1}/.../{packageN}/{file
      * name}</li>
      * <li>For other files (shared lib, launchers, config, ...):/{module name}/
-     * {@literal bin|conf|native}/{dir1}>/.../{dirN}/{file name}</li>
+     * {@literal bin|conf|native}/{dir1}/.../{dirN}/{file name}</li>
      * </ul>
      */
     public static class ModuleData {
--- a/jdk/src/jdk.unsupported/share/classes/sun/misc/ManagedLocalsThread.java	Thu Apr 21 12:57:17 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,92 +0,0 @@
-/*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.misc;
-
-/**
- * A thread that has it's thread locals, and inheritable thread
- * locals erased on construction.
- */
-public class ManagedLocalsThread extends Thread {
-    private static final jdk.internal.misc.Unsafe UNSAFE;
-    private static final long THREAD_LOCALS;
-    private static final long INHERITABLE_THREAD_LOCALS;
-
-    public ManagedLocalsThread() {
-        eraseThreadLocals();
-    }
-
-    public ManagedLocalsThread(Runnable target) {
-        super(target);
-        eraseThreadLocals();
-    }
-
-    public ManagedLocalsThread(String name) {
-        super(name);
-        eraseThreadLocals();
-    }
-
-    public ManagedLocalsThread(ThreadGroup group, Runnable target) {
-        super(group, target);
-        eraseThreadLocals();
-    }
-
-    public ManagedLocalsThread(Runnable target, String name) {
-        super(target, name);
-        eraseThreadLocals();
-    }
-
-    public ManagedLocalsThread(ThreadGroup group, String name) {
-        super(group, name);
-        eraseThreadLocals();
-    }
-
-    public ManagedLocalsThread(ThreadGroup group, Runnable target, String name) {
-        super(group, target, name);
-        eraseThreadLocals();
-    }
-
-    /**
-     * Drops all thread locals (and inherited thread locals).
-     */
-    public final void eraseThreadLocals() {
-        UNSAFE.putObject(this, THREAD_LOCALS, null);
-        UNSAFE.putObject(this, INHERITABLE_THREAD_LOCALS, null);
-    }
-
-    static {
-        UNSAFE = jdk.internal.misc.Unsafe.getUnsafe();
-        Class<?> t = Thread.class;
-        try {
-            THREAD_LOCALS = UNSAFE.objectFieldOffset
-                (t.getDeclaredField("threadLocals"));
-            INHERITABLE_THREAD_LOCALS = UNSAFE.objectFieldOffset
-                (t.getDeclaredField("inheritableThreadLocals"));
-        } catch (Exception e) {
-            throw new Error(e);
-        }
-    }
-}
-
--- a/jdk/test/ProblemList.txt	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/test/ProblemList.txt	Wed Jul 05 21:37:42 2017 +0200
@@ -335,10 +335,6 @@
 
 com/sun/jdi/GetLocalVariables4Test.sh                           8067354 windows-all
 
-com/sun/jdi/InterfaceMethodsTest.java				8152586 generic-all
-
-com/sun/jdi/InvokeTest.java					8152586 generic-all
-
 ############################################################################
 
 # jdk_util
--- a/jdk/test/TEST.groups	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/test/TEST.groups	Wed Jul 05 21:37:42 2017 +0200
@@ -32,7 +32,6 @@
     -java/util/WeakHashMap/GCDuringIteration.java \
     -java/util/concurrent/ThreadPoolExecutor/ConfigChanges.java \
     -java/util/concurrent/forkjoin/FJExceptionTableLeak.java \
-    -java/util/TimeZone/Bug6772689.java \
     sun/nio/cs/ISO8859x.java \
     java/nio/Buffer \
     com/sun/crypto/provider/Cipher \
@@ -43,7 +42,6 @@
     java/util/WeakHashMap/GCDuringIteration.java \
     java/util/concurrent/ThreadPoolExecutor/ConfigChanges.java \
     java/util/concurrent/forkjoin/FJExceptionTableLeak.java \
-    java/util/TimeZone/Bug6772689.java \
     :jdk_io \
     :jdk_nio \
     -sun/nio/cs/ISO8859x.java \
--- a/jdk/test/com/sun/jdi/ShellScaffold.sh	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/test/com/sun/jdi/ShellScaffold.sh	Wed Jul 05 21:37:42 2017 +0200
@@ -924,7 +924,7 @@
         # If jstack exists, so will jps
         # Show stack traces of jdb and debuggee as a possible debugging aid.
         jdbCmd=`$jdk/bin/jps -v | $grep $jdbKeyword`
-        realJdbPid=`echo "$jdbCmd" | sed -e 's@ TTY.*@@'`
+        realJdbPid=`echo "$jdbCmd" | sed -e 's@ .*@@'`
         if [ ! -z "$realJdbPid" ] ; then
             echo "-- jdb process info ----------------------" >&2
             echo "      $jdbCmd"                              >&2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/jdi/SunBootClassPathEmptyTest.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,97 @@
+/*
+ * 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 com.sun.jdi.connect.*;
+import com.sun.jdi.*;
+import java.util.Map;
+import java.util.List;
+import jdk.test.lib.Asserts;
+
+/*
+ * @test
+ * @summary Verifies that PathSearchingVirtualMachine.bootClassPath()
+ *          returns an empty list in case no bootclass path specified
+ *          regardless of sun.boot.class.path option, which is now obsolete
+ * @library /test/lib/share/classes
+ * @compile TestClass.java
+ * @compile SunBootClassPathEmptyTest.java
+ * @run main/othervm SunBootClassPathEmptyTest
+ */
+public class SunBootClassPathEmptyTest {
+
+    /**
+     * Helper class to facilitate the debuggee VM launching
+     */
+    private static class VmConnector {
+
+        LaunchingConnector lc;
+        VirtualMachine vm;
+
+        VmConnector() {
+            for (LaunchingConnector c : Bootstrap.virtualMachineManager().launchingConnectors()) {
+                System.out.println("name: " + c.name());
+                if (c.name().equals("com.sun.jdi.CommandLineLaunch")) {
+                    lc = c;
+                    break;
+                }
+            }
+            if (lc == null) {
+                throw new RuntimeException("Connector not found");
+            }
+        }
+
+        PathSearchingVirtualMachine launchVm(String cmdLine, String options) throws Exception {
+            Map<String, Connector.Argument> vmArgs = lc.defaultArguments();
+            vmArgs.get("main").setValue(cmdLine);
+            if (options != null) {
+                vmArgs.get("options").setValue(options);
+            }
+            System.out.println("Debugger is launching vm ...");
+            vm = lc.launch(vmArgs);
+            if (!(vm instanceof PathSearchingVirtualMachine)) {
+                throw new RuntimeException("VM is not a PathSearchingVirtualMachine");
+            }
+            return (PathSearchingVirtualMachine) vm;
+        }
+
+    }
+
+    private static VmConnector connector = new VmConnector();
+
+    public static void main(String[] args) throws Exception {
+        testWithObsoleteClassPathOption(null);
+        testWithObsoleteClassPathOption("someclasspath");
+    }
+
+    private static void testWithObsoleteClassPathOption(String obsoleteClassPath) throws Exception {
+        PathSearchingVirtualMachine vm = connector.launchVm("TestClass", makeClassPathOptions(obsoleteClassPath));
+        List<String> bootClassPath = vm.bootClassPath();
+        Asserts.assertNotNull(bootClassPath, "Expected bootClassPath to be empty but was null");
+        Asserts.assertEquals(0, bootClassPath.size(), "Expected bootClassPath.size() 0 but was: " + bootClassPath.size());
+    }
+
+    private static String makeClassPathOptions(String obsoleteClassPath) {
+        return obsoleteClassPath == null ? null : "-Dsun.boot.class.path=" + obsoleteClassPath;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/jdi/TestClass.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+public class TestClass {
+
+    public static void main(String[] args) {
+        System.out.println("This is a test");
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Button/ActionEventTest/ActionEventTest.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,109 @@
+/*
+ * 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 6191390
+ * @summary Verify that ActionEvent is received with correct modifiers set.
+ * @run main/manual ActionEventTest
+ */
+
+import java.awt.AWTException;
+import java.awt.FlowLayout;
+import java.awt.Frame;
+import java.awt.Button;
+import java.awt.TextArea;
+import java.awt.Robot;
+import java.awt.Point;
+import java.awt.event.InputEvent;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.KeyEvent;
+
+public class ActionEventTest extends Frame {
+    Button button;
+    Robot robot;
+    TextArea instructions;
+    public static boolean isProgInterruption = false;
+    static Thread mainThread = null;
+    static int sleepTime = 300000;
+
+    public ActionEventTest() {
+        try {
+            robot = new Robot();
+        } catch(AWTException e) {
+            throw new RuntimeException(e.getMessage());
+        }
+
+        button = new Button("ClickMe");
+        button.setEnabled(true);
+
+        instructions = new TextArea(10, 50);
+        instructions.setText(
+        " This is a manual test\n" +
+        " Keep the Alt, Shift & Ctrl Keys pressed &\n" +
+        " Click 'ClickMe' button with left mouse button\n" +
+        " Test exits automatically after mouse click.");
+
+        add(button);
+        add(instructions);
+        setSize(400,400);
+        setLayout(new FlowLayout());
+        pack();
+        setVisible(true);
+        robot.waitForIdle();
+
+        button.addActionListener(new ActionListener() {
+            @Override
+            public void actionPerformed(ActionEvent ae) {
+                int md = ae.getModifiers();
+                int expectedMask = ActionEvent.ALT_MASK | ActionEvent.CTRL_MASK
+                        | ActionEvent.SHIFT_MASK;
+
+                isProgInterruption = true;
+                mainThread.interrupt();
+                if ((md & expectedMask) != expectedMask) {
+                    throw new RuntimeException("Action Event modifiers"
+                        + " are not set correctly.");
+                }
+            }
+        });
+    }
+
+    public static void main(String args[]) throws Exception {
+        mainThread = Thread.currentThread();
+        ActionEventTest test = new ActionEventTest();
+        try {
+            mainThread.sleep(sleepTime);
+        } catch (InterruptedException e) {
+            if (!isProgInterruption) {
+                throw e;
+            }
+        }
+        test.dispose();
+        if (!isProgInterruption) {
+            throw new RuntimeException("Timed out after " + sleepTime / 1000
+                    + " seconds");
+        }
+    }
+}
--- a/jdk/test/java/awt/Component/CompEventOnHiddenComponent/CompEventOnHiddenComponent.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/test/java/awt/Component/CompEventOnHiddenComponent/CompEventOnHiddenComponent.java	Wed Jul 05 21:37:42 2017 +0200
@@ -25,7 +25,7 @@
 
 /*
   @test
-  @bug 6383903
+  @bug 6383903 8144166
   @summary REGRESSION: componentMoved is now getting called for some hidden components
   @author andrei.dmitriev: area=awt.component
   @run main CompEventOnHiddenComponent
--- a/jdk/test/java/awt/FontClass/CreateFont/CreateFontArrayTest.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/test/java/awt/FontClass/CreateFont/CreateFontArrayTest.java	Wed Jul 05 21:37:42 2017 +0200
@@ -23,9 +23,9 @@
 
 /*
  * @test
- * @bug 8055463
+ * @bug 8055463 8153272
  * @summary Test createFont APIs
- * @run CreateFontArrayTest
+ * @run main CreateFontArrayTest
  */
 
 import java.awt.Font;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/FontClass/TextRequiresLayoutTest.java	Wed Jul 05 21:37:42 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 8146324
+ * @summary Test Font.textRequiresLayout
+ */
+
+import java.awt.Font;
+
+public class TextRequiresLayoutTest {
+
+    public static void main(String args[]) {
+
+        String simpleStr = "Hello World";
+        String complexStr = "\u0641\u0642\u0643";
+        char[] simpleChars = simpleStr.toCharArray();
+        char[] complexChars = complexStr.toCharArray();
+
+        if (Font.textRequiresLayout(simpleChars, 0, simpleChars.length)) {
+            throw new RuntimeException("Simple text should not need layout");
+        }
+
+        if (!Font.textRequiresLayout(complexChars, 0, complexChars.length)) {
+            throw new RuntimeException("Complex text should need layout");
+        }
+
+        if (Font.textRequiresLayout(complexChars, 0, 0)) {
+            throw new RuntimeException("Empty text should not need layout");
+        }
+
+        boolean except = false;
+        try {
+             Font.textRequiresLayout(null, 0, 0);
+        } catch (NullPointerException npe) {
+           except = true;
+        }
+        if (!except) {
+            throw new RuntimeException("No expected IllegalArgumentException");
+        }
+
+        except = false;
+        try {
+             Font.textRequiresLayout(complexChars, -1, 0);
+        } catch (ArrayIndexOutOfBoundsException aioobe) {
+           except = true;
+        }
+        if (!except) {
+            throw new
+                RuntimeException("No expected ArrayIndexOutOfBoundsException");
+        }
+
+        except = false;
+        try {
+             Font.textRequiresLayout(complexChars, 0, complexChars.length+1);
+        } catch (ArrayIndexOutOfBoundsException aioobe) {
+           except = true;
+        }
+        if (!except) {
+            throw new
+                RuntimeException("No expected ArrayIndexOutOfBoundsException");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/List/ActionEventTest/ActionEventTest.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,100 @@
+/*
+ * 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 6191390
+ * @summary Verify that ActionEvent is received with correct modifiers set.
+ * @run main ActionEventTest
+ */
+
+import java.awt.AWTException;
+import java.awt.FlowLayout;
+import java.awt.Frame;
+import java.awt.List;
+import java.awt.Robot;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.KeyEvent;
+
+public class ActionEventTest extends Frame {
+    List list;
+    Robot robot;
+
+    public ActionEventTest() {
+        try {
+            robot = new Robot();
+        } catch(AWTException e) {
+            throw new RuntimeException(e.getMessage());
+        }
+
+        list = new List(1, false);
+        list.add("0");
+        add(list);
+        setSize(400,400);
+        setLayout(new FlowLayout());
+        pack();
+        setVisible(true);
+        robot.waitForIdle();
+    }
+
+    void performTest() {
+        list.addActionListener(new ActionListener() {
+            @Override
+            public void actionPerformed(ActionEvent ae) {
+                int md = ae.getModifiers();
+                int expectedMask = ActionEvent.ALT_MASK | ActionEvent.CTRL_MASK
+                        | ActionEvent.SHIFT_MASK;
+
+                if ((md & expectedMask) != expectedMask) {
+
+                    robot.keyRelease(KeyEvent.VK_ALT);
+                    robot.keyRelease(KeyEvent.VK_SHIFT);
+                    robot.keyRelease(KeyEvent.VK_CONTROL);
+                    dispose();
+                    throw new RuntimeException("Action Event modifiers are not"
+                        + " set correctly.");
+                }
+            }
+        });
+
+        list.select(0);
+        robot.keyPress(KeyEvent.VK_ALT);
+        robot.keyPress(KeyEvent.VK_SHIFT);
+        robot.keyPress(KeyEvent.VK_CONTROL);
+        // Press Enter on list item, to generate action event.
+        robot.keyPress(KeyEvent.VK_ENTER);
+        robot.keyRelease(KeyEvent.VK_ENTER);
+        robot.waitForIdle();
+        robot.keyRelease(KeyEvent.VK_ALT);
+        robot.keyRelease(KeyEvent.VK_SHIFT);
+        robot.keyRelease(KeyEvent.VK_CONTROL);
+        robot.waitForIdle();
+    }
+
+    public static void main(String args[]) {
+       ActionEventTest test = new ActionEventTest();
+       test.performTest();
+       test.dispose();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/List/ItemEventTest/ItemEventTest.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,143 @@
+/*
+ * 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 8033936
+ *  @summary Verify that correct ItemEvent is received while selection &
+ *           deselection of multi select List items.
+ */
+
+import java.awt.AWTException;
+import java.awt.Event;
+import java.awt.FlowLayout;
+import java.awt.Frame;
+import java.awt.List;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.Robot;
+import java.awt.event.KeyEvent;
+import java.awt.event.InputEvent;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+
+public class ItemEventTest extends Frame
+{
+    List list;
+    final String expectedSelectionOrder;
+    StringBuilder actualSelectionOrder;
+    Robot robot;
+
+    public ItemEventTest()
+    {
+        try {
+            robot = new Robot();
+        } catch(AWTException e) {
+            throw new RuntimeException(e.getMessage());
+        }
+        expectedSelectionOrder = "01230123";
+
+        list = new List(4, true);
+        list.add("0");
+        list.add("1");
+        list.add("2");
+        list.add("3");
+
+        add(list);
+        setSize(400,400);
+        setLayout(new FlowLayout());
+        pack();
+        setVisible(true);
+        robot.waitForIdle();
+    }
+
+    @Override
+    public boolean handleEvent(Event e) {
+        if (e.target instanceof List) {
+            if (e.id == Event.LIST_DESELECT || e.id == Event.LIST_SELECT) {
+                actualSelectionOrder.append(e.arg);
+            }
+        }
+        return true;
+    }
+
+    void testHandleEvent() {
+        // When no ItemListener is added to List, parent's handleEvent is
+        // called with ItemEvent.
+        performTest();
+    }
+
+    void testItemListener() {
+        list.addItemListener(new ItemListener() {
+            @Override
+            public void itemStateChanged(ItemEvent ie) {
+                actualSelectionOrder.append(ie.getItem());
+            }
+        });
+        performTest();
+    }
+
+    void performTest() {
+        actualSelectionOrder = new StringBuilder();
+        Point loc = list.getLocationOnScreen();
+        Rectangle rect = list.getBounds();
+        int dY = rect.height / list.getItemCount();
+        loc = new Point(loc.x + 10, loc.y + 5);
+
+        String osName = System.getProperty("os.name");
+        boolean isMac = osName.contains("Mac") || osName.contains("mac");
+        if(isMac) {
+            robot.keyPress(KeyEvent.VK_META);
+        }
+
+        // First loop to select & Second loop to deselect the list items.
+        for (int j = 0; j < 2; ++j) {
+            for (int i = 0; i < list.getItemCount(); ++i) {
+                robot.mouseMove(loc.x, loc.y + i * dY);
+                robot.mousePress(InputEvent.BUTTON1_MASK);
+                robot.delay(100);
+                robot.mouseRelease(InputEvent.BUTTON1_MASK);
+                robot.waitForIdle();
+            }
+        }
+
+        if(isMac) {
+            robot.keyRelease(KeyEvent.VK_META);
+        }
+
+        if (!expectedSelectionOrder.equals(actualSelectionOrder.toString())) {
+            dispose();
+            throw new RuntimeException("ItemEvent for selection & deselection"
+                + " of multi select List's item is not correct"
+                + " Expected : " + expectedSelectionOrder
+                + " Actual : " + actualSelectionOrder);
+        }
+    }
+
+    public static void main(String args[]) {
+       ItemEventTest test = new ItemEventTest();
+       test.testHandleEvent();
+       test.testItemListener();
+       test.dispose();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/MenuBar/ActionEventTest/ActionEventTest.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,104 @@
+/*
+ * 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 6191390
+ * @summary Verify that ActionEvent is received with correct modifiers set.
+ * @run main/manual ActionEventTest
+ */
+
+import java.awt.Frame;
+import java.awt.Menu;
+import java.awt.MenuBar;
+import java.awt.MenuItem;
+import java.awt.TextArea;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+public final class ActionEventTest extends Frame {
+
+    MenuBar menuBar;
+    TextArea instructions;
+    public static boolean isProgInterruption = false;
+    static Thread mainThread = null;
+    static int sleepTime = 300000;
+
+    public ActionEventTest() {
+        menuBar = new MenuBar();
+        Menu menu = new Menu("Menu1");
+        MenuItem menuItem = new MenuItem("MenuItem");
+
+        menuItem.addActionListener(new ActionListener() {
+            @Override
+            public void actionPerformed(ActionEvent ae) {
+                System.out.println("actionPerformed");
+                int md = ae.getModifiers();
+                int expectedMask = ActionEvent.ALT_MASK | ActionEvent.CTRL_MASK
+                        | ActionEvent.SHIFT_MASK;
+
+                isProgInterruption = true;
+                mainThread.interrupt();
+                if ((md & expectedMask) != expectedMask) {
+                    throw new RuntimeException("Action Event modifiers are not"
+                        + " set correctly.");
+                }
+            }
+        });
+        menu.add(menuItem);
+        menuBar.add(menu);
+        setMenuBar(menuBar);
+
+        instructions = new TextArea(10, 50);
+        instructions.setText(
+        " This is a manual test\n" +
+        " Keep the Alt, Shift & Ctrl Keys pressed while doing next steps\n" +
+        " Click 'Menu1' Menu from the Menu Bar\n" +
+        " It will show 'MenuItem'\n" +
+        " Left mouse Click the 'MenuItem'\n" +
+        " Test exits automatically after mouse click.");
+        add(instructions);
+
+        setSize(400, 400);
+        setVisible(true);
+        validate();
+    }
+
+
+    public static void main(final String[] args) throws Exception {
+        mainThread = Thread.currentThread();
+        ActionEventTest test = new ActionEventTest();
+        try {
+            mainThread.sleep(sleepTime);
+        } catch (InterruptedException e) {
+            if (!isProgInterruption) {
+                throw e;
+            }
+        }
+        test.dispose();
+        if (!isProgInterruption) {
+            throw new RuntimeException("Timed out after " + sleepTime / 1000
+                    + " seconds");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/PrintJob/JobAttrUpdateTest.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,126 @@
+/*
+ * 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 6357905
+ * @summary  JobAttributes.getFromPage() and getToPage() always returns 1
+ * @run main/manual JobAttrUpdateTest
+ */
+import java.awt.BorderLayout;
+import java.awt.FlowLayout;
+import java.awt.JobAttributes;
+import java.awt.PrintJob;
+import java.awt.Toolkit;
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JTextArea;
+import javax.swing.SwingUtilities;
+
+public class JobAttrUpdateTest {
+
+    private static Thread mainThread;
+    private static boolean testPassed;
+    private static boolean testGeneratedInterrupt;
+
+    public static void main(String[] args) throws Exception {
+        SwingUtilities.invokeAndWait(() -> {
+            doTest(JobAttrUpdateTest::printTest);
+        });
+        mainThread = Thread.currentThread();
+        try {
+            Thread.sleep(30000);
+        } catch (InterruptedException e) {
+            if (!testPassed && testGeneratedInterrupt) {
+                throw new RuntimeException(""
+                        + "JobAttributes.getFromPage(),getToPage() not updated correctly");
+            }
+        }
+        if (!testGeneratedInterrupt) {
+            throw new RuntimeException("user has not executed the test");
+        }
+    }
+
+    private static void printTest() {
+        JobAttributes ja = new JobAttributes();
+
+        Toolkit tk = Toolkit.getDefaultToolkit();
+        // ja.setToPage(4);
+        // ja.setFromPage(3);
+        // show dialog
+        PrintJob pjob = tk.getPrintJob(new JFrame(), "test", ja, null);
+        if (pjob == null) {
+            return;
+        }
+
+
+        if (ja.getDefaultSelection() == JobAttributes.DefaultSelectionType.RANGE) {
+            int fromPage = ja.getFromPage();
+            int toPage = ja.getToPage();
+            if (fromPage != 2 || toPage != 3) {
+                fail();
+            } else {
+                pass();
+            }
+        }
+    }
+
+    public static synchronized void pass() {
+        testPassed = true;
+        testGeneratedInterrupt = true;
+        mainThread.interrupt();
+    }
+
+    public static synchronized void fail() {
+        testPassed = false;
+        testGeneratedInterrupt = true;
+        mainThread.interrupt();
+    }
+
+    private static void doTest(Runnable action) {
+        String description
+                = " A print dialog will be shown.\n "
+                + " Please select Pages within Page-range.\n"
+                + " and enter From 2 and To 3. Then Select OK.";
+
+        final JDialog dialog = new JDialog();
+        dialog.setTitle("JobAttribute Updation Test");
+        JTextArea textArea = new JTextArea(description);
+        textArea.setEditable(false);
+        final JButton testButton = new JButton("Start Test");
+
+        testButton.addActionListener((e) -> {
+            testButton.setEnabled(false);
+            action.run();
+        });
+        JPanel mainPanel = new JPanel(new BorderLayout());
+        mainPanel.add(textArea, BorderLayout.CENTER);
+        JPanel buttonPanel = new JPanel(new FlowLayout());
+        buttonPanel.add(testButton);
+        mainPanel.add(buttonPanel, BorderLayout.SOUTH);
+        dialog.add(mainPanel);
+        dialog.pack();
+        dialog.setVisible(true);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/TrayIcon/ActionEventTest/ActionEventTest.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,132 @@
+/*
+ * 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 6191390
+ * @summary Verify that ActionEvent is received with correct modifiers set.
+ * @library ../../../../lib/testlibrary ../
+ * @build ExtendedRobot SystemTrayIconHelper
+ */
+
+import java.awt.Image;
+import java.awt.TrayIcon;
+import java.awt.SystemTray;
+import java.awt.Robot;
+import java.awt.EventQueue;
+import java.awt.Point;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+import java.awt.image.BufferedImage;
+
+public class ActionEventTest {
+
+    Image image;
+    TrayIcon icon;
+    Robot robot;
+
+    public static void main(String[] args) throws Exception {
+        if (!SystemTray.isSupported()) {
+            System.out.println("SystemTray not supported on the platform." +
+                " Marking the test passed.");
+        } else {
+            if (System.getProperty("os.name").toLowerCase().startsWith("win")) {
+                System.err.println(
+                    "Test can fail on Windows platform\n"+
+                    "On Windows 7, by default icon hides behind icon pool\n" +
+                    "Due to which test might fail\n" +
+                    "Set \"Right mouse click\" -> " +
+                    "\"Customize notification icons\" -> \"Always show " +
+                    "all icons and notifications on the taskbar\" true " +
+                    "to avoid this problem.\nOR change behavior only for " +
+                    "Java SE tray icon and rerun test.");
+            }
+
+            ActionEventTest test = new ActionEventTest();
+            test.doTest();
+            test.clear();
+        }
+    }
+
+    public ActionEventTest() throws Exception {
+        robot = new Robot();
+        EventQueue.invokeAndWait(this::initializeGUI);
+    }
+
+    private void initializeGUI() {
+
+        icon = new TrayIcon(
+            new BufferedImage(20, 20, BufferedImage.TYPE_INT_RGB), "ti");
+        icon.addActionListener(new ActionListener() {
+            @Override
+            public void actionPerformed(ActionEvent ae) {
+                int md = ae.getModifiers();
+                int expectedMask = ActionEvent.ALT_MASK | ActionEvent.CTRL_MASK
+                        | ActionEvent.SHIFT_MASK;
+
+                if ((md & expectedMask) != expectedMask) {
+                    clear();
+                    throw new RuntimeException("Action Event modifiers are not"
+                        + " set correctly.");
+                }
+            }
+        });
+
+        try {
+            SystemTray.getSystemTray().add(icon);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public void clear() {
+        SystemTray.getSystemTray().remove(icon);
+    }
+
+    void doTest() throws Exception {
+        robot.keyPress(KeyEvent.VK_ALT);
+        robot.keyPress(KeyEvent.VK_SHIFT);
+        robot.keyPress(KeyEvent.VK_CONTROL);
+
+        Point iconPosition = SystemTrayIconHelper.getTrayIconLocation(icon);
+        if (iconPosition == null) {
+            throw new RuntimeException("Unable to find the icon location!");
+        }
+
+        robot.mouseMove(iconPosition.x, iconPosition.y);
+        robot.waitForIdle();
+
+        robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
+        robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
+        robot.delay(100);
+        robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
+        robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
+        robot.delay(100);
+        robot.waitForIdle();
+        robot.keyRelease(KeyEvent.VK_ALT);
+        robot.keyRelease(KeyEvent.VK_SHIFT);
+        robot.keyRelease(KeyEvent.VK_CONTROL);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/font/MonospacedGlyphWidth/MonospacedGlyphWidthTest.java	Wed Jul 05 21:37:42 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.
+ */
+
+/* @test
+ * @bug 8073400
+ * @summary Some Monospaced logical fonts have a different width
+ * @author Dmitry Markov
+ * @run main MonospacedGlyphWidthTest
+ */
+import java.awt.*;
+import java.awt.font.FontRenderContext;
+
+public class MonospacedGlyphWidthTest {
+    private static final int START_INDEX = 0x2018;
+    private static final int END_INDEX = 0x201F;
+
+    public static void main(String[] args) {
+        Font font = new Font(Font.MONOSPACED, Font.PLAIN, 12);
+        double width = getCharWidth(font, 'a');
+
+        for (int i = START_INDEX; i <= END_INDEX; i++) {
+            if (width != getCharWidth(font, (char)i)) {
+                throw new RuntimeException("Test Failed: characters have different width!");
+            }
+        }
+        System.out.println("Test Passed!");
+    }
+
+    private static double getCharWidth(Font font, char c) {
+        FontRenderContext fontRenderContext = new FontRenderContext(null, false, false);
+        return font.getStringBounds(new char[] {c}, 0, 1, fontRenderContext).getWidth();
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/image/RasterCreationTest.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,352 @@
+/*
+ * 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.awt.Point;
+import java.awt.image.DataBuffer;
+import java.awt.image.DataBufferByte;
+import java.awt.image.DataBufferDouble;
+import java.awt.image.DataBufferFloat;
+import java.awt.image.DataBufferInt;
+import java.awt.image.DataBufferShort;
+import java.awt.image.DataBufferUShort;
+import java.awt.image.Raster;
+import java.awt.image.SampleModel;
+import java.awt.image.MultiPixelPackedSampleModel;
+import java.awt.image.PixelInterleavedSampleModel;
+import java.awt.image.SinglePixelPackedSampleModel;
+
+/*
+ * @test
+ * @bug  6353518
+ * @summary  Test possible combinations of Raster creation
+ *           Test fails if any of Raster.createXXX() method throws exception.
+ */
+public class RasterCreationTest {
+
+    public static void main(String[] args) {
+
+        final int width = 10;
+        final int height = 5;
+        final int imageSize = width * height;
+        Point location = new Point(0, 0);
+        int[] bandOffsets = {0};
+        int[] bitMask = {0x00ff0000, 0x0000ff00, 0xff, 0x0};
+
+        SampleModel[] inputSampleModels = {
+            new PixelInterleavedSampleModel(DataBuffer.TYPE_BYTE,
+                    1, 1, 1, 1, bandOffsets),
+            new PixelInterleavedSampleModel(DataBuffer.TYPE_USHORT,
+                    1, 1, 1, 1, bandOffsets),
+            new PixelInterleavedSampleModel(DataBuffer.TYPE_INT,
+                    1, 1, 1, 1, bandOffsets),
+            new SinglePixelPackedSampleModel(DataBuffer.TYPE_BYTE,
+                    width, height, bitMask),
+            new SinglePixelPackedSampleModel(DataBuffer.TYPE_USHORT,
+                    width, height, bitMask),
+            new SinglePixelPackedSampleModel(DataBuffer.TYPE_INT,
+                    width, height, bitMask),
+            new MultiPixelPackedSampleModel(DataBuffer.TYPE_BYTE,
+                    width, height, 4),
+            new MultiPixelPackedSampleModel(DataBuffer.TYPE_USHORT,
+                    width, height, 2),
+            new MultiPixelPackedSampleModel(DataBuffer.TYPE_INT,
+                    width, height, 2)
+        };
+
+        // ---------------------------------------------------------------------
+        // Test ability to create Raster & WritableRaster with DataBuffer
+        // classes
+        // ---------------------------------------------------------------------
+        DataBuffer[] inputDataBuffer = {
+            new DataBufferByte(imageSize),
+            new DataBufferUShort(imageSize),
+            new DataBufferInt(imageSize, 1),
+            new DataBufferShort(imageSize),
+            new DataBufferFloat(imageSize),
+            new DataBufferDouble(imageSize)
+        };
+
+        for (SampleModel sm : inputSampleModels) {
+            for (DataBuffer db : inputDataBuffer) {
+                // Test Raster creation
+                Raster.createRaster(sm, db, location);
+
+                // Test writableRaster creation
+                Raster.createWritableRaster(sm, db, location);
+                Raster.createWritableRaster(sm, location);
+            }
+        }
+
+        // ---------------------------------------------------------------------
+        // Test ability to create Raster & WritableRaster with custom DataBuffer
+        // classes
+        // ---------------------------------------------------------------------
+        DataBuffer[] myDataBuffer = {
+            new MyDataBufferByte(imageSize),
+            new MyDataBufferUShort(imageSize),
+            new MyDataBufferInt(imageSize),
+            new MyDataBufferShort(imageSize),
+            new MyDataBufferDouble(imageSize),
+            new MyDataBufferFloat(imageSize)
+        };
+
+        for (SampleModel sm : inputSampleModels) {
+            for (DataBuffer db : myDataBuffer) {
+                // Test Raster creation
+                Raster.createRaster(sm, db, location);
+
+                // Test writableRaster creation
+                Raster.createWritableRaster(sm, db, location);
+                Raster.createWritableRaster(sm, location);
+            }
+        }
+
+        // ---------------------------------------------------------------------
+        // Test ability to create InterleavedRaster
+        // ---------------------------------------------------------------------
+        int[] interleavedInputDataTypes = {
+            DataBuffer.TYPE_BYTE,
+            DataBuffer.TYPE_USHORT
+        };
+
+        int numBands = 1;
+
+        for (int i : interleavedInputDataTypes) {
+            Raster.createInterleavedRaster(i, width, height, 1, location);
+            Raster.createInterleavedRaster(i, width, height, width * numBands,
+                    numBands, bandOffsets, location);
+        }
+
+        for (int i = 0; i < interleavedInputDataTypes.length ; i++) {
+            DataBuffer d1 = inputDataBuffer[i];
+            DataBuffer d2 = myDataBuffer[i];
+
+            Raster.createInterleavedRaster(d1, width, height, width * numBands,
+                    numBands, bandOffsets, location);
+            Raster.createInterleavedRaster(d2, width, height, width * numBands,
+                    numBands, bandOffsets, location);
+        }
+
+        // ---------------------------------------------------------------------
+        // Test ability to create BandedRaster
+        // ---------------------------------------------------------------------
+        int[] bankIndices = new int[numBands];
+        bankIndices[0] = 0;
+
+        int[] bandedInputDataTypes = {
+            DataBuffer.TYPE_BYTE,
+            DataBuffer.TYPE_USHORT,
+            DataBuffer.TYPE_INT
+        };
+
+        for (int i : bandedInputDataTypes) {
+            Raster.createBandedRaster(i, width, height, 1, location);
+            Raster.createBandedRaster(i, width, height, width,
+                    bankIndices, bandOffsets, location);
+        }
+
+        for (int i = 0; i < bandedInputDataTypes.length; i++) {
+            DataBuffer d1 = inputDataBuffer[i];
+            DataBuffer d2 = myDataBuffer[i];
+
+            Raster.createBandedRaster(d1, width, height, width,
+                    bankIndices, bandOffsets, location);
+            Raster.createBandedRaster(d2, width, height, width,
+                    bankIndices, bandOffsets, location);
+        }
+
+        // ---------------------------------------------------------------------
+        // Test ability to create PackedRaster
+        // ---------------------------------------------------------------------
+        int[] bandMasks = new int[numBands];
+        bandMasks[0] = 0;
+
+        int packedInputDataTypes[] = {
+            DataBuffer.TYPE_BYTE,
+            DataBuffer.TYPE_USHORT,
+            DataBuffer.TYPE_INT
+        };
+
+        for (int i : packedInputDataTypes) {
+            Raster.createPackedRaster(i, width, height, bandMasks, location);
+
+            for (int bits = 1; bits < 5; bits *= 2) {
+                Raster.createPackedRaster(i, width, height, 1, bits, location);
+            }
+        }
+
+        for (int i = 0; i < packedInputDataTypes.length; i++) {
+            DataBuffer d1 = inputDataBuffer[i];
+            DataBuffer d2 = myDataBuffer[i];
+
+            for (int bits = 1; bits < 5; bits *= 2) {
+                Raster.createPackedRaster(d1, width, height, bits, location);
+                Raster.createPackedRaster(d2, width, height, bits, location);
+            }
+
+            Raster.createPackedRaster(d1, width, height, 1,bandMasks, location);
+            Raster.createPackedRaster(d2, width, height, 1,bandMasks, location);
+        }
+    }
+}
+
+// ---------------------------------------------------------------------
+// Custom DataBuffer classes for testing purpose
+// ---------------------------------------------------------------------
+final class MyDataBufferByte extends DataBuffer {
+
+    byte[] data;
+    byte[][] bankdata;
+
+    public MyDataBufferByte(int size) {
+        super(TYPE_BYTE, size);
+        data = new byte[size];
+        bankdata = new byte[1][];
+        bankdata[0] = data;
+    }
+
+    @Override
+    public int getElem(int bank, int i) {
+        return bankdata[bank][i + offsets[bank]];
+    }
+
+    @Override
+    public void setElem(int bank, int i, int val) {
+        bankdata[bank][i + offsets[bank]] = (byte) val;
+    }
+}
+
+final class MyDataBufferDouble extends DataBuffer {
+
+    double[] data;
+    double[][] bankdata;
+
+    public MyDataBufferDouble(int size) {
+        super(TYPE_DOUBLE, size);
+        data = new double[size];
+        bankdata = new double[1][];
+        bankdata[0] = data;
+    }
+
+    @Override
+    public int getElem(int bank, int i) {
+        return (int) bankdata[bank][i + offsets[bank]];
+    }
+
+    @Override
+    public void setElem(int bank, int i, int val) {
+        bankdata[bank][i + offsets[bank]] = (double) val;
+    }
+}
+
+final class MyDataBufferFloat extends DataBuffer {
+
+    float[] data;
+    float[][] bankdata;
+
+    public MyDataBufferFloat(int size) {
+        super(TYPE_FLOAT, size);
+        data = new float[size];
+        bankdata = new float[1][];
+        bankdata[0] = data;
+    }
+
+    @Override
+    public int getElem(int bank, int i) {
+        return (int) bankdata[bank][i + offsets[bank]];
+    }
+
+    @Override
+    public void setElem(int bank, int i, int val) {
+        bankdata[bank][i + offsets[bank]] = (float) val;
+    }
+}
+
+final class MyDataBufferShort extends DataBuffer {
+
+    short[] data;
+    short[][] bankdata;
+
+    public MyDataBufferShort(int size) {
+        super(TYPE_SHORT, size);
+        data = new short[size];
+        bankdata = new short[1][];
+        bankdata[0] = data;
+    }
+
+    @Override
+    public int getElem(int bank, int i) {
+        return bankdata[bank][i + offsets[bank]];
+    }
+
+    @Override
+    public void setElem(int bank, int i, int val) {
+        bankdata[bank][i + offsets[bank]] = (short) val;
+    }
+}
+
+final class MyDataBufferUShort extends DataBuffer {
+
+    short[] data;
+    short[][] bankdata;
+
+    public MyDataBufferUShort(int size) {
+        super(TYPE_USHORT, size);
+        data = new short[size];
+        bankdata = new short[1][];
+        bankdata[0] = data;
+    }
+
+    @Override
+    public int getElem(int bank, int i) {
+        return bankdata[bank][i + offsets[bank]];
+    }
+
+    @Override
+    public void setElem(int bank, int i, int val) {
+        bankdata[bank][i + offsets[bank]] = (short) val;
+    }
+}
+
+final class MyDataBufferInt extends DataBuffer {
+
+    int[] data;
+    int[][] bankdata;
+
+    public MyDataBufferInt(int size) {
+        super(TYPE_INT, size);
+        data = new int[size];
+        bankdata = new int[1][];
+        bankdata[0] = data;
+    }
+
+    @Override
+    public int getElem(int bank, int i) {
+        return bankdata[bank][i + offsets[bank]];
+    }
+
+    @Override
+    public void setElem(int bank, int i, int val) {
+        bankdata[bank][i + offsets[bank]] = (int) val;
+    }
+}
--- a/jdk/test/java/awt/image/multiresolution/MultiResolutionTrayIconTest/MultiResolutionTrayIconTest.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/test/java/awt/image/multiresolution/MultiResolutionTrayIconTest/MultiResolutionTrayIconTest.java	Wed Jul 05 21:37:42 2017 +0200
@@ -24,8 +24,7 @@
 
 /*
   @test
-  @bug 8150176
-  @ignore 8150176
+  @bug 8150176 8151773
   @summary Check if correct resolution variant is used for tray icon.
   @author a.stepanov
   @run applet/manual=yesno MultiResolutionTrayIconTest.html
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/print/PrinterJob/DlgAttrsBug.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,152 @@
+/*
+ * 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 8061258
+ * @summary  PrinterJob's native Print Dialog does not reflect
+ *           specified Copies or Page Ranges
+ * @run main/manual DlgAttrsBug
+ */
+import java.awt.BorderLayout;
+import java.awt.FlowLayout;
+import java.awt.Graphics;
+import java.awt.print.PageFormat;
+import java.awt.print.Printable;
+import java.awt.print.PrinterException;
+import java.awt.print.PrinterJob;
+import javax.print.attribute.HashPrintRequestAttributeSet;
+import javax.print.attribute.PrintRequestAttributeSet;
+import javax.print.attribute.standard.Copies;
+import javax.print.attribute.standard.PageRanges;
+import javax.print.attribute.standard.DialogTypeSelection;
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JPanel;
+import javax.swing.JTextArea;
+import javax.swing.SwingUtilities;
+
+
+public class DlgAttrsBug implements Printable {
+    private static Thread mainThread;
+    private static boolean testPassed;
+    private static boolean testGeneratedInterrupt;
+
+    public static void main(String[] args)  throws Exception {
+        SwingUtilities.invokeAndWait(() -> {
+            doTest(DlgAttrsBug::printTest);
+        });
+        mainThread = Thread.currentThread();
+        try {
+            Thread.sleep(30000);
+        } catch (InterruptedException e) {
+            if (!testPassed && testGeneratedInterrupt) {
+                throw new RuntimeException("Print Dialog does not " +
+                          "reflect Copies or Page Ranges");
+            }
+        }
+        if (!testGeneratedInterrupt) {
+            throw new RuntimeException("user has not executed the test");
+        }
+    }
+
+    private static void printTest() {
+        PrinterJob job = PrinterJob.getPrinterJob();
+        if (job.getPrintService() == null) {
+            System.out.println("No printers. Test cannot continue");
+            return;
+        }
+        job.setPrintable(new DlgAttrsBug());
+        PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
+        aset.add(new Copies(5));
+        aset.add(new PageRanges(3,4));
+        aset.add(DialogTypeSelection.NATIVE);
+        job.printDialog(aset);
+    }
+
+    public static synchronized void pass() {
+        testPassed = true;
+        testGeneratedInterrupt = true;
+        mainThread.interrupt();
+    }
+
+    public static synchronized void fail() {
+        testPassed = false;
+        testGeneratedInterrupt = true;
+        mainThread.interrupt();
+    }
+
+    private static void doTest(Runnable action) {
+        String description
+                = " Visual inspection of print dialog is required.\n"
+                + " A print dialog will be shown.\n "
+                + " Please verify Copies 5 is selected.\n"
+                + " Also verify, Page Range is selected with "
+                + " from page 3 and to Page 4.\n"
+                + " If ok, press PASS else press FAIL";
+
+        final JDialog dialog = new JDialog();
+        dialog.setTitle("printSelectionTest");
+        JTextArea textArea = new JTextArea(description);
+        textArea.setEditable(false);
+        final JButton testButton = new JButton("Start Test");
+        final JButton passButton = new JButton("PASS");
+        passButton.setEnabled(false);
+        passButton.addActionListener((e) -> {
+            dialog.dispose();
+            pass();
+        });
+        final JButton failButton = new JButton("FAIL");
+        failButton.setEnabled(false);
+        failButton.addActionListener((e) -> {
+            dialog.dispose();
+            fail();
+        });
+        testButton.addActionListener((e) -> {
+            testButton.setEnabled(false);
+            action.run();
+            passButton.setEnabled(true);
+            failButton.setEnabled(true);
+        });
+        JPanel mainPanel = new JPanel(new BorderLayout());
+        mainPanel.add(textArea, BorderLayout.CENTER);
+        JPanel buttonPanel = new JPanel(new FlowLayout());
+        buttonPanel.add(testButton);
+        buttonPanel.add(passButton);
+        buttonPanel.add(failButton);
+        mainPanel.add(buttonPanel, BorderLayout.SOUTH);
+        dialog.add(mainPanel);
+        dialog.pack();
+        dialog.setVisible(true);
+    }
+
+    public int print(Graphics g, PageFormat pf, int pi)
+            throws PrinterException {
+        System.out.println("pi = " + pi);
+        if (pi >= 5) {
+            return NO_SUCH_PAGE;
+        }
+        g.drawString("Page : " + (pi+1), 200, 200);
+        return PAGE_EXISTS;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/print/PrinterJob/PrintAttributeUpdateTest.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,91 @@
+/*
+ * 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 8042713
+  @summary  Print Dialog does not update attribute set with page range
+  @run main/manual PrintAttributeUpdateTest
+ */
+import java.awt.Component;
+import java.awt.Graphics;
+import java.awt.print.PageFormat;
+import java.awt.print.Pageable;
+import java.awt.print.Printable;
+import java.awt.print.PrinterJob;
+import javax.print.attribute.Attribute;
+import javax.print.attribute.HashPrintRequestAttributeSet;
+import javax.print.attribute.standard.DialogTypeSelection;
+import javax.print.attribute.standard.PageRanges;
+import javax.swing.JOptionPane;
+import javax.swing.SwingUtilities;
+
+public class PrintAttributeUpdateTest implements Pageable, Printable {
+
+    public static void main(String args[]) throws Exception {
+        String[] instructions
+                = {
+                    "Select Pages Range From instead of All in print dialog. ",
+                    "Then select Print"
+                };
+        SwingUtilities.invokeAndWait(() -> {
+            JOptionPane.showMessageDialog((Component) null,
+                    instructions, "Instructions",
+                    JOptionPane.INFORMATION_MESSAGE);
+        });
+        HashPrintRequestAttributeSet as = new HashPrintRequestAttributeSet();
+        PrinterJob j = PrinterJob.getPrinterJob();
+        j.setPageable(new PrintAttributeUpdateTest());
+        as.add(DialogTypeSelection.NATIVE);
+        j.printDialog(as);
+        if (as.containsKey(PageRanges.class) == false) {
+            throw new RuntimeException("Print Dialog did not update "
+                    + " attribute set with page range");
+        }
+        Attribute attrs[] = as.toArray();
+        for (int i = 0; i < attrs.length; i++) {
+            System.out.println("attr " + attrs[i]);
+        }
+        j.print(as);
+    }
+
+    public int getNumberOfPages() {
+        return UNKNOWN_NUMBER_OF_PAGES;
+    }
+
+    public PageFormat getPageFormat(int pageIndex) {
+        PageFormat pf = new PageFormat();
+        return pf;
+    }
+
+    public Printable getPrintable(int pageIndex) {
+        return this;
+    }
+
+    public int print(Graphics g, PageFormat pgFmt, int pi) {
+        g.drawString("Page : " + (pi + 1), 200, 200);
+
+        return PAGE_EXISTS;
+    }
+
+}
--- a/jdk/test/java/awt/xembed/server/TestXEmbedServerJava.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/test/java/awt/xembed/server/TestXEmbedServerJava.java	Wed Jul 05 21:37:42 2017 +0200
@@ -76,7 +76,23 @@
     public Process startClient(Rectangle[] bounds, long window) {
         try {
             String java_home = System.getProperty("java.home");
-            return Runtime.getRuntime().exec(java_home + "/bin/java  -XaddExports:java.desktop/sun.awt.X11=ALL-UNNAMED  JavaClient " + window);
+            boolean hasModules = true;
+            try {
+                Class.class.getMethod("getModule");
+            }catch(Exception hasModulesEx) {
+                hasModules = false;
+            }
+            if (hasModules) {
+                System.out.println(java_home +
+                               "/bin/java  -XaddExports:java.desktop/sun.awt.X11=ALL-UNNAMED "+
+                               "-XaddExports:java.desktop/sun.awt=ALL-UNNAMED  JavaClient " + window);
+                return Runtime.getRuntime().exec(java_home +
+                               "/bin/java  -XaddExports:java.desktop/sun.awt.X11=ALL-UNNAMED "+
+                               "-XaddExports:java.desktop/sun.awt=ALL-UNNAMED  JavaClient " + window);
+            }else{
+                System.out.println(java_home + "/bin/java JavaClient " + window);
+                return Runtime.getRuntime().exec(java_home + "/bin/java JavaClient " + window);
+            }
         } catch (IOException ex1) {
             ex1.printStackTrace();
         }
--- a/jdk/test/java/lang/Class/GetPackageTest.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/test/java/lang/Class/GetPackageTest.java	Wed Jul 05 21:37:42 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
@@ -52,7 +52,7 @@
         assertEquals(fooClass.getClassLoader(), loader);
     }
 
-    @DataProvider(name = "testclasses")
+    @DataProvider(name = "testClasses")
     public Object[][] testClasses() {
         return new Object[][] {
                 // primitive type, void, array types
--- a/jdk/test/java/lang/StackWalker/DumpStackTest.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/test/java/lang/StackWalker/DumpStackTest.java	Wed Jul 05 21:37:42 2017 +0200
@@ -28,9 +28,6 @@
  *          This test should also been run against jdk9 successfully except of
  *          VM option MemberNameInStackFrame.
  * @run main/othervm DumpStackTest
- * @run main/othervm -Dstackwalk.newThrowable=false DumpStackTest
- * @run main/othervm -Dstackwalk.newThrowable=true -XX:-MemberNameInStackFrame DumpStackTest
- * @run main/othervm -Dstackwalk.newThrowable=true -XX:+MemberNameInStackFrame DumpStackTest
  */
 
 import java.lang.invoke.MethodHandle;
--- a/jdk/test/java/lang/StackWalker/GetCallerClassTest.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/test/java/lang/StackWalker/GetCallerClassTest.java	Wed Jul 05 21:37:42 2017 +0200
@@ -25,8 +25,7 @@
  * @test
  * @bug 8140450
  * @summary Basic test for StackWalker.getCallerClass()
- * @run main/othervm -XX:-MemberNameInStackFrame GetCallerClassTest
- * @run main/othervm -XX:+MemberNameInStackFrame GetCallerClassTest
+ * @run main/othervm GetCallerClassTest
  * @run main/othervm GetCallerClassTest sm
  */
 
--- a/jdk/test/java/lang/StackWalker/StackWalkTest.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/test/java/lang/StackWalker/StackWalkTest.java	Wed Jul 05 21:37:42 2017 +0200
@@ -44,10 +44,6 @@
  * @run main/othervm/java.security.policy=stackwalktest.policy StackWalkTest
  * @run main/othervm StackWalkTest -random:50
  * @run main/othervm/java.security.policy=stackwalktest.policy StackWalkTest -random:50
- * @run main/othervm -XX:-MemberNameInStackFrame -Dstackwalk.newThrowable=false StackWalkTest -random:50
- * @run main/othervm -XX:-MemberNameInStackFrame -Dstackwalk.newThrowable=true  StackWalkTest -random:50
- * @run main/othervm -XX:+MemberNameInStackFrame -Dstackwalk.newThrowable=false StackWalkTest -random:50
- * @run main/othervm -XX:+MemberNameInStackFrame -Dstackwalk.newThrowable=true  StackWalkTest -random:50
  * @author danielfuchs, bchristi
  * @key randomness
  */
--- a/jdk/test/java/lang/StackWalker/VerifyStackTrace.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/test/java/lang/StackWalker/VerifyStackTrace.java	Wed Jul 05 21:37:42 2017 +0200
@@ -40,8 +40,7 @@
  * @summary Verify stack trace information obtained with respect to StackWalker
  *          options, when the stack contains lambdas, method handle invoke
  *          virtual calls, and reflection.
- * @run main/othervm -XX:-MemberNameInStackFrame VerifyStackTrace
- * @run main/othervm -XX:+MemberNameInStackFrame VerifyStackTrace
+ * @run main/othervm VerifyStackTrace
  * @run main/othervm/java.security.policy=stackwalk.policy VerifyStackTrace
  * @author danielfuchs
  */
--- a/jdk/test/java/lang/invoke/LoopCombinatorTest.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/test/java/lang/invoke/LoopCombinatorTest.java	Wed Jul 05 21:37:42 2017 +0200
@@ -26,8 +26,12 @@
 /* @test
  * @bug 8139885
  * @bug 8150635
+ * @bug 8150956
  * @bug 8150957
+ * @bug 8152667
  * @bug 8153637
+ * @bug 8154751
+ * @bug 8154754
  * @run testng/othervm -ea -esa test.java.lang.invoke.LoopCombinatorTest
  */
 
@@ -266,6 +270,28 @@
     }
 
     @Test
+    public static void testWhileVoidInit() throws Throwable {
+        While w = new While();
+        int v = 5;
+        MethodHandle loop = MethodHandles.whileLoop(While.MH_voidInit.bindTo(w), While.MH_voidPred.bindTo(w),
+                While.MH_voidBody.bindTo(w));
+        assertEquals(While.MT_void, loop.type());
+        loop.invoke(v);
+        assertEquals(v, w.i);
+    }
+
+    @Test
+    public static void testDoWhileVoidInit() throws Throwable {
+        While w = new While();
+        int v = 5;
+        MethodHandle loop = MethodHandles.doWhileLoop(While.MH_voidInit.bindTo(w), While.MH_voidBody.bindTo(w),
+                While.MH_voidPred.bindTo(w));
+        assertEquals(While.MT_void, loop.type());
+        loop.invoke(v);
+        assertEquals(v, w.i);
+    }
+
+    @Test
     public static void testCountedLoop() throws Throwable {
         // String s = "Lambdaman!"; for (int i = 0; i < 13; ++i) { s = "na " + s; } return s; => a variation on a well known theme
         MethodHandle fit13 = MethodHandles.constant(int.class, 13);
@@ -275,6 +301,14 @@
     }
 
     @Test
+    public static void testCountedLoopVoidInit() throws Throwable {
+        MethodHandle fit5 = MethodHandles.constant(int.class, 5);
+        MethodHandle loop = MethodHandles.countedLoop(fit5, MethodHandles.zero(void.class), Counted.MH_printHello);
+        assertEquals(Counted.MT_countedPrinting, loop.type());
+        loop.invoke();
+    }
+
+    @Test
     public static void testCountedArrayLoop() throws Throwable {
         // int[] a = new int[]{0}; for (int i = 0; i < 13; ++i) { ++a[0]; } => a[0] == 13
         MethodHandle fit13 = MethodHandles.dropArguments(MethodHandles.constant(int.class, 13), 0, int[].class);
@@ -294,6 +328,74 @@
     }
 
     @Test
+    public static void testCountedLoopNullBody() throws Throwable {
+        MethodHandle h5 = MethodHandles.constant(int.class, 5);
+        MethodHandle h13 = MethodHandles.constant(int.class, 13);
+        MethodHandle loop = MethodHandles.countedLoop(h5, h13, null);
+        assertEquals(methodType(int.class), loop.type());
+        assertEquals(13, loop.invoke());
+    }
+
+    @Test
+    public static void testCountedLoopNullIterations() throws Throwable {
+        MethodHandle loop = MethodHandles.countedLoop(null, null, null);
+        assertEquals(methodType(void.class), loop.type());
+        loop.invoke();
+    }
+
+    @Test
+    public static void testCountedLoopNullInitAndBody() throws Throwable {
+        MethodHandle loop = MethodHandles.countedLoop(MethodHandles.constant(int.class, 5), null, null);
+        assertEquals(methodType(void.class), loop.type());
+        loop.invoke();
+    }
+
+    @DataProvider
+    static Object[][] countedLoopBodyParameters() {
+        return new Object[][] {
+                {methodType(String.class), methodType(String.class, int.class)},
+                {methodType(String.class, List.class), methodType(String.class, int.class)},
+                {methodType(String.class, List.class), methodType(String.class, int.class, String.class)}
+        };
+    }
+
+    @Test(dataProvider = "countedLoopBodyParameters")
+    public static void testCountedLoopBodyParameters(MethodType initType, MethodType bodyType) throws Throwable {
+        MethodHandle loop = MethodHandles.countedLoop(MethodHandles.constant(int.class, 5),
+                MethodHandles.empty(initType), MethodHandles.empty(bodyType));
+        assertEquals(initType, loop.type());
+    }
+
+    @DataProvider
+    static Object[][] countedLoopTypes() {
+        return new Object[][]{{void.class}, {int.class}, {Object.class}, {String.class}, {List.class}};
+    }
+
+    @Test(dataProvider = "countedLoopTypes")
+    public static void testCountedLoopBodyParametersNullInit(Class<?> t) throws Throwable {
+        MethodHandle loop = MethodHandles.countedLoop(MethodHandles.constant(int.class, 5), null,
+                MethodHandles.empty(methodType(t, int.class)));
+        assertEquals(methodType(t), loop.type());
+        loop.invoke();
+    }
+
+    @Test
+    public static void testCountedLoopStateDefinedByBody() throws Throwable {
+        MethodHandle loop = MethodHandles.countedLoop(MethodHandles.constant(int.class, 5), null, Counted.MH_stateBody);
+        assertEquals(Counted.MT_bodyDeterminesState, loop.type());
+        assertEquals("sssssnull01234", loop.invoke());
+    }
+
+    @Test
+    public static void testCountedLoopArgsDefinedByIterations() throws Throwable {
+        MethodHandle loop = MethodHandles.countedLoop(
+                MethodHandles.dropArguments(MethodHandles.constant(int.class, 3), 0, String.class),
+                null, Counted.MH_append);
+        assertEquals(Counted.MT_iterationsDefineArgs, loop.type());
+        assertEquals("hello012", loop.invoke("hello"));
+    }
+
+    @Test
     public static void testCountedRangeLoop() throws Throwable {
         // String s = "Lambdaman!"; for (int i = -5; i < 8; ++i) { s = "na " + s; } return s; => a well known theme
         MethodHandle fitm5 = MethodHandles.dropArguments(Counted.MH_m5, 0, String.class);
@@ -316,6 +418,23 @@
     }
 
     @Test
+    public static void testCountedLoopEmpty() throws Throwable {
+        // for (int i = 0; i < 5; ++i) { /* empty */ }
+        MethodHandle loop = MethodHandles.countedLoop(MethodHandles.constant(int.class, 5), null, null);
+        assertEquals(methodType(void.class), loop.type());
+        loop.invoke();
+    }
+
+    @Test
+    public static void testCountedRangeLoopEmpty() throws Throwable {
+        // for (int i = -5; i < 5; ++i) { /* empty */ }
+        MethodHandle loop = MethodHandles.countedLoop(MethodHandles.constant(int.class, -5),
+                MethodHandles.constant(int.class, 5), null, null);
+        assertEquals(methodType(void.class), loop.type());
+        loop.invoke();
+    }
+
+    @Test
     public static void testIterateSum() throws Throwable {
         // Integer[] a = new Integer[]{1,2,3,4,5,6}; int sum = 0; for (int e : a) { sum += e; } return sum; => 21
         MethodHandle loop = MethodHandles.iteratedLoop(Iterate.MH_sumIterator, Iterate.MH_sumInit, Iterate.MH_sumStep);
@@ -360,7 +479,8 @@
     public static void testIterateNullBody() {
         boolean caught = false;
         try {
-            MethodHandles.iteratedLoop(MethodHandles.identity(int.class), MethodHandles.identity(int.class), null);
+            MethodHandles.iteratedLoop(MethodHandles.empty(methodType(Iterator.class, int.class)),
+                    MethodHandles.identity(int.class), null);
         } catch (IllegalArgumentException iae) {
             assertEquals("iterated loop body must not be null", iae.getMessage());
             caught = true;
@@ -368,6 +488,102 @@
         assertTrue(caught);
     }
 
+    @DataProvider
+    static Object[][] wrongIteratorTypes() {
+        return new Object[][]{{void.class}, {Object.class}, {Iterable.class}};
+    }
+
+    @Test(dataProvider = "wrongIteratorTypes")
+    public static void testIterateVoidIterator(Class<?> it) {
+        boolean caught = false;
+        MethodType v = methodType(it);
+        try {
+            MethodHandles.iteratedLoop(MethodHandles.empty(v), null, MethodHandles.empty(v));
+        } catch(IllegalArgumentException iae) {
+            assertEquals("iteratedLoop first argument must have Iterator return type", iae.getMessage());
+            caught = true;
+        }
+        assertTrue(caught);
+    }
+
+    @Test
+    public static void testIterateVoidInit() throws Throwable {
+        MethodHandle loop = MethodHandles.iteratedLoop(null, Iterate.MH_voidInit, Iterate.MH_printStep);
+        assertEquals(Iterate.MT_print, loop.type());
+        loop.invoke(Arrays.asList("hello", "world"));
+    }
+
+    @DataProvider
+    static Object[][] iterateParameters() {
+        MethodType i = methodType(int.class);
+        MethodType sil_i = methodType(int.class, String.class, int.class, List.class);
+        MethodType sl_v = methodType(void.class, String.class, List.class);
+        MethodType l_it = methodType(Iterator.class, List.class);
+        MethodType li_it = methodType(Iterator.class, List.class, int.class);
+        MethodType l_i = methodType(int.class, List.class);
+        MethodType _it = methodType(Iterator.class);
+        MethodType si_i = methodType(int.class, String.class, int.class);
+        MethodType s_i = methodType(int.class, String.class);
+        return new Object[][]{
+                {null, null, sl_v},
+                {null, i, sil_i},
+                {null, l_i, sil_i},
+                {l_it, null, sl_v},
+                {l_it, i, sil_i},
+                {li_it, l_i, sil_i},
+                {l_it, null, sil_i},
+                {li_it, null, sl_v},
+                {_it, l_i, si_i},
+                {_it, l_i, s_i}
+        };
+    }
+
+    @Test(dataProvider = "iterateParameters")
+    public static void testIterateParameters(MethodType it, MethodType in, MethodType bo) throws Throwable {
+        MethodHandle iterator = it == null ? null : MethodHandles.empty(it);
+        MethodHandle init = in == null ? null : MethodHandles.empty(in);
+        MethodHandle loop = MethodHandles.iteratedLoop(iterator, init, MethodHandles.empty(bo));
+        MethodType lt = loop.type();
+        if (it == null && in == null) {
+            assertEquals(bo.dropParameterTypes(0, 1), lt);
+        } else if (it == null) {
+            if (in.parameterCount() == 0) {
+                assertEquals(bo.dropParameterTypes(0, in.returnType() == void.class ? 1 : 2), lt);
+            } else {
+                assertEquals(methodType(bo.returnType(), in.parameterArray()), lt);
+            }
+        } else if (in == null) {
+            assertEquals(methodType(bo.returnType(), it.parameterArray()), lt);
+        } else if (it.parameterCount() > in.parameterCount()) {
+            assertEquals(methodType(bo.returnType(), it.parameterArray()), lt);
+        } else if (it.parameterCount() < in.parameterCount()) {
+            assertEquals(methodType(bo.returnType(), in.parameterArray()), lt);
+        } else {
+            // both it, in present; with equal parameter list lengths
+            assertEquals(it.parameterList(), lt.parameterList());
+            assertEquals(in.parameterList(), lt.parameterList());
+            assertEquals(bo.returnType(), lt.returnType());
+        }
+    }
+
+    @Test
+    public static void testIteratorSubclass() throws Throwable {
+        MethodHandle loop = MethodHandles.iteratedLoop(MethodHandles.empty(methodType(BogusIterator.class, List.class)),
+                null, MethodHandles.empty(methodType(void.class, String.class)));
+        assertEquals(methodType(void.class, List.class), loop.type());
+    }
+
+    static class BogusIterator implements Iterator {
+        @Override
+        public boolean hasNext() {
+            return false;
+        }
+        @Override
+        public Object next() {
+            return null;
+        }
+    }
+
     static class Empty {
 
         static void f() { }
@@ -604,6 +820,10 @@
 
         private int i = 0;
 
+        void voidInit(int k) {
+            // empty
+        }
+
         void voidBody(int k) {
             ++i;
         }
@@ -623,6 +843,7 @@
         static final MethodType MT_zipInitZip = methodType(List.class, Iterator.class, Iterator.class);
         static final MethodType MT_zipPred = methodType(boolean.class, List.class, Iterator.class, Iterator.class);
         static final MethodType MT_zipStep = methodType(List.class, List.class, Iterator.class, Iterator.class);
+        static final MethodType MT_voidInit = methodType(void.class, int.class);
         static final MethodType MT_voidBody = methodType(void.class, int.class);
         static final MethodType MT_voidPred = methodType(boolean.class, int.class);
 
@@ -635,6 +856,7 @@
         static final MethodHandle MH_zipInitZip;
         static final MethodHandle MH_zipPred;
         static final MethodHandle MH_zipStep;
+        static final MethodHandle MH_voidInit;
         static final MethodHandle MH_voidBody;
         static final MethodHandle MH_voidPred;
 
@@ -654,6 +876,7 @@
                 MH_zipInitZip = LOOKUP.findStatic(WHILE, "zipInitZip", MT_zipInitZip);
                 MH_zipPred = LOOKUP.findStatic(WHILE, "zipPred", MT_zipPred);
                 MH_zipStep = LOOKUP.findStatic(WHILE, "zipStep", MT_zipStep);
+                MH_voidInit = LOOKUP.findVirtual(WHILE, "voidInit", MT_voidInit);
                 MH_voidBody = LOOKUP.findVirtual(WHILE, "voidBody", MT_voidBody);
                 MH_voidPred = LOOKUP.findVirtual(WHILE, "voidPred", MT_voidPred);
             } catch (Exception e) {
@@ -685,6 +908,17 @@
             return x + counter;
         }
 
+        static String stateBody(int counter, String s) {
+            return "s" + s + counter;
+        }
+
+        static String append(int counter, String localState, String loopArg) {
+            if (null == localState) {
+                return loopArg + counter;
+            }
+            return localState + counter;
+        }
+
         static final Class<Counted> COUNTED = Counted.class;
 
         static final MethodType MT_start = methodType(String.class, String.class);
@@ -692,6 +926,8 @@
         static final MethodType MT_stepUpdateArray = methodType(void.class, int.class, int[].class);
         static final MethodType MT_printHello = methodType(void.class, int.class);
         static final MethodType MT_addCounter = methodType(int.class, int.class, int.class);
+        static final MethodType MT_stateBody = methodType(String.class, int.class, String.class);
+        static final MethodType MT_append = methodType(String.class, int.class, String.class, String.class);
 
         static final MethodHandle MH_13;
         static final MethodHandle MH_m5;
@@ -701,11 +937,15 @@
         static final MethodHandle MH_stepUpdateArray;
         static final MethodHandle MH_printHello;
         static final MethodHandle MH_addCounter;
+        static final MethodHandle MH_stateBody;
+        static final MethodHandle MH_append;
 
         static final MethodType MT_counted = methodType(String.class, String.class);
         static final MethodType MT_arrayCounted = methodType(void.class, int[].class);
         static final MethodType MT_countedPrinting = methodType(void.class);
         static final MethodType MT_counterInit = methodType(int.class);
+        static final MethodType MT_bodyDeterminesState = methodType(String.class);
+        static final MethodType MT_iterationsDefineArgs = methodType(String.class, String.class);
 
         static {
             try {
@@ -717,6 +957,8 @@
                 MH_stepUpdateArray = LOOKUP.findStatic(COUNTED, "stepUpdateArray", MT_stepUpdateArray);
                 MH_printHello = LOOKUP.findStatic(COUNTED, "printHello", MT_printHello);
                 MH_addCounter = LOOKUP.findStatic(COUNTED, "addCounter", MT_addCounter);
+                MH_stateBody = LOOKUP.findStatic(COUNTED, "stateBody", MT_stateBody);
+                MH_append = LOOKUP.findStatic(COUNTED, "append", MT_append);
             } catch (Exception e) {
                 throw new ExceptionInInitializerError(e);
             }
@@ -768,6 +1010,10 @@
             System.out.print(s);
         }
 
+        static void voidInit() {
+            // empty
+        }
+
         static final Class<Iterate> ITERATE = Iterate.class;
 
         static final MethodType MT_sumIterator = methodType(Iterator.class, Integer[].class);
@@ -783,6 +1029,8 @@
         static final MethodType MT_mapStep = methodType(List.class, String.class, List.class, List.class);
         static final MethodType MT_printStep = methodType(void.class, String.class, List.class);
 
+        static final MethodType MT_voidInit = methodType(void.class);
+
         static final MethodHandle MH_sumIterator;
         static final MethodHandle MH_sumInit;
         static final MethodHandle MH_sumStep;
@@ -797,6 +1045,8 @@
         static final MethodHandle MH_mapInit;
         static final MethodHandle MH_mapStep;
 
+        static final MethodHandle MH_voidInit;
+
         static final MethodType MT_sum = methodType(int.class, Integer[].class);
         static final MethodType MT_reverse = methodType(List.class, List.class);
         static final MethodType MT_length = methodType(int.class, List.class);
@@ -815,6 +1065,7 @@
                 MH_mapInit = LOOKUP.findStatic(ITERATE, "mapInit", MT_mapInit);
                 MH_mapStep = LOOKUP.findStatic(ITERATE, "mapStep", MT_mapStep);
                 MH_printStep = LOOKUP.findStatic(ITERATE, "printStep", MT_printStep);
+                MH_voidInit = LOOKUP.findStatic(ITERATE, "voidInit", MT_voidInit);
             } catch (Exception e) {
                 throw new ExceptionInInitializerError(e);
             }
--- a/jdk/test/java/net/NetworkInterface/NetworkInterfaceStreamTest.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/test/java/net/NetworkInterface/NetworkInterfaceStreamTest.java	Wed Jul 05 21:37:42 2017 +0200
@@ -28,7 +28,6 @@
  * @build java.base/java.util.stream.OpTestCase
  * @run testng/othervm NetworkInterfaceStreamTest
  * @run testng/othervm -Djava.net.preferIPv4Stack=true NetworkInterfaceStreamTest
- * @key intermittent
  */
 
 import org.testng.annotations.Test;
@@ -52,21 +51,27 @@
     public void testNetworkInterfaces() throws SocketException {
         Supplier<Stream<NetworkInterface>> ss = () -> {
             try {
-                return NetworkInterface.networkInterfaces();
+                return NetworkInterface.networkInterfaces()
+                        .filter(ni -> isIncluded(ni));
             }
             catch (SocketException e) {
                 throw new RuntimeException(e);
             }
         };
 
-        Collection<NetworkInterface> expected = Collections.list(NetworkInterface.getNetworkInterfaces());
+        Collection<NetworkInterface> enums = Collections.list(NetworkInterface.getNetworkInterfaces());
+        Collection<NetworkInterface> expected = new ArrayList<>();
+        enums.forEach(ni -> {
+            if (isIncluded(ni)) {
+                expected.add(ni);
+            }
+        });
         withData(TestData.Factory.ofSupplier("Top-level network interfaces", ss))
                 .stream(s -> s)
                 .expectedResult(expected)
                 .exercise();
     }
 
-
     private Collection<NetworkInterface> getAllNetworkInterfaces() throws SocketException {
         Collection<NetworkInterface> anis = new ArrayList<>();
         for (NetworkInterface ni : Collections.list(NetworkInterface.getNetworkInterfaces())) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/http2/HpackDriver.java	Wed Jul 05 21:37:42 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
+ * @bug 8153353
+ * @modules java.httpclient/sun.net.httpclient.hpack
+ * @key randomness
+ * @compile/module=java.httpclient sun/net/httpclient/hpack/SpecHelper.java
+ * @compile/module=java.httpclient sun/net/httpclient/hpack/TestHelper.java
+ * @compile/module=java.httpclient sun/net/httpclient/hpack/BuffersTestingKit.java
+ * @run testng/othervm -XaddReads:java.httpclient=ALL-UNNAMED java.httpclient/sun.net.httpclient.hpack.BinaryPrimitivesTest
+ * @run testng/othervm -XaddReads:java.httpclient=ALL-UNNAMED java.httpclient/sun.net.httpclient.hpack.CircularBufferTest
+ * @run testng/othervm -XaddReads:java.httpclient=ALL-UNNAMED java.httpclient/sun.net.httpclient.hpack.DecoderTest
+ * @run testng/othervm -XaddReads:java.httpclient=ALL-UNNAMED java.httpclient/sun.net.httpclient.hpack.EncoderTest
+ * @run testng/othervm -XaddReads:java.httpclient=ALL-UNNAMED java.httpclient/sun.net.httpclient.hpack.HeaderTableTest
+ * @run testng/othervm -XaddReads:java.httpclient=ALL-UNNAMED java.httpclient/sun.net.httpclient.hpack.HuffmanTest
+ * @run testng/othervm -XaddReads:java.httpclient=ALL-UNNAMED java.httpclient/sun.net.httpclient.hpack.TestHelper
+ */
+public class HpackDriver { }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/http2/java.httpclient/sun/net/httpclient/hpack/BinaryPrimitivesTest.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,347 @@
+/*
+ * 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.net.httpclient.hpack;
+
+import org.testng.annotations.Test;
+
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.fail;
+import static sun.net.httpclient.hpack.BuffersTestingKit.*;
+import static sun.net.httpclient.hpack.TestHelper.newRandom;
+
+//
+// Some of the tests below overlap in what they test. This allows to diagnose
+// bugs quicker and with less pain by simply ruling out common working bits.
+//
+public final class BinaryPrimitivesTest {
+
+    private final Random rnd = newRandom();
+
+    @Test
+    public void integerRead1() {
+        verifyRead(bytes(0b00011111, 0b10011010, 0b00001010), 1337, 5);
+    }
+
+    @Test
+    public void integerRead2() {
+        verifyRead(bytes(0b00001010), 10, 5);
+    }
+
+    @Test
+    public void integerRead3() {
+        verifyRead(bytes(0b00101010), 42, 8);
+    }
+
+    @Test
+    public void integerWrite1() {
+        verifyWrite(bytes(0b00011111, 0b10011010, 0b00001010), 1337, 5);
+    }
+
+    @Test
+    public void integerWrite2() {
+        verifyWrite(bytes(0b00001010), 10, 5);
+    }
+
+    @Test
+    public void integerWrite3() {
+        verifyWrite(bytes(0b00101010), 42, 8);
+    }
+
+    //
+    // Since readInteger(x) is the inverse of writeInteger(x), thus:
+    //
+    // for all x: readInteger(writeInteger(x)) == x
+    //
+    @Test
+    public void integerIdentity() {
+        final int MAX_VALUE = 1 << 22;
+        int totalCases = 0;
+        int maxFilling = 0;
+        IntegerReader r = new IntegerReader();
+        IntegerWriter w = new IntegerWriter();
+        ByteBuffer buf = ByteBuffer.allocate(8);
+        for (int N = 1; N < 9; N++) {
+            for (int expected = 0; expected <= MAX_VALUE; expected++) {
+                w.reset().configure(expected, N, 1).write(buf);
+                buf.flip();
+                totalCases++;
+                maxFilling = Math.max(maxFilling, buf.remaining());
+                r.reset().configure(N).read(buf);
+                assertEquals(r.get(), expected);
+                buf.clear();
+            }
+        }
+        System.out.printf("totalCases: %,d, maxFilling: %,d, maxValue: %,d%n",
+                totalCases, maxFilling, MAX_VALUE);
+    }
+
+    @Test
+    public void integerReadChunked() {
+        final int NUM_TESTS = 1024;
+        IntegerReader r = new IntegerReader();
+        ByteBuffer bb = ByteBuffer.allocate(8);
+        IntegerWriter w = new IntegerWriter();
+        for (int i = 0; i < NUM_TESTS; i++) {
+            final int N = 1 + rnd.nextInt(8);
+            final int expected = rnd.nextInt(Integer.MAX_VALUE) + 1;
+            w.reset().configure(expected, N, rnd.nextInt()).write(bb);
+            bb.flip();
+
+            forEachSplit(bb,
+                    (buffers) -> {
+                        Iterable<? extends ByteBuffer> buf = relocateBuffers(injectEmptyBuffers(buffers));
+                        r.configure(N);
+                        for (ByteBuffer b : buf) {
+                            r.read(b);
+                        }
+                        assertEquals(r.get(), expected);
+                        r.reset();
+                    });
+            bb.clear();
+        }
+    }
+
+    // FIXME: use maxValue in the test
+
+    @Test
+    // FIXME: tune values for better coverage
+    public void integerWriteChunked() {
+        ByteBuffer bb = ByteBuffer.allocate(6);
+        IntegerWriter w = new IntegerWriter();
+        IntegerReader r = new IntegerReader();
+        for (int i = 0; i < 1024; i++) { // number of tests
+            final int N = 1 + rnd.nextInt(8);
+            final int payload = rnd.nextInt(255);
+            final int expected = rnd.nextInt(Integer.MAX_VALUE) + 1;
+
+            forEachSplit(bb,
+                    (buffers) -> {
+                        List<ByteBuffer> buf = new ArrayList<>();
+                        relocateBuffers(injectEmptyBuffers(buffers)).forEach(buf::add);
+                        boolean written = false;
+                        w.configure(expected, N, payload); // TODO: test for payload it can be read after written
+                        for (ByteBuffer b : buf) {
+                            int pos = b.position();
+                            written = w.write(b);
+                            b.position(pos);
+                        }
+                        if (!written) {
+                            fail("please increase bb size");
+                        }
+                        r.configure(N).read(concat(buf));
+                        // TODO: check payload here
+                        assertEquals(r.get(), expected);
+                        w.reset();
+                        r.reset();
+                        bb.clear();
+                    });
+        }
+    }
+
+
+    //
+    // Since readString(x) is the inverse of writeString(x), thus:
+    //
+    // for all x: readString(writeString(x)) == x
+    //
+    @Test
+    public void stringIdentity() {
+        final int MAX_STRING_LENGTH = 4096;
+        ByteBuffer bytes = ByteBuffer.allocate(MAX_STRING_LENGTH + 6); // it takes 6 bytes to encode string length of Integer.MAX_VALUE
+        CharBuffer chars = CharBuffer.allocate(MAX_STRING_LENGTH);
+        StringReader reader = new StringReader();
+        StringWriter writer = new StringWriter();
+        for (int len = 0; len <= MAX_STRING_LENGTH; len++) {
+            for (int i = 0; i < 64; i++) {
+                // not so much "test in isolation", I know... we're testing .reset() as well
+                bytes.clear();
+                chars.clear();
+
+                byte[] b = new byte[len];
+                rnd.nextBytes(b);
+
+                String expected = new String(b, StandardCharsets.ISO_8859_1); // reference string
+
+                boolean written = writer
+                        .configure(CharBuffer.wrap(expected), 0, expected.length(), false)
+                        .write(bytes);
+
+                if (!written) {
+                    fail("please increase 'bytes' size");
+                }
+                bytes.flip();
+                reader.read(bytes, chars);
+                chars.flip();
+                assertEquals(chars.toString(), expected);
+                reader.reset();
+                writer.reset();
+            }
+        }
+    }
+
+//    @Test
+//    public void huffmanStringWriteChunked() {
+//        fail();
+//    }
+//
+//    @Test
+//    public void huffmanStringReadChunked() {
+//        fail();
+//    }
+
+    @Test
+    public void stringWriteChunked() {
+        final int MAX_STRING_LENGTH = 8;
+        final ByteBuffer bytes = ByteBuffer.allocate(MAX_STRING_LENGTH + 6);
+        final CharBuffer chars = CharBuffer.allocate(MAX_STRING_LENGTH);
+        final StringReader reader = new StringReader();
+        final StringWriter writer = new StringWriter();
+        for (int len = 0; len <= MAX_STRING_LENGTH; len++) {
+
+            byte[] b = new byte[len];
+            rnd.nextBytes(b);
+
+            String expected = new String(b, StandardCharsets.ISO_8859_1); // reference string
+
+            forEachSplit(bytes, (buffers) -> {
+                writer.configure(expected, 0, expected.length(), false);
+                boolean written = false;
+                for (ByteBuffer buf : buffers) {
+                    int p0 = buf.position();
+                    written = writer.write(buf);
+                    buf.position(p0);
+                }
+                if (!written) {
+                    fail("please increase 'bytes' size");
+                }
+                reader.read(concat(buffers), chars);
+                chars.flip();
+                assertEquals(chars.toString(), expected);
+                reader.reset();
+                writer.reset();
+                chars.clear();
+                bytes.clear();
+            });
+        }
+    }
+
+    @Test
+    public void stringReadChunked() {
+        final int MAX_STRING_LENGTH = 16;
+        final ByteBuffer bytes = ByteBuffer.allocate(MAX_STRING_LENGTH + 6);
+        final CharBuffer chars = CharBuffer.allocate(MAX_STRING_LENGTH);
+        final StringReader reader = new StringReader();
+        final StringWriter writer = new StringWriter();
+        for (int len = 0; len <= MAX_STRING_LENGTH; len++) {
+
+            byte[] b = new byte[len];
+            rnd.nextBytes(b);
+
+            String expected = new String(b, StandardCharsets.ISO_8859_1); // reference string
+
+            boolean written = writer
+                    .configure(CharBuffer.wrap(expected), 0, expected.length(), false)
+                    .write(bytes);
+            writer.reset();
+
+            if (!written) {
+                fail("please increase 'bytes' size");
+            }
+            bytes.flip();
+
+            forEachSplit(bytes, (buffers) -> {
+                for (ByteBuffer buf : buffers) {
+                    int p0 = buf.position();
+                    reader.read(buf, chars);
+                    buf.position(p0);
+                }
+                chars.flip();
+                assertEquals(chars.toString(), expected);
+                reader.reset();
+                chars.clear();
+            });
+
+            bytes.clear();
+        }
+    }
+
+//    @Test
+//    public void test_Huffman_String_Identity() {
+//        StringWriter writer = new StringWriter();
+//        StringReader reader = new StringReader();
+//        // 256 * 8 gives 2048 bits in case of plain 8 bit coding
+//        // 256 * 30 gives you 7680 bits or 960 bytes in case of almost
+//        //          improbable event of 256 30 bits symbols in a row
+//        ByteBuffer binary = ByteBuffer.allocate(960);
+//        CharBuffer text = CharBuffer.allocate(960 / 5); // 5 = minimum code length
+//        for (int len = 0; len < 128; len++) {
+//            for (int i = 0; i < 256; i++) {
+//                // not so much "test in isolation", I know...
+//                binary.clear();
+//
+//                byte[] bytes = new byte[len];
+//                rnd.nextBytes(bytes);
+//
+//                String s = new String(bytes, StandardCharsets.ISO_8859_1);
+//
+//                writer.write(CharBuffer.wrap(s), binary, true);
+//                binary.flip();
+//                reader.read(binary, text);
+//                text.flip();
+//                assertEquals(text.toString(), s);
+//            }
+//        }
+//    }
+
+    // TODO: atomic failures: e.g. readonly/overflow
+
+    private static byte[] bytes(int... data) {
+        byte[] bytes = new byte[data.length];
+        for (int i = 0; i < data.length; i++) {
+            bytes[i] = (byte) data[i];
+        }
+        return bytes;
+    }
+
+    private static void verifyRead(byte[] data, int expected, int N) {
+        ByteBuffer buf = ByteBuffer.wrap(data, 0, data.length);
+        IntegerReader reader = new IntegerReader();
+        reader.configure(N).read(buf);
+        assertEquals(expected, reader.get());
+    }
+
+    private void verifyWrite(byte[] expected, int data, int N) {
+        IntegerWriter w = new IntegerWriter();
+        ByteBuffer buf = ByteBuffer.allocate(2 * expected.length);
+        w.configure(data, N, 1).write(buf);
+        buf.flip();
+        assertEquals(ByteBuffer.wrap(expected), buf);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/http2/java.httpclient/sun/net/httpclient/hpack/BuffersTestingKit.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,210 @@
+/*
+ * 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.net.httpclient.hpack;
+
+import java.nio.ByteBuffer;
+import java.util.*;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Supplier;
+
+import static java.nio.ByteBuffer.allocate;
+
+public final class BuffersTestingKit {
+
+    /**
+     * Relocates a {@code [position, limit)} region of the given buffer to
+     * corresponding region in a new buffer starting with provided {@code
+     * newPosition}.
+     *
+     * <p> Might be useful to make sure ByteBuffer's users do not rely on any
+     * absolute positions, but solely on what's reported by position(), limit().
+     *
+     * <p> The contents between the given buffer and the returned one are not
+     * shared.
+     */
+    public static ByteBuffer relocate(ByteBuffer buffer, int newPosition,
+                                      int newCapacity) {
+        int oldPosition = buffer.position();
+        int oldLimit = buffer.limit();
+
+        if (newPosition + oldLimit - oldPosition > newCapacity) {
+            throw new IllegalArgumentException();
+        }
+
+        ByteBuffer result;
+        if (buffer.isDirect()) {
+            result = ByteBuffer.allocateDirect(newCapacity);
+        } else {
+            result = allocate(newCapacity);
+        }
+
+        result.position(newPosition);
+        result.put(buffer).limit(result.position()).position(newPosition);
+        buffer.position(oldPosition);
+
+        if (buffer.isReadOnly()) {
+            return result.asReadOnlyBuffer();
+        }
+        return result;
+    }
+
+    public static Iterable<? extends ByteBuffer> relocateBuffers(
+            Iterable<? extends ByteBuffer> source) {
+        return () ->
+                new Iterator<ByteBuffer>() {
+
+                    private final Iterator<? extends ByteBuffer> it = source.iterator();
+
+                    @Override
+                    public boolean hasNext() {
+                        return it.hasNext();
+                    }
+
+                    @Override
+                    public ByteBuffer next() {
+                        ByteBuffer buf = it.next();
+                        int remaining = buf.remaining();
+                        int newCapacity = remaining + random.nextInt(17);
+                        int newPosition = random.nextInt(newCapacity - remaining + 1);
+                        return relocate(buf, newPosition, newCapacity);
+                    }
+                };
+    }
+
+    // TODO: not always of size 0 (it's fine for buffer to report !b.hasRemaining())
+    public static Iterable<? extends ByteBuffer> injectEmptyBuffers(
+            Iterable<? extends ByteBuffer> source) {
+        return injectEmptyBuffers(source, () -> allocate(0));
+    }
+
+    public static Iterable<? extends ByteBuffer> injectEmptyBuffers(
+            Iterable<? extends ByteBuffer> source,
+            Supplier<? extends ByteBuffer> emptyBufferFactory) {
+
+        return () ->
+                new Iterator<ByteBuffer>() {
+
+                    private final Iterator<? extends ByteBuffer> it = source.iterator();
+                    private ByteBuffer next = calculateNext();
+
+                    private ByteBuffer calculateNext() {
+                        if (random.nextBoolean()) {
+                            return emptyBufferFactory.get();
+                        } else if (it.hasNext()) {
+                            return it.next();
+                        } else {
+                            return null;
+                        }
+                    }
+
+                    @Override
+                    public boolean hasNext() {
+                        return next != null;
+                    }
+
+                    @Override
+                    public ByteBuffer next() {
+                        if (!hasNext()) {
+                            throw new NoSuchElementException();
+                        }
+                        ByteBuffer next = this.next;
+                        this.next = calculateNext();
+                        return next;
+                    }
+                };
+    }
+
+    public static ByteBuffer concat(Iterable<? extends ByteBuffer> split) {
+        return concat(split, ByteBuffer::allocate);
+    }
+
+    public static ByteBuffer concat(Iterable<? extends ByteBuffer> split,
+                                    Function<? super Integer, ? extends ByteBuffer> concatBufferFactory) {
+        int size = 0;
+        for (ByteBuffer bb : split) {
+            size += bb.remaining();
+        }
+
+        ByteBuffer result = concatBufferFactory.apply(size);
+        for (ByteBuffer bb : split) {
+            result.put(bb);
+        }
+
+        result.flip();
+        return result;
+    }
+
+    public static void forEachSplit(ByteBuffer bb,
+                                    Consumer<? super Iterable<? extends ByteBuffer>> action) {
+        forEachSplit(bb.remaining(),
+                (lengths) -> {
+                    int end = bb.position();
+                    List<ByteBuffer> buffers = new LinkedList<>();
+                    for (int len : lengths) {
+                        ByteBuffer d = bb.duplicate();
+                        d.position(end);
+                        d.limit(end + len);
+                        end += len;
+                        buffers.add(d);
+                    }
+                    action.accept(buffers);
+                });
+    }
+
+    private static void forEachSplit(int n, Consumer<? super Iterable<? extends Integer>> action) {
+        forEachSplit(n, new Stack<>(), action);
+    }
+
+    private static void forEachSplit(int n, Stack<Integer> path,
+                                     Consumer<? super Iterable<? extends Integer>> action) {
+        if (n == 0) {
+            action.accept(path);
+        } else {
+            for (int i = 1; i <= n; i++) {
+                path.push(i);
+                forEachSplit(n - i, path, action);
+                path.pop();
+            }
+        }
+    }
+
+    private static final Random random = new Random();
+
+    private BuffersTestingKit() {
+        throw new InternalError();
+    }
+
+//    public static void main(String[] args) {
+//
+//        List<ByteBuffer> buffers = Arrays.asList(
+//                (ByteBuffer) allocate(3).position(1).limit(2),
+//                allocate(0),
+//                allocate(7));
+//
+//        Iterable<? extends ByteBuffer> buf = relocateBuffers(injectEmptyBuffers(buffers));
+//        List<ByteBuffer> result = new ArrayList<>();
+//        buf.forEach(result::add);
+//        System.out.println(result);
+//    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/http2/java.httpclient/sun/net/httpclient/hpack/CircularBufferTest.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,125 @@
+/*
+ * 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 sun.net.httpclient.hpack;
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+import sun.net.httpclient.hpack.HeaderTable.CircularBuffer;
+
+import java.util.Queue;
+import java.util.Random;
+import java.util.concurrent.ArrayBlockingQueue;
+
+import static org.testng.Assert.assertEquals;
+import static sun.net.httpclient.hpack.TestHelper.newRandom;
+
+public final class CircularBufferTest {
+
+    private final Random r = newRandom();
+
+    @BeforeClass
+    public void setUp() {
+        r.setSeed(System.currentTimeMillis());
+    }
+
+    @Test
+    public void queue() {
+        for (int capacity = 1; capacity <= 2048; capacity++) {
+            queueOnce(capacity, 32);
+        }
+    }
+
+    @Test
+    public void resize() {
+        for (int capacity = 1; capacity <= 4096; capacity++) {
+            resizeOnce(capacity);
+        }
+    }
+
+    @Test
+    public void downSizeEmptyBuffer() {
+        CircularBuffer<Integer> buffer = new CircularBuffer<>(16);
+        buffer.resize(15);
+    }
+
+    private void resizeOnce(int capacity) {
+
+        int nextNumberToPut = 0;
+
+        Queue<Integer> referenceQueue = new ArrayBlockingQueue<>(capacity);
+        CircularBuffer<Integer> buffer = new CircularBuffer<>(capacity);
+
+        // Fill full, so the next add will wrap
+        for (int i = 0; i < capacity; i++, nextNumberToPut++) {
+            buffer.add(nextNumberToPut);
+            referenceQueue.add(nextNumberToPut);
+        }
+        int gets = r.nextInt(capacity); // [0, capacity)
+        for (int i = 0; i < gets; i++) {
+            referenceQueue.poll();
+            buffer.remove();
+        }
+        int puts = r.nextInt(gets + 1); // [0, gets]
+        for (int i = 0; i < puts; i++, nextNumberToPut++) {
+            buffer.add(nextNumberToPut);
+            referenceQueue.add(nextNumberToPut);
+        }
+
+        Integer[] expected = referenceQueue.toArray(new Integer[0]);
+        buffer.resize(expected.length);
+
+        assertEquals(buffer.elements, expected);
+    }
+
+    private void queueOnce(int capacity, int numWraps) {
+
+        Queue<Integer> referenceQueue = new ArrayBlockingQueue<>(capacity);
+        CircularBuffer<Integer> buffer = new CircularBuffer<>(capacity);
+
+        int nextNumberToPut = 0;
+        int totalPuts = 0;
+        int putsLimit = capacity * numWraps;
+        int remainingCapacity = capacity;
+        int size = 0;
+
+        while (totalPuts < putsLimit) {
+            assert remainingCapacity + size == capacity;
+            int puts = r.nextInt(remainingCapacity + 1); // [0, remainingCapacity]
+            remainingCapacity -= puts;
+            size += puts;
+            for (int i = 0; i < puts; i++, nextNumberToPut++) {
+                referenceQueue.add(nextNumberToPut);
+                buffer.add(nextNumberToPut);
+            }
+            totalPuts += puts;
+            int gets = r.nextInt(size + 1); // [0, size]
+            size -= gets;
+            remainingCapacity += gets;
+            for (int i = 0; i < gets; i++) {
+                Integer expected = referenceQueue.poll();
+                Integer actual = buffer.remove();
+                assertEquals(actual, expected);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/http2/java.httpclient/sun/net/httpclient/hpack/DecoderTest.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,595 @@
+/*
+ * 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.net.httpclient.hpack;
+
+import org.testng.annotations.Test;
+
+import java.io.UncheckedIOException;
+import java.net.ProtocolException;
+import java.nio.ByteBuffer;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static sun.net.httpclient.hpack.TestHelper.*;
+
+public final class DecoderTest {
+
+    //
+    // http://tools.ietf.org/html/rfc7541#appendix-C.2.1
+    //
+    @Test
+    public void example1() {
+        // @formatter:off
+        test("400a 6375 7374 6f6d 2d6b 6579 0d63 7573\n" +
+             "746f 6d2d 6865 6164 6572",
+
+             "[  1] (s =  55) custom-key: custom-header\n" +
+             "      Table size:  55",
+
+             "custom-key: custom-header");
+        // @formatter:on
+    }
+
+    //
+    // http://tools.ietf.org/html/rfc7541#appendix-C.2.2
+    //
+    @Test
+    public void example2() {
+        // @formatter:off
+        test("040c 2f73 616d 706c 652f 7061 7468",
+             "empty.",
+             ":path: /sample/path");
+        // @formatter:on
+    }
+
+    //
+    // http://tools.ietf.org/html/rfc7541#appendix-C.2.3
+    //
+    @Test
+    public void example3() {
+        // @formatter:off
+        test("1008 7061 7373 776f 7264 0673 6563 7265\n" +
+             "74",
+             "empty.",
+             "password: secret");
+        // @formatter:on
+    }
+
+    //
+    // http://tools.ietf.org/html/rfc7541#appendix-C.2.4
+    //
+    @Test
+    public void example4() {
+        // @formatter:off
+        test("82",
+             "empty.",
+             ":method: GET");
+        // @formatter:on
+    }
+
+    //
+    // http://tools.ietf.org/html/rfc7541#appendix-C.3
+    //
+    @Test
+    public void example5() {
+        // @formatter:off
+        Decoder d = new Decoder(256);
+
+        test(d, "8286 8441 0f77 7777 2e65 7861 6d70 6c65\n" +
+                "2e63 6f6d",
+
+                "[  1] (s =  57) :authority: www.example.com\n" +
+                "      Table size:  57",
+
+                ":method: GET\n" +
+                ":scheme: http\n" +
+                ":path: /\n" +
+                ":authority: www.example.com");
+
+        test(d, "8286 84be 5808 6e6f 2d63 6163 6865",
+
+                "[  1] (s =  53) cache-control: no-cache\n" +
+                "[  2] (s =  57) :authority: www.example.com\n" +
+                "      Table size: 110",
+
+                ":method: GET\n" +
+                ":scheme: http\n" +
+                ":path: /\n" +
+                ":authority: www.example.com\n" +
+                "cache-control: no-cache");
+
+        test(d, "8287 85bf 400a 6375 7374 6f6d 2d6b 6579\n" +
+                "0c63 7573 746f 6d2d 7661 6c75 65",
+
+                "[  1] (s =  54) custom-key: custom-value\n" +
+                "[  2] (s =  53) cache-control: no-cache\n" +
+                "[  3] (s =  57) :authority: www.example.com\n" +
+                "      Table size: 164",
+
+                ":method: GET\n" +
+                ":scheme: https\n" +
+                ":path: /index.html\n" +
+                ":authority: www.example.com\n" +
+                "custom-key: custom-value");
+
+        // @formatter:on
+    }
+
+    //
+    // http://tools.ietf.org/html/rfc7541#appendix-C.4
+    //
+    @Test
+    public void example6() {
+        // @formatter:off
+        Decoder d = new Decoder(256);
+
+        test(d, "8286 8441 8cf1 e3c2 e5f2 3a6b a0ab 90f4\n" +
+                "ff",
+
+                "[  1] (s =  57) :authority: www.example.com\n" +
+                "      Table size:  57",
+
+                ":method: GET\n" +
+                ":scheme: http\n" +
+                ":path: /\n" +
+                ":authority: www.example.com");
+
+        test(d, "8286 84be 5886 a8eb 1064 9cbf",
+
+                "[  1] (s =  53) cache-control: no-cache\n" +
+                "[  2] (s =  57) :authority: www.example.com\n" +
+                "      Table size: 110",
+
+                ":method: GET\n" +
+                ":scheme: http\n" +
+                ":path: /\n" +
+                ":authority: www.example.com\n" +
+                "cache-control: no-cache");
+
+        test(d, "8287 85bf 4088 25a8 49e9 5ba9 7d7f 8925\n" +
+                "a849 e95b b8e8 b4bf",
+
+                "[  1] (s =  54) custom-key: custom-value\n" +
+                "[  2] (s =  53) cache-control: no-cache\n" +
+                "[  3] (s =  57) :authority: www.example.com\n" +
+                "      Table size: 164",
+
+                ":method: GET\n" +
+                ":scheme: https\n" +
+                ":path: /index.html\n" +
+                ":authority: www.example.com\n" +
+                "custom-key: custom-value");
+        // @formatter:on
+    }
+
+    //
+    // http://tools.ietf.org/html/rfc7541#appendix-C.5
+    //
+    @Test
+    public void example7() {
+        // @formatter:off
+        Decoder d = new Decoder(256);
+
+        test(d, "4803 3330 3258 0770 7269 7661 7465 611d\n" +
+                "4d6f 6e2c 2032 3120 4f63 7420 3230 3133\n" +
+                "2032 303a 3133 3a32 3120 474d 546e 1768\n" +
+                "7474 7073 3a2f 2f77 7777 2e65 7861 6d70\n" +
+                "6c65 2e63 6f6d",
+
+                "[  1] (s =  63) location: https://www.example.com\n" +
+                "[  2] (s =  65) date: Mon, 21 Oct 2013 20:13:21 GMT\n" +
+                "[  3] (s =  52) cache-control: private\n" +
+                "[  4] (s =  42) :status: 302\n" +
+                "      Table size: 222",
+
+                ":status: 302\n" +
+                "cache-control: private\n" +
+                "date: Mon, 21 Oct 2013 20:13:21 GMT\n" +
+                "location: https://www.example.com");
+
+        test(d, "4803 3330 37c1 c0bf",
+
+                "[  1] (s =  42) :status: 307\n" +
+                "[  2] (s =  63) location: https://www.example.com\n" +
+                "[  3] (s =  65) date: Mon, 21 Oct 2013 20:13:21 GMT\n" +
+                "[  4] (s =  52) cache-control: private\n" +
+                "      Table size: 222",
+
+                ":status: 307\n" +
+                "cache-control: private\n" +
+                "date: Mon, 21 Oct 2013 20:13:21 GMT\n" +
+                "location: https://www.example.com");
+
+        test(d, "88c1 611d 4d6f 6e2c 2032 3120 4f63 7420\n" +
+                "3230 3133 2032 303a 3133 3a32 3220 474d\n" +
+                "54c0 5a04 677a 6970 7738 666f 6f3d 4153\n" +
+                "444a 4b48 514b 425a 584f 5157 454f 5049\n" +
+                "5541 5851 5745 4f49 553b 206d 6178 2d61\n" +
+                "6765 3d33 3630 303b 2076 6572 7369 6f6e\n" +
+                "3d31",
+
+                "[  1] (s =  98) set-cookie: foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1\n" +
+                "[  2] (s =  52) content-encoding: gzip\n" +
+                "[  3] (s =  65) date: Mon, 21 Oct 2013 20:13:22 GMT\n" +
+                "      Table size: 215",
+
+                ":status: 200\n" +
+                "cache-control: private\n" +
+                "date: Mon, 21 Oct 2013 20:13:22 GMT\n" +
+                "location: https://www.example.com\n" +
+                "content-encoding: gzip\n" +
+                "set-cookie: foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1");
+        // @formatter:on
+    }
+
+    //
+    // http://tools.ietf.org/html/rfc7541#appendix-C.6
+    //
+    @Test
+    public void example8() {
+        // @formatter:off
+        Decoder d = new Decoder(256);
+
+        test(d, "4882 6402 5885 aec3 771a 4b61 96d0 7abe\n" +
+                "9410 54d4 44a8 2005 9504 0b81 66e0 82a6\n" +
+                "2d1b ff6e 919d 29ad 1718 63c7 8f0b 97c8\n" +
+                "e9ae 82ae 43d3",
+
+                "[  1] (s =  63) location: https://www.example.com\n" +
+                "[  2] (s =  65) date: Mon, 21 Oct 2013 20:13:21 GMT\n" +
+                "[  3] (s =  52) cache-control: private\n" +
+                "[  4] (s =  42) :status: 302\n" +
+                "      Table size: 222",
+
+                ":status: 302\n" +
+                "cache-control: private\n" +
+                "date: Mon, 21 Oct 2013 20:13:21 GMT\n" +
+                "location: https://www.example.com");
+
+        test(d, "4883 640e ffc1 c0bf",
+
+                "[  1] (s =  42) :status: 307\n" +
+                "[  2] (s =  63) location: https://www.example.com\n" +
+                "[  3] (s =  65) date: Mon, 21 Oct 2013 20:13:21 GMT\n" +
+                "[  4] (s =  52) cache-control: private\n" +
+                "      Table size: 222",
+
+                ":status: 307\n" +
+                "cache-control: private\n" +
+                "date: Mon, 21 Oct 2013 20:13:21 GMT\n" +
+                "location: https://www.example.com");
+
+        test(d, "88c1 6196 d07a be94 1054 d444 a820 0595\n" +
+                "040b 8166 e084 a62d 1bff c05a 839b d9ab\n" +
+                "77ad 94e7 821d d7f2 e6c7 b335 dfdf cd5b\n" +
+                "3960 d5af 2708 7f36 72c1 ab27 0fb5 291f\n" +
+                "9587 3160 65c0 03ed 4ee5 b106 3d50 07",
+
+                "[  1] (s =  98) set-cookie: foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1\n" +
+                "[  2] (s =  52) content-encoding: gzip\n" +
+                "[  3] (s =  65) date: Mon, 21 Oct 2013 20:13:22 GMT\n" +
+                "      Table size: 215",
+
+                ":status: 200\n" +
+                "cache-control: private\n" +
+                "date: Mon, 21 Oct 2013 20:13:22 GMT\n" +
+                "location: https://www.example.com\n" +
+                "content-encoding: gzip\n" +
+                "set-cookie: foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1");
+        // @formatter:on
+    }
+
+    @Test
+    // One of responses from Apache Server that helped to catch a bug
+    public void testX() {
+        Decoder d = new Decoder(4096);
+        // @formatter:off
+        test(d, "3fe1 1f88 6196 d07a be94 03ea 693f 7504\n" +
+                "00b6 a05c b827 2e32 fa98 b46f 769e 86b1\n" +
+                "9272 b025 da5c 2ea9 fd70 a8de 7fb5 3556\n" +
+                "5ab7 6ece c057 02e2 2ad2 17bf 6c96 d07a\n" +
+                "be94 0854 cb6d 4a08 0075 40bd 71b6 6e05\n" +
+                "a531 68df 0f13 8efe 4522 cd32 21b6 5686\n" +
+                "eb23 781f cf52 848f d24a 8f0f 0d02 3435\n" +
+                "5f87 497c a589 d34d 1f",
+
+                "[  1] (s =  53) content-type: text/html\n" +
+                "[  2] (s =  50) accept-ranges: bytes\n" +
+                "[  3] (s =  74) last-modified: Mon, 11 Jun 2007 18:53:14 GMT\n" +
+                "[  4] (s =  77) server: Apache/2.4.17 (Unix) OpenSSL/1.0.2e-dev\n" +
+                "[  5] (s =  65) date: Mon, 09 Nov 2015 16:26:39 GMT\n" +
+                "      Table size: 319",
+
+                ":status: 200\n" +
+                "date: Mon, 09 Nov 2015 16:26:39 GMT\n" +
+                "server: Apache/2.4.17 (Unix) OpenSSL/1.0.2e-dev\n" +
+                "last-modified: Mon, 11 Jun 2007 18:53:14 GMT\n" +
+                "etag: \"2d-432a5e4a73a80\"\n" +
+                "accept-ranges: bytes\n" +
+                "content-length: 45\n" +
+                "content-type: text/html");
+        // @formatter:on
+    }
+
+    //
+    // This test is missing in the spec
+    //
+    @Test
+    public void sizeUpdate() {
+        Decoder d = new Decoder(4096);
+        assertEquals(d.getTable().maxSize(), 4096);
+        d.decode(ByteBuffer.wrap(new byte[]{0b00111110}), true, nopCallback()); // newSize = 30
+        assertEquals(d.getTable().maxSize(), 30);
+    }
+
+    @Test
+    public void incorrectSizeUpdate() {
+        ByteBuffer b = ByteBuffer.allocate(8);
+        Encoder e = new Encoder(8192) {
+            @Override
+            protected int calculateCapacity(int maxCapacity) {
+                return maxCapacity;
+            }
+        };
+        e.header("a", "b");
+        e.encode(b);
+        b.flip();
+        {
+            Decoder d = new Decoder(4096);
+            UncheckedIOException ex = assertVoidThrows(UncheckedIOException.class,
+                    () -> d.decode(b, true, (name, value) -> { }));
+
+            assertNotNull(ex.getCause());
+            assertEquals(ex.getCause().getClass(), ProtocolException.class);
+        }
+        b.flip();
+        {
+            Decoder d = new Decoder(4096);
+            UncheckedIOException ex = assertVoidThrows(UncheckedIOException.class,
+                    () -> d.decode(b, false, (name, value) -> { }));
+
+            assertNotNull(ex.getCause());
+            assertEquals(ex.getCause().getClass(), ProtocolException.class);
+        }
+    }
+
+    @Test
+    public void corruptedHeaderBlockInteger() {
+        Decoder d = new Decoder(4096);
+        ByteBuffer data = ByteBuffer.wrap(new byte[]{
+                (byte) 0b11111111, // indexed
+                (byte) 0b10011010  // 25 + ...
+        });
+        UncheckedIOException e = assertVoidThrows(UncheckedIOException.class,
+                () -> d.decode(data, true, nopCallback()));
+        assertNotNull(e.getCause());
+        assertEquals(e.getCause().getClass(), ProtocolException.class);
+        assertExceptionMessageContains(e, "Unexpected end of header block");
+    }
+
+    // 5.1.  Integer Representation
+    // ...
+    // Integer encodings that exceed implementation limits -- in value or octet
+    // length -- MUST be treated as decoding errors. Different limits can
+    // be set for each of the different uses of integers, based on
+    // implementation constraints.
+    @Test
+    public void headerBlockIntegerNoOverflow() {
+        Decoder d = new Decoder(4096);
+        ByteBuffer data = ByteBuffer.wrap(new byte[]{
+                (byte) 0b11111111, // indexed + 127
+                // Integer.MAX_VALUE - 127 (base 128, little-endian):
+                (byte) 0b10000000,
+                (byte) 0b11111111,
+                (byte) 0b11111111,
+                (byte) 0b11111111,
+                (byte) 0b00000111
+        });
+
+        IllegalArgumentException e = assertVoidThrows(IllegalArgumentException.class,
+                () -> d.decode(data, true, nopCallback()));
+
+        assertExceptionMessageContains(e, "index=2147483647");
+    }
+
+    @Test
+    public void headerBlockIntegerOverflow() {
+        Decoder d = new Decoder(4096);
+        ByteBuffer data = ByteBuffer.wrap(new byte[]{
+                (byte) 0b11111111, // indexed + 127
+                // Integer.MAX_VALUE - 127 + 1 (base 128, little endian):
+                (byte) 0b10000001,
+                (byte) 0b11111111,
+                (byte) 0b11111111,
+                (byte) 0b11111111,
+                (byte) 0b00000111
+        });
+
+        IllegalArgumentException e = assertVoidThrows(IllegalArgumentException.class,
+                () -> d.decode(data, true, nopCallback()));
+
+        assertExceptionMessageContains(e, "Integer overflow");
+    }
+
+    @Test
+    public void corruptedHeaderBlockString1() {
+        Decoder d = new Decoder(4096);
+        ByteBuffer data = ByteBuffer.wrap(new byte[]{
+                0b00001111, // literal, index=15
+                0b00000000,
+                0b00001000, // huffman=false, length=8
+                0b00000000, // \
+                0b00000000, //  but only 3 octets available...
+                0b00000000  // /
+        });
+        UncheckedIOException e = assertVoidThrows(UncheckedIOException.class,
+                () -> d.decode(data, true, nopCallback()));
+        assertNotNull(e.getCause());
+        assertEquals(e.getCause().getClass(), ProtocolException.class);
+        assertExceptionMessageContains(e, "Unexpected end of header block");
+    }
+
+    @Test
+    public void corruptedHeaderBlockString2() {
+        Decoder d = new Decoder(4096);
+        ByteBuffer data = ByteBuffer.wrap(new byte[]{
+                0b00001111, // literal, index=15
+                0b00000000,
+                (byte) 0b10001000, // huffman=true, length=8
+                0b00000000, // \
+                0b00000000, //  \
+                0b00000000, //   but only 5 octets available...
+                0b00000000, //  /
+                0b00000000  // /
+        });
+        UncheckedIOException e = assertVoidThrows(UncheckedIOException.class,
+                () -> d.decode(data, true, nopCallback()));
+        assertNotNull(e.getCause());
+        assertEquals(e.getCause().getClass(), ProtocolException.class);
+        assertExceptionMessageContains(e, "Unexpected end of header block");
+    }
+
+    // 5.2.  String Literal Representation
+    // ...A Huffman-encoded string literal containing the EOS symbol MUST be
+    // treated as a decoding error...
+    @Test
+    public void corruptedHeaderBlockHuffmanStringEOS() {
+        Decoder d = new Decoder(4096);
+        ByteBuffer data = ByteBuffer.wrap(new byte[]{
+                0b00001111, // literal, index=15
+                0b00000000,
+                (byte) 0b10000110, // huffman=true, length=6
+                0b00011001, 0b01001101, (byte) 0b11111111,
+                (byte) 0b11111111, (byte) 0b11111111, (byte) 0b11111100
+        });
+        IllegalArgumentException e = assertVoidThrows(IllegalArgumentException.class,
+                () -> d.decode(data, true, nopCallback()));
+
+        assertExceptionMessageContains(e, "Encountered EOS");
+    }
+
+    // 5.2.  String Literal Representation
+    // ...A padding strictly longer than 7 bits MUST be treated as a decoding
+    // error...
+    @Test
+    public void corruptedHeaderBlockHuffmanStringLongPadding1() {
+        Decoder d = new Decoder(4096);
+        ByteBuffer data = ByteBuffer.wrap(new byte[]{
+                0b00001111, // literal, index=15
+                0b00000000,
+                (byte) 0b10000011, // huffman=true, length=3
+                0b00011001, 0b01001101, (byte) 0b11111111
+                // len("aei") + len(padding) = (5 + 5 + 5) + (9)
+        });
+        IllegalArgumentException e = assertVoidThrows(IllegalArgumentException.class,
+                () -> d.decode(data, true, nopCallback()));
+
+        assertExceptionMessageContains(e, "Padding is too long", "len=9");
+    }
+
+    @Test
+    public void corruptedHeaderBlockHuffmanStringLongPadding2() {
+        Decoder d = new Decoder(4096);
+        ByteBuffer data = ByteBuffer.wrap(new byte[]{
+                0b00001111, // literal, index=15
+                0b00000000,
+                (byte) 0b10000011, // huffman=true, length=3
+                0b00011001, 0b01111010, (byte) 0b11111111
+                // len("aek") + len(padding) = (5 + 5 + 7) + (7)
+        });
+        assertVoidDoesNotThrow(() -> d.decode(data, true, nopCallback()));
+    }
+
+    // 5.2.  String Literal Representation
+    // ...A padding not corresponding to the most significant bits of the code
+    // for the EOS symbol MUST be treated as a decoding error...
+    @Test
+    public void corruptedHeaderBlockHuffmanStringNotEOSPadding() {
+        Decoder d = new Decoder(4096);
+        ByteBuffer data = ByteBuffer.wrap(new byte[]{
+                0b00001111, // literal, index=15
+                0b00000000,
+                (byte) 0b10000011, // huffman=true, length=3
+                0b00011001, 0b01111010, (byte) 0b11111110
+        });
+        IllegalArgumentException e = assertVoidThrows(IllegalArgumentException.class,
+                () -> d.decode(data, true, nopCallback()));
+
+        assertExceptionMessageContains(e, "Not a EOS prefix");
+    }
+
+    @Test
+    public void argsTestBiConsumerIsNull() {
+        Decoder decoder = new Decoder(4096);
+        assertVoidThrows(NullPointerException.class,
+                () -> decoder.decode(ByteBuffer.allocate(16), true, null));
+    }
+
+    @Test
+    public void argsTestByteBufferIsNull() {
+        Decoder decoder = new Decoder(4096);
+        assertVoidThrows(NullPointerException.class,
+                () -> decoder.decode(null, true, nopCallback()));
+    }
+
+    @Test
+    public void argsTestBothAreNull() {
+        Decoder decoder = new Decoder(4096);
+        assertVoidThrows(NullPointerException.class,
+                () -> decoder.decode(null, true, null));
+    }
+
+    private static void test(String hexdump,
+                             String headerTable, String headerList) {
+        test(new Decoder(4096), hexdump, headerTable, headerList);
+    }
+
+    //
+    // Sometimes we need to keep the same decoder along several runs,
+    // as it models the same connection
+    //
+    private static void test(Decoder d, String hexdump,
+                             String expectedHeaderTable, String expectedHeaderList) {
+
+        ByteBuffer source = SpecHelper.toBytes(hexdump);
+
+        List<String> actual = new LinkedList<>();
+        d.decode(source, true, (name, value) -> {
+            if (value == null) {
+                actual.add(name.toString());
+            } else {
+                actual.add(name + ": " + value);
+            }
+        });
+
+        assertEquals(d.getTable().getStateString(), expectedHeaderTable);
+        assertEquals(actual.stream().collect(Collectors.joining("\n")), expectedHeaderList);
+    }
+
+    private static DecodingCallback nopCallback() {
+        return (t, u) -> { };
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/http2/java.httpclient/sun/net/httpclient/hpack/EncoderTest.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,623 @@
+/*
+ * 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.net.httpclient.hpack;
+
+import org.testng.annotations.Test;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.function.Function;
+
+import static java.util.Arrays.asList;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+import static sun.net.httpclient.hpack.SpecHelper.toHexdump;
+import static sun.net.httpclient.hpack.TestHelper.assertVoidThrows;
+
+// TODO: map textual representation of commands from the spec to actual
+// calls to encoder (actually, this is a good idea for decoder as well)
+public final class EncoderTest {
+
+    //
+    // http://tools.ietf.org/html/rfc7541#appendix-C.2.1
+    //
+    @Test
+    public void example1() {
+
+        Encoder e = newCustomEncoder(256);
+        drainInitialUpdate(e);
+
+        e.literalWithIndexing("custom-key", false, "custom-header", false);
+        // @formatter:off
+        test(e,
+
+             "400a 6375 7374 6f6d 2d6b 6579 0d63 7573\n" +
+             "746f 6d2d 6865 6164 6572",
+
+             "[  1] (s =  55) custom-key: custom-header\n" +
+             "      Table size:  55");
+        // @formatter:on
+    }
+
+    //
+    // http://tools.ietf.org/html/rfc7541#appendix-C.2.2
+    //
+    @Test
+    public void example2() {
+
+        Encoder e = newCustomEncoder(256);
+        drainInitialUpdate(e);
+
+        e.literal(4, "/sample/path", false);
+        // @formatter:off
+        test(e,
+
+             "040c 2f73 616d 706c 652f 7061 7468",
+
+             "empty.");
+        // @formatter:on
+    }
+
+    //
+    // http://tools.ietf.org/html/rfc7541#appendix-C.2.3
+    //
+    @Test
+    public void example3() {
+
+        Encoder e = newCustomEncoder(256);
+        drainInitialUpdate(e);
+
+        e.literalNeverIndexed("password", false, "secret", false);
+        // @formatter:off
+        test(e,
+
+             "1008 7061 7373 776f 7264 0673 6563 7265\n" +
+             "74",
+
+             "empty.");
+        // @formatter:on
+    }
+
+    //
+    // http://tools.ietf.org/html/rfc7541#appendix-C.2.4
+    //
+    @Test
+    public void example4() {
+
+        Encoder e = newCustomEncoder(256);
+        drainInitialUpdate(e);
+
+        e.indexed(2);
+        // @formatter:off
+        test(e,
+
+             "82",
+
+             "empty.");
+        // @formatter:on
+    }
+
+    //
+    // http://tools.ietf.org/html/rfc7541#appendix-C.3
+    //
+    @Test
+    public void example5() {
+        Encoder e = newCustomEncoder(256);
+        drainInitialUpdate(e);
+
+        ByteBuffer output = ByteBuffer.allocate(64);
+        e.indexed(2);
+        e.encode(output);
+        e.indexed(6);
+        e.encode(output);
+        e.indexed(4);
+        e.encode(output);
+        e.literalWithIndexing(1, "www.example.com", false);
+        e.encode(output);
+
+        output.flip();
+
+        // @formatter:off
+        test(e, output,
+
+             "8286 8441 0f77 7777 2e65 7861 6d70 6c65\n" +
+             "2e63 6f6d",
+
+             "[  1] (s =  57) :authority: www.example.com\n" +
+             "      Table size:  57");
+
+        output.clear();
+
+        e.indexed( 2);
+        e.encode(output);
+        e.indexed( 6);
+        e.encode(output);
+        e.indexed( 4);
+        e.encode(output);
+        e.indexed(62);
+        e.encode(output);
+        e.literalWithIndexing(24, "no-cache", false);
+        e.encode(output);
+
+        output.flip();
+
+        test(e, output,
+
+             "8286 84be 5808 6e6f 2d63 6163 6865",
+
+             "[  1] (s =  53) cache-control: no-cache\n" +
+             "[  2] (s =  57) :authority: www.example.com\n" +
+             "      Table size: 110");
+
+        output.clear();
+
+        e.indexed( 2);
+        e.encode(output);
+        e.indexed( 7);
+        e.encode(output);
+        e.indexed( 5);
+        e.encode(output);
+        e.indexed(63);
+        e.encode(output);
+        e.literalWithIndexing("custom-key", false, "custom-value", false);
+        e.encode(output);
+
+        output.flip();
+
+        test(e, output,
+
+             "8287 85bf 400a 6375 7374 6f6d 2d6b 6579\n" +
+             "0c63 7573 746f 6d2d 7661 6c75 65",
+
+             "[  1] (s =  54) custom-key: custom-value\n" +
+             "[  2] (s =  53) cache-control: no-cache\n" +
+             "[  3] (s =  57) :authority: www.example.com\n" +
+             "      Table size: 164");
+        // @formatter:on
+    }
+
+    //
+    // http://tools.ietf.org/html/rfc7541#appendix-C.4
+    //
+    @Test
+    public void example6() {
+        Encoder e = newCustomEncoder(256);
+        drainInitialUpdate(e);
+
+        ByteBuffer output = ByteBuffer.allocate(64);
+        e.indexed(2);
+        e.encode(output);
+        e.indexed(6);
+        e.encode(output);
+        e.indexed(4);
+        e.encode(output);
+        e.literalWithIndexing(1, "www.example.com", true);
+        e.encode(output);
+
+        output.flip();
+
+        // @formatter:off
+        test(e, output,
+
+             "8286 8441 8cf1 e3c2 e5f2 3a6b a0ab 90f4\n" +
+             "ff",
+
+             "[  1] (s =  57) :authority: www.example.com\n" +
+             "      Table size:  57");
+
+        output.clear();
+
+        e.indexed( 2);
+        e.encode(output);
+        e.indexed( 6);
+        e.encode(output);
+        e.indexed( 4);
+        e.encode(output);
+        e.indexed(62);
+        e.encode(output);
+        e.literalWithIndexing(24, "no-cache", true);
+        e.encode(output);
+
+        output.flip();
+
+        test(e, output,
+
+             "8286 84be 5886 a8eb 1064 9cbf",
+
+             "[  1] (s =  53) cache-control: no-cache\n" +
+             "[  2] (s =  57) :authority: www.example.com\n" +
+             "      Table size: 110");
+
+        output.clear();
+
+        e.indexed( 2);
+        e.encode(output);
+        e.indexed( 7);
+        e.encode(output);
+        e.indexed( 5);
+        e.encode(output);
+        e.indexed(63);
+        e.encode(output);
+        e.literalWithIndexing("custom-key", true, "custom-value", true);
+        e.encode(output);
+
+        output.flip();
+
+        test(e, output,
+
+             "8287 85bf 4088 25a8 49e9 5ba9 7d7f 8925\n" +
+             "a849 e95b b8e8 b4bf",
+
+             "[  1] (s =  54) custom-key: custom-value\n" +
+             "[  2] (s =  53) cache-control: no-cache\n" +
+             "[  3] (s =  57) :authority: www.example.com\n" +
+             "      Table size: 164");
+        // @formatter:on
+    }
+
+    //
+    // http://tools.ietf.org/html/rfc7541#appendix-C.5
+    //
+    @Test
+    public void example7() {
+        Encoder e = newCustomEncoder(256);
+        drainInitialUpdate(e);
+
+        ByteBuffer output = ByteBuffer.allocate(128);
+        // @formatter:off
+        e.literalWithIndexing( 8, "302", false);
+        e.encode(output);
+        e.literalWithIndexing(24, "private", false);
+        e.encode(output);
+        e.literalWithIndexing(33, "Mon, 21 Oct 2013 20:13:21 GMT", false);
+        e.encode(output);
+        e.literalWithIndexing(46, "https://www.example.com", false);
+        e.encode(output);
+
+        output.flip();
+
+        test(e, output,
+
+             "4803 3330 3258 0770 7269 7661 7465 611d\n" +
+             "4d6f 6e2c 2032 3120 4f63 7420 3230 3133\n" +
+             "2032 303a 3133 3a32 3120 474d 546e 1768\n" +
+             "7474 7073 3a2f 2f77 7777 2e65 7861 6d70\n" +
+             "6c65 2e63 6f6d",
+
+             "[  1] (s =  63) location: https://www.example.com\n" +
+             "[  2] (s =  65) date: Mon, 21 Oct 2013 20:13:21 GMT\n" +
+             "[  3] (s =  52) cache-control: private\n" +
+             "[  4] (s =  42) :status: 302\n" +
+             "      Table size: 222");
+
+        output.clear();
+
+        e.literalWithIndexing( 8, "307", false);
+        e.encode(output);
+        e.indexed(65);
+        e.encode(output);
+        e.indexed(64);
+        e.encode(output);
+        e.indexed(63);
+        e.encode(output);
+
+        output.flip();
+
+        test(e, output,
+
+             "4803 3330 37c1 c0bf",
+
+             "[  1] (s =  42) :status: 307\n" +
+             "[  2] (s =  63) location: https://www.example.com\n" +
+             "[  3] (s =  65) date: Mon, 21 Oct 2013 20:13:21 GMT\n" +
+             "[  4] (s =  52) cache-control: private\n" +
+             "      Table size: 222");
+
+        output.clear();
+
+        e.indexed( 8);
+        e.encode(output);
+        e.indexed(65);
+        e.encode(output);
+        e.literalWithIndexing(33, "Mon, 21 Oct 2013 20:13:22 GMT", false);
+        e.encode(output);
+        e.indexed(64);
+        e.encode(output);
+        e.literalWithIndexing(26, "gzip", false);
+        e.encode(output);
+        e.literalWithIndexing(55, "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1", false);
+        e.encode(output);
+
+        output.flip();
+
+        test(e, output,
+
+             "88c1 611d 4d6f 6e2c 2032 3120 4f63 7420\n" +
+             "3230 3133 2032 303a 3133 3a32 3220 474d\n" +
+             "54c0 5a04 677a 6970 7738 666f 6f3d 4153\n" +
+             "444a 4b48 514b 425a 584f 5157 454f 5049\n" +
+             "5541 5851 5745 4f49 553b 206d 6178 2d61\n" +
+             "6765 3d33 3630 303b 2076 6572 7369 6f6e\n" +
+             "3d31",
+
+             "[  1] (s =  98) set-cookie: foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1\n" +
+             "[  2] (s =  52) content-encoding: gzip\n" +
+             "[  3] (s =  65) date: Mon, 21 Oct 2013 20:13:22 GMT\n" +
+             "      Table size: 215");
+        // @formatter:on
+    }
+
+    //
+    // http://tools.ietf.org/html/rfc7541#appendix-C.6
+    //
+    @Test
+    public void example8() {
+        Encoder e = newCustomEncoder(256);
+        drainInitialUpdate(e);
+
+        ByteBuffer output = ByteBuffer.allocate(128);
+        // @formatter:off
+        e.literalWithIndexing( 8, "302", true);
+        e.encode(output);
+        e.literalWithIndexing(24, "private", true);
+        e.encode(output);
+        e.literalWithIndexing(33, "Mon, 21 Oct 2013 20:13:21 GMT", true);
+        e.encode(output);
+        e.literalWithIndexing(46, "https://www.example.com", true);
+        e.encode(output);
+
+        output.flip();
+
+        test(e, output,
+
+             "4882 6402 5885 aec3 771a 4b61 96d0 7abe\n" +
+             "9410 54d4 44a8 2005 9504 0b81 66e0 82a6\n" +
+             "2d1b ff6e 919d 29ad 1718 63c7 8f0b 97c8\n" +
+             "e9ae 82ae 43d3",
+
+             "[  1] (s =  63) location: https://www.example.com\n" +
+             "[  2] (s =  65) date: Mon, 21 Oct 2013 20:13:21 GMT\n" +
+             "[  3] (s =  52) cache-control: private\n" +
+             "[  4] (s =  42) :status: 302\n" +
+             "      Table size: 222");
+
+        output.clear();
+
+        e.literalWithIndexing( 8, "307", true);
+        e.encode(output);
+        e.indexed(65);
+        e.encode(output);
+        e.indexed(64);
+        e.encode(output);
+        e.indexed(63);
+        e.encode(output);
+
+        output.flip();
+
+        test(e, output,
+
+             "4883 640e ffc1 c0bf",
+
+             "[  1] (s =  42) :status: 307\n" +
+             "[  2] (s =  63) location: https://www.example.com\n" +
+             "[  3] (s =  65) date: Mon, 21 Oct 2013 20:13:21 GMT\n" +
+             "[  4] (s =  52) cache-control: private\n" +
+             "      Table size: 222");
+
+        output.clear();
+
+        e.indexed( 8);
+        e.encode(output);
+        e.indexed(65);
+        e.encode(output);
+        e.literalWithIndexing(33, "Mon, 21 Oct 2013 20:13:22 GMT", true);
+        e.encode(output);
+        e.indexed(64);
+        e.encode(output);
+        e.literalWithIndexing(26, "gzip", true);
+        e.encode(output);
+        e.literalWithIndexing(55, "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1", true);
+        e.encode(output);
+
+        output.flip();
+
+        test(e, output,
+
+             "88c1 6196 d07a be94 1054 d444 a820 0595\n" +
+             "040b 8166 e084 a62d 1bff c05a 839b d9ab\n" +
+             "77ad 94e7 821d d7f2 e6c7 b335 dfdf cd5b\n" +
+             "3960 d5af 2708 7f36 72c1 ab27 0fb5 291f\n" +
+             "9587 3160 65c0 03ed 4ee5 b106 3d50 07",
+
+             "[  1] (s =  98) set-cookie: foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1\n" +
+             "[  2] (s =  52) content-encoding: gzip\n" +
+             "[  3] (s =  65) date: Mon, 21 Oct 2013 20:13:22 GMT\n" +
+             "      Table size: 215");
+        // @formatter:on
+    }
+
+    @Test
+    public void initialSizeUpdateDefaultEncoder() {
+        Function<Integer, Encoder> e = Encoder::new;
+        testSizeUpdate(e, 1024, asList(), asList(0));
+        testSizeUpdate(e, 1024, asList(1024), asList(0));
+        testSizeUpdate(e, 1024, asList(1024, 1024), asList(0));
+        testSizeUpdate(e, 1024, asList(1024, 512), asList(0));
+        testSizeUpdate(e, 1024, asList(512, 1024), asList(0));
+        testSizeUpdate(e, 1024, asList(512, 2048), asList(0));
+    }
+
+    @Test
+    public void initialSizeUpdateCustomEncoder() {
+        Function<Integer, Encoder> e = EncoderTest::newCustomEncoder;
+        testSizeUpdate(e, 1024, asList(), asList(1024));
+        testSizeUpdate(e, 1024, asList(1024), asList(1024));
+        testSizeUpdate(e, 1024, asList(1024, 1024), asList(1024));
+        testSizeUpdate(e, 1024, asList(1024, 512), asList(512));
+        testSizeUpdate(e, 1024, asList(512, 1024), asList(1024));
+        testSizeUpdate(e, 1024, asList(512, 2048), asList(2048));
+    }
+
+    @Test
+    public void seriesOfSizeUpdatesDefaultEncoder() {
+        Function<Integer, Encoder> e = c -> {
+            Encoder encoder = new Encoder(c);
+            drainInitialUpdate(encoder);
+            return encoder;
+        };
+        testSizeUpdate(e, 0, asList(0), asList());
+        testSizeUpdate(e, 1024, asList(1024), asList());
+        testSizeUpdate(e, 1024, asList(2048), asList());
+        testSizeUpdate(e, 1024, asList(512), asList());
+        testSizeUpdate(e, 1024, asList(1024, 1024), asList());
+        testSizeUpdate(e, 1024, asList(1024, 2048), asList());
+        testSizeUpdate(e, 1024, asList(2048, 1024), asList());
+        testSizeUpdate(e, 1024, asList(1024, 512), asList());
+        testSizeUpdate(e, 1024, asList(512, 1024), asList());
+    }
+
+    //
+    // https://tools.ietf.org/html/rfc7541#section-4.2
+    //
+    @Test
+    public void seriesOfSizeUpdatesCustomEncoder() {
+        Function<Integer, Encoder> e = c -> {
+            Encoder encoder = newCustomEncoder(c);
+            drainInitialUpdate(encoder);
+            return encoder;
+        };
+        testSizeUpdate(e, 0, asList(0), asList());
+        testSizeUpdate(e, 1024, asList(1024), asList());
+        testSizeUpdate(e, 1024, asList(2048), asList(2048));
+        testSizeUpdate(e, 1024, asList(512), asList(512));
+        testSizeUpdate(e, 1024, asList(1024, 1024), asList());
+        testSizeUpdate(e, 1024, asList(1024, 2048), asList(2048));
+        testSizeUpdate(e, 1024, asList(2048, 1024), asList());
+        testSizeUpdate(e, 1024, asList(1024, 512), asList(512));
+        testSizeUpdate(e, 1024, asList(512, 1024), asList(512, 1024));
+    }
+
+    @Test
+    public void callSequenceViolations() {
+        {   // Hasn't set up a header
+            Encoder e = new Encoder(0);
+            assertVoidThrows(IllegalStateException.class, () -> e.encode(ByteBuffer.allocate(16)));
+        }
+        {   // Can't set up header while there's an unfinished encoding
+            Encoder e = new Encoder(0);
+            e.indexed(32);
+            assertVoidThrows(IllegalStateException.class, () -> e.indexed(32));
+        }
+        {   // Can't setMaxCapacity while there's an unfinished encoding
+            Encoder e = new Encoder(0);
+            e.indexed(32);
+            assertVoidThrows(IllegalStateException.class, () -> e.setMaxCapacity(512));
+        }
+        {   // Hasn't set up a header
+            Encoder e = new Encoder(0);
+            e.setMaxCapacity(256);
+            assertVoidThrows(IllegalStateException.class, () -> e.encode(ByteBuffer.allocate(16)));
+        }
+        {   // Hasn't set up a header after the previous encoding
+            Encoder e = new Encoder(0);
+            e.indexed(0);
+            boolean encoded = e.encode(ByteBuffer.allocate(16));
+            assertTrue(encoded); // assumption
+            assertVoidThrows(IllegalStateException.class, () -> e.encode(ByteBuffer.allocate(16)));
+        }
+    }
+
+    private static void test(Encoder encoder,
+                             String expectedTableState,
+                             String expectedHexdump) {
+
+        ByteBuffer b = ByteBuffer.allocate(128);
+        encoder.encode(b);
+        b.flip();
+        test(encoder, b, expectedTableState, expectedHexdump);
+    }
+
+    private static void test(Encoder encoder,
+                             ByteBuffer output,
+                             String expectedHexdump,
+                             String expectedTableState) {
+
+        String actualTableState = encoder.getHeaderTable().getStateString();
+        assertEquals(actualTableState, expectedTableState);
+
+        String actualHexdump = toHexdump(output);
+        assertEquals(actualHexdump, expectedHexdump.replaceAll("\\n", " "));
+    }
+
+    // initial size - the size encoder is constructed with
+    // updates      - a sequence of values for consecutive calls to encoder.setMaxCapacity
+    // expected     - a sequence of values expected to be decoded by a decoder
+    private void testSizeUpdate(Function<Integer, Encoder> encoder,
+                                int initialSize,
+                                List<Integer> updates,
+                                List<Integer> expected) {
+        Encoder e = encoder.apply(initialSize);
+        updates.forEach(e::setMaxCapacity);
+        ByteBuffer b = ByteBuffer.allocate(64);
+        e.header("a", "b");
+        e.encode(b);
+        b.flip();
+        Decoder d = new Decoder(updates.isEmpty() ? initialSize : Collections.max(updates));
+        List<Integer> actual = new ArrayList<>();
+        d.decode(b, true, new DecodingCallback() {
+            @Override
+            public void onDecoded(CharSequence name, CharSequence value) { }
+
+            @Override
+            public void onSizeUpdate(int capacity) {
+                actual.add(capacity);
+            }
+        });
+        assertEquals(actual, expected);
+    }
+
+    //
+    // Default encoder does not need any table, therefore a subclass that
+    // behaves differently is needed
+    //
+    private static Encoder newCustomEncoder(int maxCapacity) {
+        return new Encoder(maxCapacity) {
+            @Override
+            protected int calculateCapacity(int maxCapacity) {
+                return maxCapacity;
+            }
+        };
+    }
+
+    private static void drainInitialUpdate(Encoder e) {
+        ByteBuffer b = ByteBuffer.allocate(4);
+        e.header("a", "b");
+        boolean done;
+        do {
+            done = e.encode(b);
+            b.flip();
+        } while (!done);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/http2/java.httpclient/sun/net/httpclient/hpack/HeaderTableTest.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,375 @@
+/*
+ * 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.net.httpclient.hpack;
+
+import org.testng.annotations.Test;
+import sun.net.httpclient.hpack.HeaderTable.HeaderField;
+
+import java.nio.charset.StandardCharsets;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Random;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import static java.lang.String.format;
+import static org.testng.Assert.assertEquals;
+import static sun.net.httpclient.hpack.TestHelper.*;
+
+public class HeaderTableTest {
+
+    //
+    // https://tools.ietf.org/html/rfc7541#appendix-A
+    //
+    // @formatter:off
+    private static final String SPEC =
+       "          | 1     | :authority                  |               |\n" +
+       "          | 2     | :method                     | GET           |\n" +
+       "          | 3     | :method                     | POST          |\n" +
+       "          | 4     | :path                       | /             |\n" +
+       "          | 5     | :path                       | /index.html   |\n" +
+       "          | 6     | :scheme                     | http          |\n" +
+       "          | 7     | :scheme                     | https         |\n" +
+       "          | 8     | :status                     | 200           |\n" +
+       "          | 9     | :status                     | 204           |\n" +
+       "          | 10    | :status                     | 206           |\n" +
+       "          | 11    | :status                     | 304           |\n" +
+       "          | 12    | :status                     | 400           |\n" +
+       "          | 13    | :status                     | 404           |\n" +
+       "          | 14    | :status                     | 500           |\n" +
+       "          | 15    | accept-charset              |               |\n" +
+       "          | 16    | accept-encoding             | gzip, deflate |\n" +
+       "          | 17    | accept-language             |               |\n" +
+       "          | 18    | accept-ranges               |               |\n" +
+       "          | 19    | accept                      |               |\n" +
+       "          | 20    | access-control-allow-origin |               |\n" +
+       "          | 21    | age                         |               |\n" +
+       "          | 22    | allow                       |               |\n" +
+       "          | 23    | authorization               |               |\n" +
+       "          | 24    | cache-control               |               |\n" +
+       "          | 25    | content-disposition         |               |\n" +
+       "          | 26    | content-encoding            |               |\n" +
+       "          | 27    | content-language            |               |\n" +
+       "          | 28    | content-length              |               |\n" +
+       "          | 29    | content-location            |               |\n" +
+       "          | 30    | content-range               |               |\n" +
+       "          | 31    | content-type                |               |\n" +
+       "          | 32    | cookie                      |               |\n" +
+       "          | 33    | date                        |               |\n" +
+       "          | 34    | etag                        |               |\n" +
+       "          | 35    | expect                      |               |\n" +
+       "          | 36    | expires                     |               |\n" +
+       "          | 37    | from                        |               |\n" +
+       "          | 38    | host                        |               |\n" +
+       "          | 39    | if-match                    |               |\n" +
+       "          | 40    | if-modified-since           |               |\n" +
+       "          | 41    | if-none-match               |               |\n" +
+       "          | 42    | if-range                    |               |\n" +
+       "          | 43    | if-unmodified-since         |               |\n" +
+       "          | 44    | last-modified               |               |\n" +
+       "          | 45    | link                        |               |\n" +
+       "          | 46    | location                    |               |\n" +
+       "          | 47    | max-forwards                |               |\n" +
+       "          | 48    | proxy-authenticate          |               |\n" +
+       "          | 49    | proxy-authorization         |               |\n" +
+       "          | 50    | range                       |               |\n" +
+       "          | 51    | referer                     |               |\n" +
+       "          | 52    | refresh                     |               |\n" +
+       "          | 53    | retry-after                 |               |\n" +
+       "          | 54    | server                      |               |\n" +
+       "          | 55    | set-cookie                  |               |\n" +
+       "          | 56    | strict-transport-security   |               |\n" +
+       "          | 57    | transfer-encoding           |               |\n" +
+       "          | 58    | user-agent                  |               |\n" +
+       "          | 59    | vary                        |               |\n" +
+       "          | 60    | via                         |               |\n" +
+       "          | 61    | www-authenticate            |               |\n";
+    // @formatter:on
+
+    private static final int STATIC_TABLE_LENGTH = createStaticEntries().size();
+    private final Random rnd = newRandom();
+
+    @Test
+    public void staticData() {
+        HeaderTable table = new HeaderTable(0);
+        Map<Integer, HeaderField> staticHeaderFields = createStaticEntries();
+
+        Map<String, Integer> minimalIndexes = new HashMap<>();
+
+        for (Map.Entry<Integer, HeaderField> e : staticHeaderFields.entrySet()) {
+            Integer idx = e.getKey();
+            String hName = e.getValue().name;
+            Integer midx = minimalIndexes.get(hName);
+            if (midx == null) {
+                minimalIndexes.put(hName, idx);
+            } else {
+                minimalIndexes.put(hName, Math.min(idx, midx));
+            }
+        }
+
+        staticHeaderFields.entrySet().forEach(
+                e -> {
+                    // lookup
+                    HeaderField actualHeaderField = table.get(e.getKey());
+                    HeaderField expectedHeaderField = e.getValue();
+                    assertEquals(actualHeaderField, expectedHeaderField);
+
+                    // reverse lookup (name, value)
+                    String hName = expectedHeaderField.name;
+                    String hValue = expectedHeaderField.value;
+                    int expectedIndex = e.getKey();
+                    int actualIndex = table.indexOf(hName, hValue);
+
+                    assertEquals(actualIndex, expectedIndex);
+
+                    // reverse lookup (name)
+                    int expectedMinimalIndex = minimalIndexes.get(hName);
+                    int actualMinimalIndex = table.indexOf(hName, "blah-blah");
+
+                    assertEquals(-actualMinimalIndex, expectedMinimalIndex);
+                }
+        );
+    }
+
+    @Test
+    public void constructorSetsMaxSize() {
+        int size = rnd.nextInt(64);
+        HeaderTable t = new HeaderTable(size);
+        assertEquals(t.size(), 0);
+        assertEquals(t.maxSize(), size);
+    }
+
+    @Test
+    public void negativeMaximumSize() {
+        int maxSize = -(rnd.nextInt(100) + 1); // [-100, -1]
+        IllegalArgumentException e =
+                assertVoidThrows(IllegalArgumentException.class,
+                        () -> new HeaderTable(0).setMaxSize(maxSize));
+        assertExceptionMessageContains(e, "maxSize");
+    }
+
+    @Test
+    public void zeroMaximumSize() {
+        HeaderTable table = new HeaderTable(0);
+        table.setMaxSize(0);
+        assertEquals(table.maxSize(), 0);
+    }
+
+    @Test
+    public void negativeIndex() {
+        int idx = -(rnd.nextInt(256) + 1); // [-256, -1]
+        IllegalArgumentException e =
+                assertVoidThrows(IllegalArgumentException.class,
+                        () -> new HeaderTable(0).get(idx));
+        assertExceptionMessageContains(e, "index");
+    }
+
+    @Test
+    public void zeroIndex() {
+        IllegalArgumentException e =
+                assertThrows(IllegalArgumentException.class,
+                        () -> new HeaderTable(0).get(0));
+        assertExceptionMessageContains(e, "index");
+    }
+
+    @Test
+    public void length() {
+        HeaderTable table = new HeaderTable(0);
+        assertEquals(table.length(), STATIC_TABLE_LENGTH);
+    }
+
+    @Test
+    public void indexOutsideStaticRange() {
+        HeaderTable table = new HeaderTable(0);
+        int idx = table.length() + (rnd.nextInt(256) + 1);
+        IllegalArgumentException e =
+                assertThrows(IllegalArgumentException.class,
+                        () -> table.get(idx));
+        assertExceptionMessageContains(e, "index");
+    }
+
+    @Test
+    public void entryPutAfterStaticArea() {
+        HeaderTable table = new HeaderTable(256);
+        int idx = table.length() + 1;
+        assertThrows(IllegalArgumentException.class, () -> table.get(idx));
+
+        byte[] bytes = new byte[32];
+        rnd.nextBytes(bytes);
+        String name = new String(bytes, StandardCharsets.ISO_8859_1);
+        String value = "custom-value";
+
+        table.put(name, value);
+        HeaderField f = table.get(idx);
+        assertEquals(name, f.name);
+        assertEquals(value, f.value);
+    }
+
+    @Test
+    public void staticTableHasZeroSize() {
+        HeaderTable table = new HeaderTable(0);
+        assertEquals(0, table.size());
+    }
+
+    @Test
+    public void lowerIndexPriority() {
+        HeaderTable table = new HeaderTable(256);
+        int oldLength = table.length();
+        table.put("bender", "rodriguez");
+        table.put("bender", "rodriguez");
+        table.put("bender", "rodriguez");
+
+        assertEquals(table.length(), oldLength + 3); // more like an assumption
+        int i = table.indexOf("bender", "rodriguez");
+        assertEquals(oldLength + 1, i);
+    }
+
+    @Test
+    public void lowerIndexPriority2() {
+        HeaderTable table = new HeaderTable(256);
+        int oldLength = table.length();
+        int idx = rnd.nextInt(oldLength) + 1;
+        HeaderField f = table.get(idx);
+        table.put(f.name, f.value);
+        assertEquals(table.length(), oldLength + 1);
+        int i = table.indexOf(f.name, f.value);
+        assertEquals(idx, i);
+    }
+
+    // TODO: negative indexes check
+    // TODO: ensure full table clearance when adding huge header field
+    // TODO: ensure eviction deletes minimum needed entries, not more
+
+    @Test
+    public void fifo() {
+        HeaderTable t = new HeaderTable(Integer.MAX_VALUE);
+        // Let's add a series of header fields
+        int NUM_HEADERS = 32;
+        for (int i = 1; i <= NUM_HEADERS; i++) {
+            String s = String.valueOf(i);
+            t.put(s, s);
+        }
+        // They MUST appear in a FIFO order:
+        //   newer entries are at lower indexes
+        //   older entries are at higher indexes
+        for (int j = 1; j <= NUM_HEADERS; j++) {
+            HeaderField f = t.get(STATIC_TABLE_LENGTH + j);
+            int actualName = Integer.parseInt(f.name);
+            int expectedName = NUM_HEADERS - j + 1;
+            assertEquals(expectedName, actualName);
+        }
+        // Entries MUST be evicted in the order they were added:
+        //   the newer the entry the later it is evicted
+        for (int k = 1; k <= NUM_HEADERS; k++) {
+            HeaderField f = t.evictEntry();
+            assertEquals(String.valueOf(k), f.name);
+        }
+    }
+
+    @Test
+    public void indexOf() {
+        HeaderTable t = new HeaderTable(Integer.MAX_VALUE);
+        // Let's put a series of header fields
+        int NUM_HEADERS = 32;
+        for (int i = 1; i <= NUM_HEADERS; i++) {
+            String s = String.valueOf(i);
+            t.put(s, s);
+        }
+        // and verify indexOf (reverse lookup) returns correct indexes for
+        // full lookup
+        for (int j = 1; j <= NUM_HEADERS; j++) {
+            String s = String.valueOf(j);
+            int actualIndex = t.indexOf(s, s);
+            int expectedIndex = STATIC_TABLE_LENGTH + NUM_HEADERS - j + 1;
+            assertEquals(expectedIndex, actualIndex);
+        }
+        // as well as for just a name lookup
+        for (int j = 1; j <= NUM_HEADERS; j++) {
+            String s = String.valueOf(j);
+            int actualIndex = t.indexOf(s, "blah");
+            int expectedIndex = -(STATIC_TABLE_LENGTH + NUM_HEADERS - j + 1);
+            assertEquals(expectedIndex, actualIndex);
+        }
+        // lookup for non-existent name returns 0
+        assertEquals(0, t.indexOf("chupacabra", "1"));
+    }
+
+    @Test
+    public void testToString() {
+        HeaderTable table = new HeaderTable(0);
+        {
+            table.setMaxSize(2048);
+            assertEquals("entries: 0; used 0/2048 (0.0%)", table.toString());
+        }
+
+        {
+            String name = "custom-name";
+            String value = "custom-value";
+            int size = 512;
+
+            table.setMaxSize(size);
+            table.put(name, value);
+            String s = table.toString();
+
+            int used = name.length() + value.length() + 32;
+            double ratio = used * 100.0 / size;
+
+            String expected = format("entries: 1; used %s/%s (%.1f%%)", used, size, ratio);
+            assertEquals(expected, s);
+        }
+
+        {
+            table.setMaxSize(78);
+            table.put(":method", "");
+            table.put(":status", "");
+            String s = table.toString();
+            assertEquals("entries: 2; used 78/78 (100.0%)", s);
+        }
+    }
+
+    @Test
+    public void stateString() {
+        HeaderTable table = new HeaderTable(256);
+        table.put("custom-key", "custom-header");
+        // @formatter:off
+        assertEquals("[  1] (s =  55) custom-key: custom-header\n" +
+                     "      Table size:  55", table.getStateString());
+        // @formatter:on
+    }
+
+    private static Map<Integer, HeaderField> createStaticEntries() {
+        Pattern line = Pattern.compile(
+                "\\|\\s*(?<index>\\d+?)\\s*\\|\\s*(?<name>.+?)\\s*\\|\\s*(?<value>.*?)\\s*\\|");
+        Matcher m = line.matcher(SPEC);
+        Map<Integer, HeaderField> result = new HashMap<>();
+        while (m.find()) {
+            int index = Integer.parseInt(m.group("index"));
+            String name = m.group("name");
+            String value = m.group("value");
+            HeaderField f = new HeaderField(name, value);
+            result.put(index, f);
+        }
+        return Collections.unmodifiableMap(result); // lol
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/http2/java.httpclient/sun/net/httpclient/hpack/HuffmanTest.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,623 @@
+/*
+ * 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.net.httpclient.hpack;
+
+import org.testng.annotations.Test;
+
+import java.nio.ByteBuffer;
+import java.util.Stack;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import static java.lang.Integer.parseInt;
+import static org.testng.Assert.*;
+
+public final class HuffmanTest {
+
+    //
+    // https://tools.ietf.org/html/rfc7541#appendix-B
+    //
+    private static final String SPEC =
+            // @formatter:off
+     "                          code as bits                 as hex   len\n" +
+     "        sym              aligned to MSB                aligned   in\n" +
+     "                                                       to LSB   bits\n" +
+     "       (  0)  |11111111|11000                             1ff8  [13]\n" +
+     "       (  1)  |11111111|11111111|1011000                7fffd8  [23]\n" +
+     "       (  2)  |11111111|11111111|11111110|0010         fffffe2  [28]\n" +
+     "       (  3)  |11111111|11111111|11111110|0011         fffffe3  [28]\n" +
+     "       (  4)  |11111111|11111111|11111110|0100         fffffe4  [28]\n" +
+     "       (  5)  |11111111|11111111|11111110|0101         fffffe5  [28]\n" +
+     "       (  6)  |11111111|11111111|11111110|0110         fffffe6  [28]\n" +
+     "       (  7)  |11111111|11111111|11111110|0111         fffffe7  [28]\n" +
+     "       (  8)  |11111111|11111111|11111110|1000         fffffe8  [28]\n" +
+     "       (  9)  |11111111|11111111|11101010               ffffea  [24]\n" +
+     "       ( 10)  |11111111|11111111|11111111|111100      3ffffffc  [30]\n" +
+     "       ( 11)  |11111111|11111111|11111110|1001         fffffe9  [28]\n" +
+     "       ( 12)  |11111111|11111111|11111110|1010         fffffea  [28]\n" +
+     "       ( 13)  |11111111|11111111|11111111|111101      3ffffffd  [30]\n" +
+     "       ( 14)  |11111111|11111111|11111110|1011         fffffeb  [28]\n" +
+     "       ( 15)  |11111111|11111111|11111110|1100         fffffec  [28]\n" +
+     "       ( 16)  |11111111|11111111|11111110|1101         fffffed  [28]\n" +
+     "       ( 17)  |11111111|11111111|11111110|1110         fffffee  [28]\n" +
+     "       ( 18)  |11111111|11111111|11111110|1111         fffffef  [28]\n" +
+     "       ( 19)  |11111111|11111111|11111111|0000         ffffff0  [28]\n" +
+     "       ( 20)  |11111111|11111111|11111111|0001         ffffff1  [28]\n" +
+     "       ( 21)  |11111111|11111111|11111111|0010         ffffff2  [28]\n" +
+     "       ( 22)  |11111111|11111111|11111111|111110      3ffffffe  [30]\n" +
+     "       ( 23)  |11111111|11111111|11111111|0011         ffffff3  [28]\n" +
+     "       ( 24)  |11111111|11111111|11111111|0100         ffffff4  [28]\n" +
+     "       ( 25)  |11111111|11111111|11111111|0101         ffffff5  [28]\n" +
+     "       ( 26)  |11111111|11111111|11111111|0110         ffffff6  [28]\n" +
+     "       ( 27)  |11111111|11111111|11111111|0111         ffffff7  [28]\n" +
+     "       ( 28)  |11111111|11111111|11111111|1000         ffffff8  [28]\n" +
+     "       ( 29)  |11111111|11111111|11111111|1001         ffffff9  [28]\n" +
+     "       ( 30)  |11111111|11111111|11111111|1010         ffffffa  [28]\n" +
+     "       ( 31)  |11111111|11111111|11111111|1011         ffffffb  [28]\n" +
+     "   ' ' ( 32)  |010100                                       14  [ 6]\n" +
+     "   '!' ( 33)  |11111110|00                                 3f8  [10]\n" +
+     "  '\"' ( 34)  |11111110|01                                 3f9  [10]\n" +
+     "   '#' ( 35)  |11111111|1010                               ffa  [12]\n" +
+     "   '$' ( 36)  |11111111|11001                             1ff9  [13]\n" +
+     "   '%' ( 37)  |010101                                       15  [ 6]\n" +
+     "   '&' ( 38)  |11111000                                     f8  [ 8]\n" +
+     "   ''' ( 39)  |11111111|010                                7fa  [11]\n" +
+     "   '(' ( 40)  |11111110|10                                 3fa  [10]\n" +
+     "   ')' ( 41)  |11111110|11                                 3fb  [10]\n" +
+     "   '*' ( 42)  |11111001                                     f9  [ 8]\n" +
+     "   '+' ( 43)  |11111111|011                                7fb  [11]\n" +
+     "   ',' ( 44)  |11111010                                     fa  [ 8]\n" +
+     "   '-' ( 45)  |010110                                       16  [ 6]\n" +
+     "   '.' ( 46)  |010111                                       17  [ 6]\n" +
+     "   '/' ( 47)  |011000                                       18  [ 6]\n" +
+     "   '0' ( 48)  |00000                                         0  [ 5]\n" +
+     "   '1' ( 49)  |00001                                         1  [ 5]\n" +
+     "   '2' ( 50)  |00010                                         2  [ 5]\n" +
+     "   '3' ( 51)  |011001                                       19  [ 6]\n" +
+     "   '4' ( 52)  |011010                                       1a  [ 6]\n" +
+     "   '5' ( 53)  |011011                                       1b  [ 6]\n" +
+     "   '6' ( 54)  |011100                                       1c  [ 6]\n" +
+     "   '7' ( 55)  |011101                                       1d  [ 6]\n" +
+     "   '8' ( 56)  |011110                                       1e  [ 6]\n" +
+     "   '9' ( 57)  |011111                                       1f  [ 6]\n" +
+     "   ':' ( 58)  |1011100                                      5c  [ 7]\n" +
+     "   ';' ( 59)  |11111011                                     fb  [ 8]\n" +
+     "   '<' ( 60)  |11111111|1111100                           7ffc  [15]\n" +
+     "   '=' ( 61)  |100000                                       20  [ 6]\n" +
+     "   '>' ( 62)  |11111111|1011                               ffb  [12]\n" +
+     "   '?' ( 63)  |11111111|00                                 3fc  [10]\n" +
+     "   '@' ( 64)  |11111111|11010                             1ffa  [13]\n" +
+     "   'A' ( 65)  |100001                                       21  [ 6]\n" +
+     "   'B' ( 66)  |1011101                                      5d  [ 7]\n" +
+     "   'C' ( 67)  |1011110                                      5e  [ 7]\n" +
+     "   'D' ( 68)  |1011111                                      5f  [ 7]\n" +
+     "   'E' ( 69)  |1100000                                      60  [ 7]\n" +
+     "   'F' ( 70)  |1100001                                      61  [ 7]\n" +
+     "   'G' ( 71)  |1100010                                      62  [ 7]\n" +
+     "   'H' ( 72)  |1100011                                      63  [ 7]\n" +
+     "   'I' ( 73)  |1100100                                      64  [ 7]\n" +
+     "   'J' ( 74)  |1100101                                      65  [ 7]\n" +
+     "   'K' ( 75)  |1100110                                      66  [ 7]\n" +
+     "   'L' ( 76)  |1100111                                      67  [ 7]\n" +
+     "   'M' ( 77)  |1101000                                      68  [ 7]\n" +
+     "   'N' ( 78)  |1101001                                      69  [ 7]\n" +
+     "   'O' ( 79)  |1101010                                      6a  [ 7]\n" +
+     "   'P' ( 80)  |1101011                                      6b  [ 7]\n" +
+     "   'Q' ( 81)  |1101100                                      6c  [ 7]\n" +
+     "   'R' ( 82)  |1101101                                      6d  [ 7]\n" +
+     "   'S' ( 83)  |1101110                                      6e  [ 7]\n" +
+     "   'T' ( 84)  |1101111                                      6f  [ 7]\n" +
+     "   'U' ( 85)  |1110000                                      70  [ 7]\n" +
+     "   'V' ( 86)  |1110001                                      71  [ 7]\n" +
+     "   'W' ( 87)  |1110010                                      72  [ 7]\n" +
+     "   'X' ( 88)  |11111100                                     fc  [ 8]\n" +
+     "   'Y' ( 89)  |1110011                                      73  [ 7]\n" +
+     "   'Z' ( 90)  |11111101                                     fd  [ 8]\n" +
+     "   '[' ( 91)  |11111111|11011                             1ffb  [13]\n" +
+     "  '\\' ( 92)  |11111111|11111110|000                     7fff0  [19]\n" +
+     "   ']' ( 93)  |11111111|11100                             1ffc  [13]\n" +
+     "   '^' ( 94)  |11111111|111100                            3ffc  [14]\n" +
+     "   '_' ( 95)  |100010                                       22  [ 6]\n" +
+     "   '`' ( 96)  |11111111|1111101                           7ffd  [15]\n" +
+     "   'a' ( 97)  |00011                                         3  [ 5]\n" +
+     "   'b' ( 98)  |100011                                       23  [ 6]\n" +
+     "   'c' ( 99)  |00100                                         4  [ 5]\n" +
+     "   'd' (100)  |100100                                       24  [ 6]\n" +
+     "   'e' (101)  |00101                                         5  [ 5]\n" +
+     "   'f' (102)  |100101                                       25  [ 6]\n" +
+     "   'g' (103)  |100110                                       26  [ 6]\n" +
+     "   'h' (104)  |100111                                       27  [ 6]\n" +
+     "   'i' (105)  |00110                                         6  [ 5]\n" +
+     "   'j' (106)  |1110100                                      74  [ 7]\n" +
+     "   'k' (107)  |1110101                                      75  [ 7]\n" +
+     "   'l' (108)  |101000                                       28  [ 6]\n" +
+     "   'm' (109)  |101001                                       29  [ 6]\n" +
+     "   'n' (110)  |101010                                       2a  [ 6]\n" +
+     "   'o' (111)  |00111                                         7  [ 5]\n" +
+     "   'p' (112)  |101011                                       2b  [ 6]\n" +
+     "   'q' (113)  |1110110                                      76  [ 7]\n" +
+     "   'r' (114)  |101100                                       2c  [ 6]\n" +
+     "   's' (115)  |01000                                         8  [ 5]\n" +
+     "   't' (116)  |01001                                         9  [ 5]\n" +
+     "   'u' (117)  |101101                                       2d  [ 6]\n" +
+     "   'v' (118)  |1110111                                      77  [ 7]\n" +
+     "   'w' (119)  |1111000                                      78  [ 7]\n" +
+     "   'x' (120)  |1111001                                      79  [ 7]\n" +
+     "   'y' (121)  |1111010                                      7a  [ 7]\n" +
+     "   'z' (122)  |1111011                                      7b  [ 7]\n" +
+     "   '{' (123)  |11111111|1111110                           7ffe  [15]\n" +
+     "   '|' (124)  |11111111|100                                7fc  [11]\n" +
+     "   '}' (125)  |11111111|111101                            3ffd  [14]\n" +
+     "   '~' (126)  |11111111|11101                             1ffd  [13]\n" +
+     "       (127)  |11111111|11111111|11111111|1100         ffffffc  [28]\n" +
+     "       (128)  |11111111|11111110|0110                    fffe6  [20]\n" +
+     "       (129)  |11111111|11111111|010010                 3fffd2  [22]\n" +
+     "       (130)  |11111111|11111110|0111                    fffe7  [20]\n" +
+     "       (131)  |11111111|11111110|1000                    fffe8  [20]\n" +
+     "       (132)  |11111111|11111111|010011                 3fffd3  [22]\n" +
+     "       (133)  |11111111|11111111|010100                 3fffd4  [22]\n" +
+     "       (134)  |11111111|11111111|010101                 3fffd5  [22]\n" +
+     "       (135)  |11111111|11111111|1011001                7fffd9  [23]\n" +
+     "       (136)  |11111111|11111111|010110                 3fffd6  [22]\n" +
+     "       (137)  |11111111|11111111|1011010                7fffda  [23]\n" +
+     "       (138)  |11111111|11111111|1011011                7fffdb  [23]\n" +
+     "       (139)  |11111111|11111111|1011100                7fffdc  [23]\n" +
+     "       (140)  |11111111|11111111|1011101                7fffdd  [23]\n" +
+     "       (141)  |11111111|11111111|1011110                7fffde  [23]\n" +
+     "       (142)  |11111111|11111111|11101011               ffffeb  [24]\n" +
+     "       (143)  |11111111|11111111|1011111                7fffdf  [23]\n" +
+     "       (144)  |11111111|11111111|11101100               ffffec  [24]\n" +
+     "       (145)  |11111111|11111111|11101101               ffffed  [24]\n" +
+     "       (146)  |11111111|11111111|010111                 3fffd7  [22]\n" +
+     "       (147)  |11111111|11111111|1100000                7fffe0  [23]\n" +
+     "       (148)  |11111111|11111111|11101110               ffffee  [24]\n" +
+     "       (149)  |11111111|11111111|1100001                7fffe1  [23]\n" +
+     "       (150)  |11111111|11111111|1100010                7fffe2  [23]\n" +
+     "       (151)  |11111111|11111111|1100011                7fffe3  [23]\n" +
+     "       (152)  |11111111|11111111|1100100                7fffe4  [23]\n" +
+     "       (153)  |11111111|11111110|11100                  1fffdc  [21]\n" +
+     "       (154)  |11111111|11111111|011000                 3fffd8  [22]\n" +
+     "       (155)  |11111111|11111111|1100101                7fffe5  [23]\n" +
+     "       (156)  |11111111|11111111|011001                 3fffd9  [22]\n" +
+     "       (157)  |11111111|11111111|1100110                7fffe6  [23]\n" +
+     "       (158)  |11111111|11111111|1100111                7fffe7  [23]\n" +
+     "       (159)  |11111111|11111111|11101111               ffffef  [24]\n" +
+     "       (160)  |11111111|11111111|011010                 3fffda  [22]\n" +
+     "       (161)  |11111111|11111110|11101                  1fffdd  [21]\n" +
+     "       (162)  |11111111|11111110|1001                    fffe9  [20]\n" +
+     "       (163)  |11111111|11111111|011011                 3fffdb  [22]\n" +
+     "       (164)  |11111111|11111111|011100                 3fffdc  [22]\n" +
+     "       (165)  |11111111|11111111|1101000                7fffe8  [23]\n" +
+     "       (166)  |11111111|11111111|1101001                7fffe9  [23]\n" +
+     "       (167)  |11111111|11111110|11110                  1fffde  [21]\n" +
+     "       (168)  |11111111|11111111|1101010                7fffea  [23]\n" +
+     "       (169)  |11111111|11111111|011101                 3fffdd  [22]\n" +
+     "       (170)  |11111111|11111111|011110                 3fffde  [22]\n" +
+     "       (171)  |11111111|11111111|11110000               fffff0  [24]\n" +
+     "       (172)  |11111111|11111110|11111                  1fffdf  [21]\n" +
+     "       (173)  |11111111|11111111|011111                 3fffdf  [22]\n" +
+     "       (174)  |11111111|11111111|1101011                7fffeb  [23]\n" +
+     "       (175)  |11111111|11111111|1101100                7fffec  [23]\n" +
+     "       (176)  |11111111|11111111|00000                  1fffe0  [21]\n" +
+     "       (177)  |11111111|11111111|00001                  1fffe1  [21]\n" +
+     "       (178)  |11111111|11111111|100000                 3fffe0  [22]\n" +
+     "       (179)  |11111111|11111111|00010                  1fffe2  [21]\n" +
+     "       (180)  |11111111|11111111|1101101                7fffed  [23]\n" +
+     "       (181)  |11111111|11111111|100001                 3fffe1  [22]\n" +
+     "       (182)  |11111111|11111111|1101110                7fffee  [23]\n" +
+     "       (183)  |11111111|11111111|1101111                7fffef  [23]\n" +
+     "       (184)  |11111111|11111110|1010                    fffea  [20]\n" +
+     "       (185)  |11111111|11111111|100010                 3fffe2  [22]\n" +
+     "       (186)  |11111111|11111111|100011                 3fffe3  [22]\n" +
+     "       (187)  |11111111|11111111|100100                 3fffe4  [22]\n" +
+     "       (188)  |11111111|11111111|1110000                7ffff0  [23]\n" +
+     "       (189)  |11111111|11111111|100101                 3fffe5  [22]\n" +
+     "       (190)  |11111111|11111111|100110                 3fffe6  [22]\n" +
+     "       (191)  |11111111|11111111|1110001                7ffff1  [23]\n" +
+     "       (192)  |11111111|11111111|11111000|00           3ffffe0  [26]\n" +
+     "       (193)  |11111111|11111111|11111000|01           3ffffe1  [26]\n" +
+     "       (194)  |11111111|11111110|1011                    fffeb  [20]\n" +
+     "       (195)  |11111111|11111110|001                     7fff1  [19]\n" +
+     "       (196)  |11111111|11111111|100111                 3fffe7  [22]\n" +
+     "       (197)  |11111111|11111111|1110010                7ffff2  [23]\n" +
+     "       (198)  |11111111|11111111|101000                 3fffe8  [22]\n" +
+     "       (199)  |11111111|11111111|11110110|0            1ffffec  [25]\n" +
+     "       (200)  |11111111|11111111|11111000|10           3ffffe2  [26]\n" +
+     "       (201)  |11111111|11111111|11111000|11           3ffffe3  [26]\n" +
+     "       (202)  |11111111|11111111|11111001|00           3ffffe4  [26]\n" +
+     "       (203)  |11111111|11111111|11111011|110          7ffffde  [27]\n" +
+     "       (204)  |11111111|11111111|11111011|111          7ffffdf  [27]\n" +
+     "       (205)  |11111111|11111111|11111001|01           3ffffe5  [26]\n" +
+     "       (206)  |11111111|11111111|11110001               fffff1  [24]\n" +
+     "       (207)  |11111111|11111111|11110110|1            1ffffed  [25]\n" +
+     "       (208)  |11111111|11111110|010                     7fff2  [19]\n" +
+     "       (209)  |11111111|11111111|00011                  1fffe3  [21]\n" +
+     "       (210)  |11111111|11111111|11111001|10           3ffffe6  [26]\n" +
+     "       (211)  |11111111|11111111|11111100|000          7ffffe0  [27]\n" +
+     "       (212)  |11111111|11111111|11111100|001          7ffffe1  [27]\n" +
+     "       (213)  |11111111|11111111|11111001|11           3ffffe7  [26]\n" +
+     "       (214)  |11111111|11111111|11111100|010          7ffffe2  [27]\n" +
+     "       (215)  |11111111|11111111|11110010               fffff2  [24]\n" +
+     "       (216)  |11111111|11111111|00100                  1fffe4  [21]\n" +
+     "       (217)  |11111111|11111111|00101                  1fffe5  [21]\n" +
+     "       (218)  |11111111|11111111|11111010|00           3ffffe8  [26]\n" +
+     "       (219)  |11111111|11111111|11111010|01           3ffffe9  [26]\n" +
+     "       (220)  |11111111|11111111|11111111|1101         ffffffd  [28]\n" +
+     "       (221)  |11111111|11111111|11111100|011          7ffffe3  [27]\n" +
+     "       (222)  |11111111|11111111|11111100|100          7ffffe4  [27]\n" +
+     "       (223)  |11111111|11111111|11111100|101          7ffffe5  [27]\n" +
+     "       (224)  |11111111|11111110|1100                    fffec  [20]\n" +
+     "       (225)  |11111111|11111111|11110011               fffff3  [24]\n" +
+     "       (226)  |11111111|11111110|1101                    fffed  [20]\n" +
+     "       (227)  |11111111|11111111|00110                  1fffe6  [21]\n" +
+     "       (228)  |11111111|11111111|101001                 3fffe9  [22]\n" +
+     "       (229)  |11111111|11111111|00111                  1fffe7  [21]\n" +
+     "       (230)  |11111111|11111111|01000                  1fffe8  [21]\n" +
+     "       (231)  |11111111|11111111|1110011                7ffff3  [23]\n" +
+     "       (232)  |11111111|11111111|101010                 3fffea  [22]\n" +
+     "       (233)  |11111111|11111111|101011                 3fffeb  [22]\n" +
+     "       (234)  |11111111|11111111|11110111|0            1ffffee  [25]\n" +
+     "       (235)  |11111111|11111111|11110111|1            1ffffef  [25]\n" +
+     "       (236)  |11111111|11111111|11110100               fffff4  [24]\n" +
+     "       (237)  |11111111|11111111|11110101               fffff5  [24]\n" +
+     "       (238)  |11111111|11111111|11111010|10           3ffffea  [26]\n" +
+     "       (239)  |11111111|11111111|1110100                7ffff4  [23]\n" +
+     "       (240)  |11111111|11111111|11111010|11           3ffffeb  [26]\n" +
+     "       (241)  |11111111|11111111|11111100|110          7ffffe6  [27]\n" +
+     "       (242)  |11111111|11111111|11111011|00           3ffffec  [26]\n" +
+     "       (243)  |11111111|11111111|11111011|01           3ffffed  [26]\n" +
+     "       (244)  |11111111|11111111|11111100|111          7ffffe7  [27]\n" +
+     "       (245)  |11111111|11111111|11111101|000          7ffffe8  [27]\n" +
+     "       (246)  |11111111|11111111|11111101|001          7ffffe9  [27]\n" +
+     "       (247)  |11111111|11111111|11111101|010          7ffffea  [27]\n" +
+     "       (248)  |11111111|11111111|11111101|011          7ffffeb  [27]\n" +
+     "       (249)  |11111111|11111111|11111111|1110         ffffffe  [28]\n" +
+     "       (250)  |11111111|11111111|11111101|100          7ffffec  [27]\n" +
+     "       (251)  |11111111|11111111|11111101|101          7ffffed  [27]\n" +
+     "       (252)  |11111111|11111111|11111101|110          7ffffee  [27]\n" +
+     "       (253)  |11111111|11111111|11111101|111          7ffffef  [27]\n" +
+     "       (254)  |11111111|11111111|11111110|000          7fffff0  [27]\n" +
+     "       (255)  |11111111|11111111|11111011|10           3ffffee  [26]\n" +
+     "   EOS (256)  |11111111|11111111|11111111|111111      3fffffff  [30]";
+    // @formatter:on
+
+    @Test
+    public void read_table() {
+        Pattern line = Pattern.compile(
+                "\\(\\s*(?<ascii>\\d+)\\s*\\)\\s*(?<binary>(\\|(0|1)+)+)\\s*" +
+                        "(?<hex>[0-9a-zA-Z]+)\\s*\\[\\s*(?<len>\\d+)\\s*\\]");
+        Matcher m = line.matcher(SPEC);
+        int i = 0;
+        while (m.find()) {
+            String ascii = m.group("ascii");
+            String binary = m.group("binary").replaceAll("\\|", "");
+            String hex = m.group("hex");
+            String len = m.group("len");
+
+            // Several sanity checks for the data read from the table, just to
+            // make sure what we read makes sense
+            assertEquals(parseInt(len), binary.length());
+            assertEquals(parseInt(binary, 2), parseInt(hex, 16));
+
+            int expected = parseInt(ascii);
+
+            // TODO: find actual eos, do not hardcode it!
+            byte[] bytes = intToBytes(0x3fffffff, 30,
+                    parseInt(hex, 16), parseInt(len));
+
+            StringBuilder actual = new StringBuilder();
+            Huffman.Reader t = new Huffman.Reader();
+            t.read(ByteBuffer.wrap(bytes), actual, false, true);
+
+            // What has been read MUST represent a single symbol
+            assertEquals(actual.length(), 1, "ascii: " + ascii);
+
+            // It's a lot more visual to compare char as codes rather than
+            // characters (as some of them might not be visible)
+            assertEquals(actual.charAt(0), expected);
+            i++;
+        }
+        assertEquals(i, 257); // 256 + EOS
+    }
+
+    //
+    // https://tools.ietf.org/html/rfc7541#appendix-C.4.1
+    //
+    @Test
+    public void read_1() {
+        read("f1e3 c2e5 f23a 6ba0 ab90 f4ff", "www.example.com");
+    }
+
+    @Test
+    public void write_1() {
+        write("www.example.com", "f1e3 c2e5 f23a 6ba0 ab90 f4ff");
+    }
+
+    //
+    // https://tools.ietf.org/html/rfc7541#appendix-C.4.2
+    //
+    @Test
+    public void read_2() {
+        read("a8eb 1064 9cbf", "no-cache");
+    }
+
+    @Test
+    public void write_2() {
+        write("no-cache", "a8eb 1064 9cbf");
+    }
+
+    //
+    // https://tools.ietf.org/html/rfc7541#appendix-C.4.3
+    //
+    @Test
+    public void read_3() {
+        read("25a8 49e9 5ba9 7d7f", "custom-key");
+    }
+
+    @Test
+    public void write_3() {
+        write("custom-key", "25a8 49e9 5ba9 7d7f");
+    }
+
+    //
+    // https://tools.ietf.org/html/rfc7541#appendix-C.4.3
+    //
+    @Test
+    public void read_4() {
+        read("25a8 49e9 5bb8 e8b4 bf", "custom-value");
+    }
+
+    @Test
+    public void write_4() {
+        write("custom-value", "25a8 49e9 5bb8 e8b4 bf");
+    }
+
+    //
+    // https://tools.ietf.org/html/rfc7541#appendix-C.6.1
+    //
+    @Test
+    public void read_5() {
+        read("6402", "302");
+    }
+
+    @Test
+    public void write_5() {
+        write("302", "6402");
+    }
+
+    //
+    // https://tools.ietf.org/html/rfc7541#appendix-C.6.1
+    //
+    @Test
+    public void read_6() {
+        read("aec3 771a 4b", "private");
+    }
+
+    @Test
+    public void write_6() {
+        write("private", "aec3 771a 4b");
+    }
+
+    //
+    // https://tools.ietf.org/html/rfc7541#appendix-C.6.1
+    //
+    @Test
+    public void read_7() {
+        read("d07a be94 1054 d444 a820 0595 040b 8166 e082 a62d 1bff",
+                "Mon, 21 Oct 2013 20:13:21 GMT");
+    }
+
+    @Test
+    public void write_7() {
+        write("Mon, 21 Oct 2013 20:13:21 GMT",
+                "d07a be94 1054 d444 a820 0595 040b 8166 e082 a62d 1bff");
+    }
+
+    //
+    // https://tools.ietf.org/html/rfc7541#appendix-C.6.1
+    //
+    @Test
+    public void read_8() {
+        read("9d29 ad17 1863 c78f 0b97 c8e9 ae82 ae43 d3",
+                "https://www.example.com");
+    }
+
+    @Test
+    public void write_8() {
+        write("https://www.example.com",
+                "9d29 ad17 1863 c78f 0b97 c8e9 ae82 ae43 d3");
+    }
+
+    //
+    // https://tools.ietf.org/html/rfc7541#appendix-C.6.2
+    //
+    @Test
+    public void read_9() {
+        read("640e ff", "307");
+    }
+
+    @Test
+    public void write_9() {
+        write("307", "640e ff");
+    }
+
+    //
+    // https://tools.ietf.org/html/rfc7541#appendix-C.6.3
+    //
+    @Test
+    public void read_10() {
+        read("d07a be94 1054 d444 a820 0595 040b 8166 e084 a62d 1bff",
+                "Mon, 21 Oct 2013 20:13:22 GMT");
+    }
+
+    @Test
+    public void write_10() {
+        write("Mon, 21 Oct 2013 20:13:22 GMT",
+                "d07a be94 1054 d444 a820 0595 040b 8166 e084 a62d 1bff");
+    }
+
+    //
+    // https://tools.ietf.org/html/rfc7541#appendix-C.6.3
+    //
+    @Test
+    public void read_11() {
+        read("9bd9 ab", "gzip");
+    }
+
+    @Test
+    public void write_11() {
+        write("gzip", "9bd9 ab");
+    }
+
+    //
+    // https://tools.ietf.org/html/rfc7541#appendix-C.6.3
+    //
+    @Test
+    public void read_12() {
+        read("94e7 821d d7f2 e6c7 b335 dfdf cd5b 3960 " +
+             "d5af 2708 7f36 72c1 ab27 0fb5 291f 9587 " +
+             "3160 65c0 03ed 4ee5 b106 3d50 07",
+             "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1");
+    }
+
+    @Test
+    public void test_trie_has_no_empty_nodes() {
+        Huffman.Node root = Huffman.INSTANCE.getRoot();
+        Stack<Huffman.Node> backlog = new Stack<>();
+        backlog.push(root);
+        while (!backlog.isEmpty()) {
+            Huffman.Node n = backlog.pop();
+            // The only type of nodes we couldn't possibly catch during
+            // construction is an empty node: no children and no char
+            if (n.left != null) {
+                backlog.push(n.left);
+            }
+            if (n.right != null) {
+                backlog.push(n.right);
+            }
+            assertFalse(!n.charIsSet && n.left == null && n.right == null,
+                    "Empty node in the trie");
+        }
+    }
+
+    @Test
+    public void test_trie_has_257_nodes() {
+        int count = 0;
+        Huffman.Node root = Huffman.INSTANCE.getRoot();
+        Stack<Huffman.Node> backlog = new Stack<>();
+        backlog.push(root);
+        while (!backlog.isEmpty()) {
+            Huffman.Node n = backlog.pop();
+            if (n.left != null) {
+                backlog.push(n.left);
+            }
+            if (n.right != null) {
+                backlog.push(n.right);
+            }
+            if (n.isLeaf()) {
+                count++;
+            }
+        }
+        assertEquals(count, 257);
+    }
+
+    @Test
+    public void cant_encode_outside_byte() {
+        TestHelper.Block<Object> coding =
+                () -> new Huffman.Writer()
+                        .from(((char) 256) + "", 0, 1)
+                        .write(ByteBuffer.allocate(1));
+        RuntimeException e =
+                TestHelper.assertVoidThrows(RuntimeException.class, coding);
+        TestHelper.assertExceptionMessageContains(e, "char");
+    }
+
+    private static void read(String hexdump, String decoded) {
+        ByteBuffer source = SpecHelper.toBytes(hexdump);
+        Appendable actual = new StringBuilder();
+        new Huffman.Reader().read(source, actual, true);
+        assertEquals(actual.toString(), decoded);
+    }
+
+    private static void write(String decoded, String hexdump) {
+        int n = Huffman.INSTANCE.lengthOf(decoded);
+        ByteBuffer destination = ByteBuffer.allocate(n); // Extra margin (1) to test having more bytes in the destination than needed is ok
+        Huffman.Writer writer = new Huffman.Writer();
+        BuffersTestingKit.forEachSplit(destination, byteBuffers -> {
+            writer.from(decoded, 0, decoded.length());
+            boolean written = false;
+            for (ByteBuffer b : byteBuffers) {
+                int pos = b.position();
+                written = writer.write(b);
+                b.position(pos);
+            }
+            assertTrue(written);
+            ByteBuffer concated = BuffersTestingKit.concat(byteBuffers);
+            String actual = SpecHelper.toHexdump(concated);
+            assertEquals(actual, hexdump);
+            writer.reset();
+        });
+    }
+
+    //
+    // It's not very pretty, yes I know that
+    //
+    //      hex:
+    //
+    //      |31|30|...|N-1|...|01|00|
+    //                  \        /
+    //                  codeLength
+    //
+    //      hex <<= 32 - codeLength; (align to MSB):
+    //
+    //      |31|30|...|32-N|...|01|00|
+    //        \        /
+    //        codeLength
+    //
+    //      EOS:
+    //
+    //      |31|30|...|M-1|...|01|00|
+    //                   \        /
+    //                   eosLength
+    //
+    //      eos <<= 32 - eosLength; (align to MSB):
+    //
+    //      pad with MSBs of EOS:
+    //
+    //      |31|30|...|32-N|32-N-1|...|01|00|
+    //                     |    32|...|
+    //
+    //      Finally, split into byte[]
+    //
+    private byte[] intToBytes(int eos, int eosLength, int hex, int codeLength) {
+        hex <<= 32 - codeLength;
+        eos >>= codeLength - (32 - eosLength);
+        hex |= eos;
+        int n = (int) Math.ceil(codeLength / 8.0);
+        byte[] result = new byte[n];
+        for (int i = 0; i < n; i++) {
+            result[i] = (byte) (hex >> (32 - 8 * (i + 1)));
+        }
+        return result;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/http2/java.httpclient/sun/net/httpclient/hpack/SpecHelper.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.net.httpclient.hpack;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+//
+// THIS IS NOT A TEST
+//
+public final class SpecHelper {
+
+    private SpecHelper() {
+        throw new AssertionError();
+    }
+
+    public static ByteBuffer toBytes(String hexdump) {
+        Pattern hexByte = Pattern.compile("[0-9a-fA-F]{2}");
+        List<String> bytes = new ArrayList<>();
+        Matcher matcher = hexByte.matcher(hexdump);
+        while (matcher.find()) {
+            bytes.add(matcher.group(0));
+        }
+        ByteBuffer result = ByteBuffer.allocate(bytes.size());
+        for (String f : bytes) {
+            result.put((byte) Integer.parseInt(f, 16));
+        }
+        result.flip();
+        return result;
+    }
+
+    public static String toHexdump(ByteBuffer bb) {
+        List<String> words = new ArrayList<>();
+        int i = 0;
+        while (bb.hasRemaining()) {
+            if (i % 2 == 0) {
+                words.add("");
+            }
+            byte b = bb.get();
+            String hex = Integer.toHexString(256 + Byte.toUnsignedInt(b)).substring(1);
+            words.set(i / 2, words.get(i / 2) + hex);
+            i++;
+        }
+        return words.stream().collect(Collectors.joining(" "));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/http2/java.httpclient/sun/net/httpclient/hpack/TestHelper.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,164 @@
+/*
+ * 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.net.httpclient.hpack;
+
+import org.testng.annotations.Test;
+
+import java.util.Objects;
+import java.util.Random;
+
+public final class TestHelper {
+
+    public static Random newRandom() {
+        long seed = Long.getLong("jdk.test.lib.random.seed", System.currentTimeMillis());
+        System.out.println("new java.util.Random(" + seed + ")");
+        return new Random(seed);
+    }
+
+    public static <T extends Throwable> T assertVoidThrows(Class<T> clazz, Block<?> code) {
+        return assertThrows(clazz, () -> {
+            code.run();
+            return null;
+        });
+    }
+
+    public static <T extends Throwable> T assertThrows(Class<T> clazz, ReturningBlock<?> code) {
+        Objects.requireNonNull(clazz, "clazz == null");
+        Objects.requireNonNull(code, "code == null");
+        try {
+            code.run();
+        } catch (Throwable t) {
+            if (clazz.isInstance(t)) {
+                return clazz.cast(t);
+            }
+            throw new AssertionError("Expected to catch exception of type "
+                    + clazz.getCanonicalName() + ", instead caught "
+                    + t.getClass().getCanonicalName(), t);
+
+        }
+        throw new AssertionError(
+                "Expected to catch exception of type " + clazz.getCanonicalName()
+                        + ", but caught nothing");
+    }
+
+    public static <T> T assertDoesNotThrow(ReturningBlock<T> code) {
+        Objects.requireNonNull(code, "code == null");
+        try {
+            return code.run();
+        } catch (Throwable t) {
+            throw new AssertionError(
+                    "Expected code block to exit normally, instead " +
+                            "caught " + t.getClass().getCanonicalName(), t);
+        }
+    }
+
+    public static void assertVoidDoesNotThrow(Block<?> code) {
+        Objects.requireNonNull(code, "code == null");
+        try {
+            code.run();
+        } catch (Throwable t) {
+            throw new AssertionError(
+                    "Expected code block to exit normally, instead " +
+                            "caught " + t.getClass().getCanonicalName(), t);
+        }
+    }
+
+
+    public static void assertExceptionMessageContains(Throwable t,
+                                                      CharSequence firstSubsequence,
+                                                      CharSequence... others) {
+        assertCharSequenceContains(t.getMessage(), firstSubsequence, others);
+    }
+
+    public static void assertCharSequenceContains(CharSequence s,
+                                                  CharSequence firstSubsequence,
+                                                  CharSequence... others) {
+        if (s == null) {
+            throw new NullPointerException("Exception message is null");
+        }
+        String str = s.toString();
+        String missing = null;
+        if (!str.contains(firstSubsequence.toString())) {
+            missing = firstSubsequence.toString();
+        } else {
+            for (CharSequence o : others) {
+                if (!str.contains(o.toString())) {
+                    missing = o.toString();
+                    break;
+                }
+            }
+        }
+        if (missing != null) {
+            throw new AssertionError("CharSequence '" + s + "'" + " does not "
+                    + "contain subsequence '" + missing + "'");
+        }
+    }
+
+    public interface ReturningBlock<T> {
+        T run() throws Throwable;
+    }
+
+    public interface Block<T> {
+        void run() throws Throwable;
+    }
+
+    // tests
+
+    @Test
+    public void assertThrows() {
+        assertThrows(NullPointerException.class, () -> ((Object) null).toString());
+    }
+
+    @Test
+    public void assertThrowsWrongType() {
+        try {
+            assertThrows(IllegalArgumentException.class, () -> ((Object) null).toString());
+        } catch (AssertionError e) {
+            Throwable cause = e.getCause();
+            String message = e.getMessage();
+            if (cause != null
+                    && cause instanceof NullPointerException
+                    && message != null
+                    && message.contains("instead caught")) {
+                return;
+            }
+        }
+        throw new AssertionError();
+    }
+
+    @Test
+    public void assertThrowsNoneCaught() {
+        try {
+            assertThrows(IllegalArgumentException.class, () -> null);
+        } catch (AssertionError e) {
+            Throwable cause = e.getCause();
+            String message = e.getMessage();
+            if (cause == null
+                    && message != null
+                    && message.contains("but caught nothing")) {
+                return;
+            }
+        }
+        throw new AssertionError();
+    }
+}
--- a/jdk/test/java/security/Signature/TestInitSignWithMyOwnRandom.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/test/java/security/Signature/TestInitSignWithMyOwnRandom.java	Wed Jul 05 21:37:42 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -55,9 +55,9 @@
 
     int count = 0;
 
-    public int nextInt() {
+    @Override
+    public void nextBytes(byte[] rs) {
         count++;
-        return 0;
     }
 
     public boolean isUsed() {
--- a/jdk/test/java/time/tck/java/time/format/TCKDateTimeFormatterBuilder.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/test/java/time/tck/java/time/format/TCKDateTimeFormatterBuilder.java	Wed Jul 05 21:37:42 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -71,6 +71,7 @@
 
 import java.text.ParsePosition;
 import java.time.LocalDate;
+import java.time.LocalDateTime;
 import java.time.YearMonth;
 import java.time.ZoneOffset;
 import java.time.format.DateTimeFormatter;
@@ -661,6 +662,8 @@
             {"W"},
             {"W"},
 
+            {"g"},
+            {"ggggg"},
         };
     }
 
@@ -762,6 +765,37 @@
     }
 
     //-----------------------------------------------------------------------
+    @DataProvider(name="modJulianFieldPattern")
+    Object[][] data_modJuilanFieldPattern() {
+        return new Object[][] {
+            {"g", "1"},
+            {"g", "123456"},
+            {"gggggg", "123456"},
+        };
+    }
+
+    @Test(dataProvider="modJulianFieldPattern")
+    public void test_modJulianFieldPattern(String pattern, String input) throws Exception {
+        DateTimeFormatter.ofPattern(pattern).parse(input);
+    }
+
+    @DataProvider(name="modJulianFieldValues")
+    Object[][] data_modJuilanFieldValues() {
+        return new Object[][] {
+            {1970, 1, 1, "40587"},
+            {1858, 11, 17, "0"},
+            {1858, 11, 16, "-1"},
+        };
+    }
+
+    @Test(dataProvider="modJulianFieldValues")
+    public void test_modJulianFieldValues(int y, int m, int d, String expected) throws Exception {
+        DateTimeFormatter df = new DateTimeFormatterBuilder().appendPattern("g").toFormatter();
+         assertEquals(LocalDate.of(y, m, d).format(df), expected);
+    }
+
+
+    //-----------------------------------------------------------------------
     @Test
     public void test_adjacent_strict_firstFixedWidth() throws Exception {
         // succeeds because both number elements are fixed width
@@ -897,7 +931,7 @@
 
     @Test
     public void test_adjacent_lenient_fractionFollows_0digit() throws Exception {
-        // succeeds because hour/min are fixed width
+        // succeeds because hour, min and fraction of seconds are fixed width
         DateTimeFormatter f = builder.parseLenient().appendValue(HOUR_OF_DAY, 2).appendValue(MINUTE_OF_HOUR, 2).appendFraction(NANO_OF_SECOND, 3, 3, false).toFormatter(Locale.UK);
         ParsePosition pp = new ParsePosition(0);
         TemporalAccessor parsed = f.parseUnresolved("1230", pp);
@@ -907,6 +941,21 @@
         assertEquals(parsed.getLong(MINUTE_OF_HOUR), 30L);
     }
 
+    @DataProvider(name="adjacentFractionParseData")
+    Object[][] data_adjacent_fraction_parse() {
+        return new Object[][] {
+            {"20130812214600025", "yyyyMMddHHmmssSSS", LocalDateTime.of(2013, 8, 12, 21, 46, 00, 25000000)},
+            {"201308122146000256", "yyyyMMddHHmmssSSSS", LocalDateTime.of(2013, 8, 12, 21, 46, 00, 25600000)},
+        };
+    }
+
+    @Test(dataProvider = "adjacentFractionParseData")
+    public void test_adjacent_fraction(String input, String pattern, LocalDateTime expected) {
+        DateTimeFormatter dtf = DateTimeFormatter.ofPattern(pattern);
+        LocalDateTime actual = LocalDateTime.parse(input, dtf);
+        assertEquals(actual, expected);
+    }
+
     @DataProvider(name="lenientOffsetParseData")
     Object[][] data_lenient_offset_parse() {
         return new Object[][] {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/time/tck/java/time/format/TCKLocalizedOffsetIdPrinterParser.java	Wed Jul 05 21:37:42 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.
+ */
+package tck.java.time.format;
+
+import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.Locale;
+
+import org.testng.annotations.Test;
+
+/**
+ * Test localized behavior of formatter.
+ */
+@Test
+public class TCKLocalizedOffsetIdPrinterParser {
+    @Test
+    public void test_localized_offset_parse() {
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.S O")
+                                                       .withLocale(Locale.ENGLISH);
+        String date = formatter.format(ZonedDateTime.now(ZoneOffset.UTC));
+        formatter.parse(date) ;
+     }
+}
--- a/jdk/test/java/util/ServiceLoader/modules/BasicTest.java	Thu Apr 21 12:57:17 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import java.lang.reflect.Layer;
-import java.security.Provider;
-import java.util.ServiceLoader;
-
-import org.testng.annotations.Test;
-import static org.testng.Assert.*;
-
-/*
- * @test
- * @run testng BasicTest
- * @summary Basic test of ServiceLoader with modules
- */
-
-public class BasicTest {
-
-    @Test
-    public void testEmptyLayer() {
-        ServiceLoader<Provider> sl
-            = ServiceLoader.load(Layer.empty(), Provider.class);
-        assertFalse(sl.iterator().hasNext());
-    }
-
-    @Test
-    public void testBootLayer() {
-        ServiceLoader<Provider> sl
-            = ServiceLoader.load(Layer.boot(), Provider.class);
-        boolean found = false;
-        for (Provider provider : sl) {
-            if (provider.getName().equals("SunJCE"))
-                found = true;
-        }
-        assertTrue(found);
-    }
-
-    @Test(expectedExceptions = { NullPointerException.class })
-    public void testNullLayer() {
-        ServiceLoader.load(null, Provider.class);
-    }
-
-    @Test(expectedExceptions = { NullPointerException.class })
-    public void testNullService() {
-        ServiceLoader.load(Layer.empty(), null);
-    }
-
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/ServiceLoader/modules/MiscTests.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.lang.reflect.Layer;
+import java.security.Provider;
+import java.util.ServiceLoader;
+
+import org.testng.annotations.Test;
+import static org.testng.Assert.*;
+
+/*
+ * @test
+ * @run testng MiscTests
+ * @summary Basic test of ServiceLoader with modules
+ */
+
+public class MiscTests {
+
+    @Test
+    public void testEmptyLayer() {
+        ServiceLoader<Provider> sl
+            = ServiceLoader.load(Layer.empty(), Provider.class);
+        assertFalse(sl.iterator().hasNext());
+    }
+
+    @Test(expectedExceptions = { NullPointerException.class })
+    public void testNullLayer() {
+        ServiceLoader.load(null, Provider.class);
+    }
+
+    @Test(expectedExceptions = { NullPointerException.class })
+    public void testNullService() {
+        ServiceLoader.load(Layer.empty(), null);
+    }
+
+}
--- a/jdk/test/java/util/TimeZone/Bug6772689.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/test/java/util/TimeZone/Bug6772689.java	Wed Jul 05 21:37:42 2017 +0200
@@ -24,7 +24,6 @@
 /*
  * @test
  * @bug 6772689
- * @key intermittent
  * @summary Test for standard-to-daylight transitions at midnight:
  * date stays on the given day.
  */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/imageio/plugins/tiff/MultiPageImageTIFFFieldTest.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,378 @@
+/*
+ * 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
+ * @ignore  8148454
+ * @bug     8152183 8148454
+ * @author  a.stepanov
+ * @summary check that TIFFields are derived properly for multi-page tiff
+ * @run     main MultiPageImageTIFFFieldTest
+ */
+
+import java.awt.*;
+import java.awt.color.*;
+import java.awt.image.BufferedImage;
+import java.io.*;
+import javax.imageio.*;
+import javax.imageio.metadata.*;
+import javax.imageio.stream.*;
+import javax.imageio.plugins.tiff.*;
+
+
+public class MultiPageImageTIFFFieldTest {
+
+    private final static String FILENAME = "test.tiff";
+    private final static int W1 = 20, H1 = 40, W2 = 100, H2 = 15;
+    private final static Color C1 = Color.BLACK, C2 = Color.RED;
+
+    private final static int N_WIDTH  = BaselineTIFFTagSet.TAG_IMAGE_WIDTH;
+    private final static int N_HEIGHT = BaselineTIFFTagSet.TAG_IMAGE_LENGTH;
+
+    private static final String DESCRIPTION_1[] = {"Description-1", "abc ABC"};
+    private static final String DESCRIPTION_2[] = {"Description-2", "1-2-3"};
+    private final static int N_DESCRIPTION =
+        BaselineTIFFTagSet.TAG_IMAGE_DESCRIPTION;
+
+    private final static String EXIF_DATA_1[] = {"2001:01:01 00:00:01"};
+    private final static String EXIF_DATA_2[] = {"2002:02:02 00:00:02"};
+    private final static int N_EXIF = ExifTIFFTagSet.TAG_DATE_TIME_ORIGINAL;
+
+    private final static String GPS_DATA[] = {
+        ExifGPSTagSet.STATUS_MEASUREMENT_IN_PROGRESS};
+    private final static int N_GPS = ExifGPSTagSet.TAG_GPS_STATUS;
+
+    private final static short FAX_DATA =
+        FaxTIFFTagSet.CLEAN_FAX_DATA_ERRORS_UNCORRECTED;
+    private final static int N_FAX = FaxTIFFTagSet.TAG_CLEAN_FAX_DATA;
+
+    private static final byte[] ICC_PROFILE_2 =
+        ICC_ProfileRGB.getInstance(ColorSpace.CS_sRGB).getData();
+    private static final int N_ICC = BaselineTIFFTagSet.TAG_ICC_PROFILE;
+
+    private static final int N_BPS = BaselineTIFFTagSet.TAG_BITS_PER_SAMPLE;
+
+    private static final int
+        COMPRESSION_1 = BaselineTIFFTagSet.COMPRESSION_DEFLATE,
+        COMPRESSION_2 = BaselineTIFFTagSet.COMPRESSION_LZW;
+    private static final int N_COMPRESSION = BaselineTIFFTagSet.TAG_COMPRESSION;
+
+    private static final int
+        GRAY_1 = BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_WHITE_IS_ZERO,
+        GRAY_2 = BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_BLACK_IS_ZERO,
+        RGB    = BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_RGB;
+
+    private static final int N_PHOTO =
+        BaselineTIFFTagSet.TAG_PHOTOMETRIC_INTERPRETATION;
+
+    private ImageWriter getTIFFWriter() {
+
+        java.util.Iterator<ImageWriter> writers =
+            ImageIO.getImageWritersByFormatName("TIFF");
+        if (!writers.hasNext()) {
+            throw new RuntimeException("No writers available for TIFF format");
+        }
+        return writers.next();
+    }
+
+    private ImageReader getTIFFReader() {
+
+        java.util.Iterator<ImageReader> readers =
+            ImageIO.getImageReadersByFormatName("TIFF");
+        if (!readers.hasNext()) {
+            throw new RuntimeException("No readers available for TIFF format");
+        }
+        return readers.next();
+    }
+
+    private void addASCIIField(TIFFDirectory d,
+                               String        name,
+                               String        data[],
+                               int           num) {
+
+        d.addTIFFField(new TIFFField(
+            new TIFFTag(name, num, 1 << TIFFTag.TIFF_ASCII),
+                TIFFTag.TIFF_ASCII, data.length, data));
+    }
+
+    private void checkASCIIField(TIFFDirectory d,
+                                 String        what,
+                                 String        data[],
+                                 int           num) {
+
+        String notFound = what + " field was not found";
+        check(d.containsTIFFField(num), notFound);
+        TIFFField f = d.getTIFFField(num);
+        check(f.getType() == TIFFTag.TIFF_ASCII, "field type != ASCII");
+        check(f.getCount() == data.length, "invalid " + what + " data count");
+        for (int i = 0; i < data.length; i++) {
+            check(f.getValueAsString(i).equals(data[i]),
+                "invalid " + what + " data");
+        }
+    }
+
+    private void writeImage() throws Exception {
+
+        OutputStream s = new BufferedOutputStream(new FileOutputStream(FILENAME));
+        try (ImageOutputStream ios = ImageIO.createImageOutputStream(s)) {
+
+            ImageWriter writer = getTIFFWriter();
+            writer.setOutput(ios);
+
+            BufferedImage img1 =
+                new BufferedImage(W1, H1, BufferedImage.TYPE_BYTE_GRAY);
+            Graphics g = img1.getGraphics();
+            g.setColor(C1);
+            g.fillRect(0, 0, W1, H1);
+            g.dispose();
+
+            BufferedImage img2 =
+                new BufferedImage(W2, H2, BufferedImage.TYPE_INT_RGB);
+            g = img2.getGraphics();
+            g.setColor(C2);
+            g.fillRect(0, 0, W2, H2);
+            g.dispose();
+
+            ImageWriteParam param1 = writer.getDefaultWriteParam();
+            param1.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
+            param1.setCompressionType("Deflate");
+            param1.setCompressionQuality(0.5f);
+
+            ImageWriteParam param2 = writer.getDefaultWriteParam();
+            param2.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
+            param2.setCompressionType("LZW");
+            param2.setCompressionQuality(0.5f);
+
+            IIOMetadata
+                md1 = writer.getDefaultImageMetadata(
+                    new ImageTypeSpecifier(img1), param1),
+                md2 = writer.getDefaultImageMetadata(
+                    new ImageTypeSpecifier(img2), param2);
+
+            TIFFDirectory
+                dir1 = TIFFDirectory.createFromMetadata(md1),
+                dir2 = TIFFDirectory.createFromMetadata(md2);
+
+            addASCIIField(dir1, "ImageDescription", DESCRIPTION_1, N_DESCRIPTION);
+            addASCIIField(dir2, "ImageDescription", DESCRIPTION_2, N_DESCRIPTION);
+
+            addASCIIField(dir1, "GPSStatus", GPS_DATA, N_GPS);
+            addASCIIField(dir2, "GPSStatus", GPS_DATA, N_GPS);
+
+            addASCIIField(dir1, "DateTimeOriginal", EXIF_DATA_1, N_EXIF);
+            addASCIIField(dir2, "DateTimeOriginal", EXIF_DATA_2, N_EXIF);
+
+            TIFFTag faxTag = new TIFFTag(
+                "CleanFaxData", N_FAX, 1 << TIFFTag.TIFF_SHORT);
+            dir1.addTIFFField(new TIFFField(faxTag, FAX_DATA));
+            dir2.addTIFFField(new TIFFField(faxTag, FAX_DATA));
+
+            dir2.addTIFFField(new TIFFField(
+                new TIFFTag("ICC Profile", N_ICC, 1 << TIFFTag.TIFF_UNDEFINED),
+                TIFFTag.TIFF_UNDEFINED, ICC_PROFILE_2.length, ICC_PROFILE_2));
+
+            writer.prepareWriteSequence(null);
+            writer.writeToSequence(
+                new IIOImage(img1, null, dir1.getAsMetadata()), param1);
+            writer.writeToSequence(
+                new IIOImage(img2, null, dir2.getAsMetadata()), param2);
+            writer.endWriteSequence();
+
+            ios.flush();
+            writer.dispose();
+        }
+        s.close();
+    }
+
+    private void checkBufferedImages(BufferedImage im1, BufferedImage im2) {
+
+        check(im1.getWidth()  == W1, "invalid width for image 1");
+        check(im1.getHeight() == H1, "invalid height for image 1");
+        check(im2.getWidth()  == W2, "invalid width for image 2");
+        check(im2.getHeight() == H2, "invalid height for image 2");
+
+        Color
+            c1 = new Color(im1.getRGB(W1 / 2, H1 / 2)),
+            c2 = new Color(im2.getRGB(W2 / 2, H2 / 2));
+
+        check(c1.equals(C1), "invalid image 1 color");
+        check(c2.equals(C2), "invalid image 2 color");
+    }
+
+    private void readAndCheckImage() throws Exception {
+
+        ImageReader reader = getTIFFReader();
+
+        ImageInputStream s = ImageIO.createImageInputStream(new File(FILENAME));
+        reader.setInput(s, false, true);
+
+        int ni = reader.getNumImages(true);
+        check(ni == 2, "invalid number of images");
+
+        // check TIFFImageReadParam for multipage image
+        TIFFImageReadParam
+            param1 = new TIFFImageReadParam(), param2 = new TIFFImageReadParam();
+
+        param1.addAllowedTagSet(ExifTIFFTagSet.getInstance());
+        param1.addAllowedTagSet(ExifGPSTagSet.getInstance());
+
+        param2.addAllowedTagSet(ExifTIFFTagSet.getInstance());
+        param2.addAllowedTagSet(GeoTIFFTagSet.getInstance());
+
+        // FaxTIFFTagSet is allowed by default
+        param2.removeAllowedTagSet(FaxTIFFTagSet.getInstance());
+
+
+        // read images and metadata
+        IIOImage i1 = reader.readAll(0, param1), i2 = reader.readAll(1, param2);
+        BufferedImage
+            bi1 = (BufferedImage) i1.getRenderedImage(),
+            bi2 = (BufferedImage) i2.getRenderedImage();
+
+        // check rendered images, just in case
+        checkBufferedImages(bi1, bi2);
+
+        TIFFDirectory
+            dir1 = TIFFDirectory.createFromMetadata(i1.getMetadata()),
+            dir2 = TIFFDirectory.createFromMetadata(i2.getMetadata());
+
+        // check ASCII fields
+        checkASCIIField(
+            dir1, "image 1 description", DESCRIPTION_1, N_DESCRIPTION);
+        checkASCIIField(
+            dir2, "image 2 description", DESCRIPTION_2, N_DESCRIPTION);
+
+        checkASCIIField(dir1, "image 1 datetime", EXIF_DATA_1, N_EXIF);
+        checkASCIIField(dir2, "image 2 datetime", EXIF_DATA_2, N_EXIF);
+
+        // check sizes
+        TIFFField f = dir1.getTIFFField(N_WIDTH);
+        check((f.getCount() == 1) && (f.getAsInt(0) == W1),
+            "invalid width field for image 1");
+        f = dir2.getTIFFField(N_WIDTH);
+        check((f.getCount() == 1) && (f.getAsInt(0) == W2),
+            "invalid width field for image 2");
+
+        f = dir1.getTIFFField(N_HEIGHT);
+        check((f.getCount() == 1) && (f.getAsInt(0) == H1),
+            "invalid height field for image 1");
+        f = dir2.getTIFFField(N_HEIGHT);
+        check((f.getCount() == 1) && (f.getAsInt(0) == H2),
+            "invalid height field for image 2");
+
+        // check fax data
+        check(dir1.containsTIFFField(N_FAX), "image 2 TIFF directory " +
+            "must contain clean fax data");
+        f = dir1.getTIFFField(N_FAX);
+        check(
+            (f.getCount() == 1) && f.isIntegral() && (f.getAsInt(0) == FAX_DATA),
+            "invalid clean fax data");
+
+        check(!dir2.containsTIFFField(N_FAX), "image 2 TIFF directory " +
+            "must not contain fax fields");
+
+        // check GPS data
+        checkASCIIField(dir1, "GPS status", GPS_DATA, N_GPS);
+
+        check(!dir2.containsTIFFField(N_GPS), "image 2 TIFF directory " +
+            "must not contain GPS fields");
+
+        // check ICC profile data
+        check(!dir1.containsTIFFField(N_ICC), "image 1 TIFF directory "
+            + "must not contain ICC Profile field");
+        check(dir2.containsTIFFField(N_ICC), "image 2 TIFF directory "
+            + "must contain ICC Profile field");
+
+        f = dir2.getTIFFField(N_ICC);
+        check(f.getType() == TIFFTag.TIFF_UNDEFINED,
+            "invalid ICC profile field type");
+        int cnt = f.getCount();
+        byte icc[] = f.getAsBytes();
+        check((cnt == ICC_PROFILE_2.length) && (cnt == icc.length),
+                "invalid ICC profile");
+        for (int i = 0; i < cnt; i++) {
+            check(icc[i] == ICC_PROFILE_2[i], "invalid ICC profile data");
+        }
+
+        // check component sizes
+        check(dir1.getTIFFField(N_BPS).isIntegral() &&
+              dir2.getTIFFField(N_BPS).isIntegral(),
+              "invalid bits per sample type");
+        int sz1[] = bi1.getColorModel().getComponentSize(),
+            sz2[] = bi2.getColorModel().getComponentSize(),
+            bps1[] = dir1.getTIFFField(N_BPS).getAsInts(),
+            bps2[] = dir2.getTIFFField(N_BPS).getAsInts();
+
+        check((bps1.length == sz1.length) && (bps2.length == sz2.length),
+            "invalid component size count");
+
+        for (int i = 0; i < bps1.length; i++) {
+            check(bps1[i] == sz1[i], "image 1: invalid bits per sample data");
+        }
+
+        for (int i = 0; i < bps2.length; i++) {
+            check(bps2[i] == sz2[i], "image 2: invalid bits per sample data");
+        }
+
+        // check compression data
+        check(dir1.containsTIFFField(N_COMPRESSION) &&
+              dir2.containsTIFFField(N_COMPRESSION),
+              "compression info lost");
+        f = dir1.getTIFFField(N_COMPRESSION);
+        check(f.isIntegral() && (f.getCount() == 1) &&
+            (f.getAsInt(0) == COMPRESSION_1), "invalid image 1 compression data");
+
+        f = dir2.getTIFFField(N_COMPRESSION);
+        check(f.isIntegral() && (f.getCount() == 1) &&
+            (f.getAsInt(0) == COMPRESSION_2), "invalid image 2 compression data");
+
+        // check photometric interpretation
+        f = dir1.getTIFFField(N_PHOTO);
+        check(f.isIntegral() && (f.getCount() == 1) &&
+            ((f.getAsInt(0) == GRAY_1) || (f.getAsInt(0) == GRAY_2)),
+            "invalid photometric interpretation for image 1");
+
+        f = dir2.getTIFFField(N_PHOTO);
+        check(f.isIntegral() && (f.getCount() == 1) && (f.getAsInt(0) == RGB),
+            "invalid photometric interpretation for image 2");
+    }
+
+    public void run() {
+
+        try {
+            writeImage();
+            readAndCheckImage();
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private void check(boolean ok, String msg) {
+
+        if (!ok) { throw new RuntimeException(msg); }
+    }
+
+    public static void main(String[] args) {
+        (new MultiPageImageTIFFFieldTest()).run();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/imageio/plugins/tiff/TIFFDirectoryTest.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,266 @@
+/*
+ * 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     8149028
+ * @author  a.stepanov
+ * @summary some simple checks for TIFFDirectory
+ * @run     main TIFFDirectoryTest
+ */
+
+import java.util.List;
+import java.util.ArrayList;
+import javax.imageio.metadata.*;
+import javax.imageio.plugins.tiff.*;
+
+
+public class TIFFDirectoryTest {
+
+    private static void check(boolean ok, String msg) {
+        if (!ok) { throw new RuntimeException(msg); }
+    }
+
+    private void run() {
+
+        int type = TIFFTag.TIFF_LONG, dt = 1 << type;
+        int n0 = 1000, n1 = 1001, n2 = 1002, n3 = 1003;
+
+        TIFFTag tag1 = new TIFFTag(Integer.toString(n1), n1, dt);
+        TIFFTag tag2 = new TIFFTag(Integer.toString(n2), n2, dt);
+        TIFFTag tag3 = new TIFFTag(Integer.toString(n3), n3, dt);
+        TIFFTag parent = new TIFFTag(Integer.toString(n0), n0, dt);
+
+        // tag sets array must not be null
+        boolean ok = false;
+        try { new TIFFDirectory(null, parent); }
+        catch (NullPointerException e) { ok = true; }
+        check(ok, "can construct TIFFDirectory with null tagsets array");
+
+        // but can be empty
+        TIFFTagSet emptySets[] = {};
+        TIFFDirectory d = new TIFFDirectory(emptySets, parent);
+        check(d.getTagSets().length == 0, "invalid number of tag sets");
+        check(d.getParentTag().getName().equals(Integer.toString(n0)) &&
+             (d.getParentTag().getNumber() == n0), "invalid parent tag");
+
+
+        // add tags
+        List<TIFFTag> tags = new ArrayList<>();
+        tags.add(tag1);
+        tags.add(tag2);
+        TIFFTagSet ts1 = new TIFFTagSet(tags);
+
+        tags.clear();
+        tags.add(tag3);
+        TIFFTagSet ts2 = new TIFFTagSet(tags);
+
+        TIFFTagSet sets[] = {ts1, ts2};
+        d = new TIFFDirectory(sets, parent);
+
+        check(d.getTagSets().length == sets.length, "invalid number of tag sets");
+
+        // check getTag()
+        for (int i = n1; i <= n3; i++) {
+            TIFFTag t = d.getTag(i);
+            check(t.getNumber() == i, "invalid tag number");
+            check(t.getName().equals(Integer.toString(i)), "invalid tag name");
+            check(t.getDataTypes() == dt, "invalid tag data types");
+        }
+
+        TIFFDirectory d2;
+        try { d2 = d.clone(); }
+        catch (CloneNotSupportedException e) { throw new RuntimeException(e); }
+
+        // check removeTagSet()
+        d.removeTagSet(ts2);
+        check(d.getTagSets().length == 1, "invalid number of tag sets");
+        check(d.getTagSets()[0].getTag(n1).getName().equals(Integer.toString(n1)),
+            "invalid tag name");
+        check(d.getTagSets()[0].getTag(n2).getName().equals(Integer.toString(n2)),
+            "invalid tag name");
+
+        d.removeTagSet(ts1);
+        check(d.getTagSets().length == 0, "invalid number of tag sets");
+
+        // check cloned data
+        check(d2.getTagSets().length == sets.length,
+            "invalid number of tag sets");
+        TIFFTagSet sets2[] = d2.getTagSets();
+        check(sets2.length == sets.length, "invalid number of tag sets");
+        check(
+            (sets2[0].getTag(Integer.toString(n1)).getNumber() == n1) &&
+            (sets2[0].getTag(Integer.toString(n2)).getNumber() == n2) &&
+            (sets2[0].getTag(Integer.toString(n0)) == null) &&
+            (sets2[1].getTag(Integer.toString(n3)).getNumber() == n3) &&
+            (sets2[1].getTag(Integer.toString(n0)) == null), "invalid data");
+
+        check(
+            (sets2[0].getTag(Integer.toString(n1)).getDataTypes() == dt) &&
+            (sets2[0].getTag(Integer.toString(n2)).getDataTypes() == dt) &&
+            (sets2[1].getTag(Integer.toString(n3)).getDataTypes() == dt),
+            "invalid data type");
+
+        // must not be able to call removeTagSet with null argument
+        ok = false;
+        try { d.removeTagSet(null); }
+        catch (NullPointerException e) { ok = true; }
+        check(ok, "must not be able to use null as an argument for remove");
+
+        // check parent tag
+        check( d.getParentTag().getName().equals(Integer.toString(n0)) &&
+              d2.getParentTag().getName().equals(Integer.toString(n0)),
+            "invalid parent tag name");
+
+        check(( d.getParentTag().getNumber() == n0) &&
+              (d2.getParentTag().getNumber() == n0),
+            "invalid parent tag number");
+
+        check(( d.getParentTag().getDataTypes() == dt) &&
+              (d2.getParentTag().getDataTypes() == dt),
+            "invalid parent data type");
+
+        d.addTagSet(ts1);
+        d.addTagSet(ts2);
+
+        // add the same tag set twice and check that nothing changed
+        d.addTagSet(ts2);
+
+        check(d.getTagSets().length == 2, "invalid number of tag sets");
+
+        // check field operations
+        check(d.getNumTIFFFields() == 0, "invalid TIFFFields number");
+        check(d.getTIFFField(Integer.MAX_VALUE) == null,
+            "must return null TIFFField");
+
+        long offset = 4L;
+        long a[] = {Long.MIN_VALUE, 0, Long.MAX_VALUE};
+        int v = 100500;
+        TIFFField
+                f1 = new TIFFField(tag1, type, offset, d),
+                f2 = new TIFFField(tag2, v),
+                f3 = new TIFFField(tag3, type, a.length, a);
+
+        d.addTIFFField(f1);
+        d.addTIFFField(f2);
+        d.addTIFFField(f3);
+
+        check(d.containsTIFFField(n1) &&
+              d.containsTIFFField(n2) &&
+              d.containsTIFFField(n3) &&
+             !d.containsTIFFField(n0), "invalid containsTIFFField() results");
+
+        check(d.getTIFFField(n0) == null, "can get unadded field");
+
+        check(d.getNumTIFFFields() == 3, "invalid TIFFFields number");
+
+        check(d.getTIFFField(n1).getCount() == 1, "invalid TIFFField count");
+        check(d.getTIFFField(n1).getAsLong(0) == offset, "invalid offset");
+
+        check(d.getTIFFField(n2).getCount() == 1, "invalid TIFFField count");
+        check(d.getTIFFField(n2).getAsInt(0) == v, "invalid TIFFField value");
+
+        check(d.getTIFFField(n3).getCount() == a.length,
+            "invalid TIFFField count");
+        for (int i = 0; i < a.length; ++i) {
+            check(d.getTIFFField(n3).getAsLong(i) == a[i],
+                "invalid TIFFField value");
+        }
+
+        TIFFField nested = d.getTIFFField(n1).getDirectory().getTIFFField(n1);
+        check(nested.getTag().getNumber() == n1, "invalid tag number");
+        check(nested.getCount() == 1, "invalid field count");
+        check(nested.getAsLong(0) == offset, "invalid offset");
+
+        // check that the field is overwritten correctly
+        int v2 = 1 << 16;
+        d.addTIFFField(new TIFFField(tag3, v2));
+        check(d.getTIFFField(n3).getCount() == 1, "invalid TIFFField count");
+        check(d.getTIFFField(n3).getAsInt(0)== v2, "invalid TIFFField value");
+        check(d.getNumTIFFFields() == 3, "invalid TIFFFields number");
+
+        // check removeTIFFField()
+        d.removeTIFFField(n3);
+        check(d.getNumTIFFFields() == 2, "invalid TIFFFields number");
+        check(d.getTIFFField(n3) == null, "can get removed field");
+
+        d.removeTIFFFields();
+        check((d.getTIFFField(n1) == null) && (d.getTIFFField(n2) == null),
+            "can get removed field");
+        check((d.getNumTIFFFields() == 0) && (d.getTIFFFields().length == 0),
+            "invalid TIFFFields number");
+
+        // check that array returned by getTIFFFields() is sorted
+        // by tag number (as it stated in the docs)
+        d.addTIFFField(f3);
+        d.addTIFFField(f1);
+        d.addTIFFField(f2);
+
+        TIFFField fa[] = d.getTIFFFields();
+        check(fa.length == 3, "invalid number of fields");
+        check((fa[0].getTagNumber() == n1) &&
+              (fa[1].getTagNumber() == n2) &&
+              (fa[2].getTagNumber() == n3),
+            "array of the fields must be sorted by tag number");
+
+        d.removeTIFFFields();
+        d.addTIFFField(f2);
+
+        // test getAsMetaData / createFromMetadata
+        try {
+            d2 = TIFFDirectory.createFromMetadata(d.getAsMetadata());
+        } catch (IIOInvalidTreeException e) {
+            throw new RuntimeException(e);
+        }
+
+        // check new data
+        check(d2.getTagSets().length == sets.length,
+            "invalid number of tag sets");
+        sets2 = d2.getTagSets();
+        check(sets2.length == sets.length, "invalid number of tag sets");
+        check(
+            (sets2[0].getTag(Integer.toString(n1)).getNumber() == n1) &&
+            (sets2[0].getTag(Integer.toString(n2)).getNumber() == n2) &&
+            (sets2[0].getTag(Integer.toString(n0)) == null) &&
+            (sets2[1].getTag(Integer.toString(n3)).getNumber() == n3) &&
+            (sets2[1].getTag(Integer.toString(n0)) == null), "invalid data");
+
+        check(
+            (sets2[0].getTag(Integer.toString(n1)).getDataTypes() == dt) &&
+            (sets2[0].getTag(Integer.toString(n2)).getDataTypes() == dt) &&
+            (sets2[1].getTag(Integer.toString(n3)).getDataTypes() == dt),
+            "invalid data type");
+
+        check(!d2.containsTIFFField(n1) &&
+               d2.containsTIFFField(n2) &&
+              !d2.containsTIFFField(n3), "invalid containsTIFFField() results");
+        check(d2.getTIFFField(n2).getCount()  == 1, "invalid TIFFField count");
+        check(d2.getTIFFField(n2).getAsInt(0) == v, "invalid TIFFField value");
+
+        check((d2.getParentTag().getNumber() == n0) &&
+               d2.getParentTag().getName().equals(Integer.toString(n0)),
+               "invalid parent tag");
+    }
+
+    public static void main(String[] args) { (new TIFFDirectoryTest()).run(); }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/imageio/plugins/tiff/TIFFDirectoryWriteReadTest.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,256 @@
+/*
+ * 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     8149028
+ * @author  a.stepanov
+ * @summary a simple write-read test for TIFFDirectory
+ * @run     main TIFFDirectoryWriteReadTest
+ */
+
+import java.awt.*;
+import java.awt.color.*;
+import java.awt.image.BufferedImage;
+import java.io.*;
+import javax.imageio.*;
+import javax.imageio.metadata.*;
+import javax.imageio.stream.*;
+import javax.imageio.plugins.tiff.*;
+
+
+public class TIFFDirectoryWriteReadTest {
+
+    private final static String FILENAME = "test.tiff";
+    private final static int SZ = 100;
+    private final static Color C = Color.RED;
+
+    private static final String COPYRIGHT[] = {"Copyright 123ABC.."};
+    private static final String DESCRIPTION[] = {"Test Image", "Description"};
+    private static final String SOFTWARE[] = {"test", "software", "123"};
+
+    private static final long RES_X[][] = {{2, 1}}, RES_Y[][] = {{1, 1}};
+
+    private static final byte[] ICC_PROFILE =
+        ICC_ProfileRGB.getInstance(ColorSpace.CS_sRGB).getData();
+
+
+    private ImageWriter getTIFFWriter() {
+
+        java.util.Iterator<ImageWriter> writers =
+            ImageIO.getImageWritersByFormatName("TIFF");
+        if (!writers.hasNext()) {
+            throw new RuntimeException("No writers available for TIFF format");
+        }
+        return writers.next();
+    }
+
+    private ImageReader getTIFFReader() {
+
+        java.util.Iterator<ImageReader> readers =
+            ImageIO.getImageReadersByFormatName("TIFF");
+        if (!readers.hasNext()) {
+            throw new RuntimeException("No readers available for TIFF format");
+        }
+        return readers.next();
+    }
+
+    private void addASCIIField(TIFFDirectory d,
+                               String        name,
+                               String        data[],
+                               int           num) {
+
+        d.addTIFFField(new TIFFField(
+            new TIFFTag(name, num, 1 << TIFFTag.TIFF_ASCII),
+                TIFFTag.TIFF_ASCII, data.length, data));
+    }
+
+    private void checkASCIIField(TIFFDirectory d,
+                                 String        what,
+                                 String        data[],
+                                 int           num) {
+
+        String notFound = what + " field was not found";
+        check(d.containsTIFFField(num), notFound);
+        TIFFField f = d.getTIFFField(num);
+        check(f.getType() == TIFFTag.TIFF_ASCII, "field type != ASCII");
+        check(f.getCount() == data.length, "invalid " + what + " data count");
+        for (int i = 0; i < data.length; i++) {
+            check(f.getValueAsString(i).equals(data[i]),
+                "invalid " + what + " data");
+        }
+    }
+
+    private void writeImage() throws Exception {
+
+        OutputStream s = new BufferedOutputStream(new FileOutputStream(FILENAME));
+        try (ImageOutputStream ios = ImageIO.createImageOutputStream(s)) {
+
+            ImageWriter writer = getTIFFWriter();
+            writer.setOutput(ios);
+
+            BufferedImage img = new BufferedImage(
+                SZ, SZ, BufferedImage.TYPE_INT_RGB);
+            Graphics g = img.getGraphics();
+            g.setColor(C);
+            g.fillRect(0, 0, SZ, SZ);
+            g.dispose();
+
+            IIOMetadata metadata = writer.getDefaultImageMetadata(
+                new ImageTypeSpecifier(img), writer.getDefaultWriteParam());
+
+            TIFFDirectory dir = TIFFDirectory.createFromMetadata(metadata);
+
+            addASCIIField(dir, "Copyright",
+                COPYRIGHT, BaselineTIFFTagSet.TAG_COPYRIGHT);
+
+            addASCIIField(dir, "ImageDescription",
+                DESCRIPTION, BaselineTIFFTagSet.TAG_IMAGE_DESCRIPTION);
+
+            addASCIIField(dir, "Software",
+                SOFTWARE, BaselineTIFFTagSet.TAG_SOFTWARE);
+
+            dir.addTIFFField(new TIFFField(
+                new TIFFTag("XResolution", BaselineTIFFTagSet.TAG_X_RESOLUTION,
+                1 << TIFFTag.TIFF_RATIONAL), TIFFTag.TIFF_RATIONAL, 1, RES_X));
+            dir.addTIFFField(new TIFFField(
+                new TIFFTag("YResolution", BaselineTIFFTagSet.TAG_Y_RESOLUTION,
+                1 << TIFFTag.TIFF_RATIONAL), TIFFTag.TIFF_RATIONAL, 1, RES_Y));
+
+            dir.addTIFFField(new TIFFField(
+            new TIFFTag("ICC Profile", BaselineTIFFTagSet.TAG_ICC_PROFILE,
+                1 << TIFFTag.TIFF_UNDEFINED),
+                TIFFTag.TIFF_UNDEFINED, ICC_PROFILE.length, ICC_PROFILE));
+
+            IIOMetadata data = dir.getAsMetadata();
+            writer.write(new IIOImage(img, null, data));
+
+            ios.flush();
+            writer.dispose();
+        }
+        s.close();
+    }
+
+
+
+    private void readAndCheckImage() throws Exception {
+
+        ImageReader reader = getTIFFReader();
+
+        ImageInputStream s = ImageIO.createImageInputStream(new File(FILENAME));
+        reader.setInput(s);
+
+        int ni = reader.getNumImages(true);
+        check(ni == 1, "invalid number of images");
+
+        // check image
+        BufferedImage img = reader.read(0);
+        check(img.getWidth() == SZ && img.getHeight() == SZ,
+            "invalid image size");
+
+        Color c = new Color(img.getRGB(SZ / 2, SZ / 2));
+        check(C.equals(c), "invalid image color");
+
+        IIOMetadata metadata = reader.readAll(0, null).getMetadata();
+        TIFFDirectory dir = TIFFDirectory.createFromMetadata(metadata);
+
+        reader.dispose();
+        s.close();
+
+        // ===== perform tag checks =====
+
+        checkASCIIField(dir, "copyright", COPYRIGHT,
+            BaselineTIFFTagSet.TAG_COPYRIGHT);
+
+        checkASCIIField(dir, "description", DESCRIPTION,
+            BaselineTIFFTagSet.TAG_IMAGE_DESCRIPTION);
+
+        checkASCIIField(dir, "software", SOFTWARE,
+            BaselineTIFFTagSet.TAG_SOFTWARE);
+
+        TIFFField f = dir.getTIFFField(BaselineTIFFTagSet.TAG_IMAGE_WIDTH);
+        check(f.getCount() == 1, "invalid width field count");
+        int w = f.getAsInt(0);
+        check(w == SZ, "invalid width");
+
+        f = dir.getTIFFField(BaselineTIFFTagSet.TAG_IMAGE_LENGTH);
+        check(f.getCount() == 1, "invalid height field count");
+        int h = f.getAsInt(0);
+        check(h == SZ, "invalid height");
+
+        f = dir.getTIFFField(BaselineTIFFTagSet.TAG_BITS_PER_SAMPLE);
+        // RGB: 3 x 8 bits for R, G and B components
+        int bps[] = f.getAsInts();
+        check((f.getCount() == 3) && (bps.length == 3), "invalid BPS count");
+        for (int b: bps) { check(b == 8, "invalid bits per sample"); }
+
+        // RGB: PhotometricInterpretation = 2
+        f = dir.getTIFFField(BaselineTIFFTagSet.TAG_PHOTOMETRIC_INTERPRETATION);
+        check(f.getCount() == 1, "invalid count");
+        check(f.getAsInt(0) == BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_RGB,
+            "invalid photometric interpretation value");
+
+        String rat = " resolution must be rational";
+        f = dir.getTIFFField(BaselineTIFFTagSet.TAG_X_RESOLUTION);
+        check(f.getType() == TIFFTag.TIFF_RATIONAL, "x" + rat);
+        check(f.getCount() == 1 &&
+              f.getAsInt(0) == (int) (RES_X[0][0] / RES_X[0][1]),
+              "invalid x resolution");
+
+        f = dir.getTIFFField(BaselineTIFFTagSet.TAG_Y_RESOLUTION);
+        check(f.getType() == TIFFTag.TIFF_RATIONAL, "y" + rat);
+        check(f.getCount() == 1 &&
+              f.getAsInt(0) == (int) (RES_Y[0][0] / RES_Y[0][1]),
+              "invalid y resolution");
+
+        f = dir.getTIFFField(BaselineTIFFTagSet.TAG_ICC_PROFILE);
+        check(f.getType() == TIFFTag.TIFF_UNDEFINED,
+            "invalid ICC profile field type");
+        int cnt = f.getCount();
+        byte icc[] = f.getAsBytes();
+        check((cnt == ICC_PROFILE.length) && (cnt == icc.length),
+                "invalid ICC profile");
+        for (int i = 0; i < cnt; i++) {
+            check(icc[i] == ICC_PROFILE[i], "invalid ICC profile");
+        }
+    }
+
+    public void run() {
+
+        try {
+            writeImage();
+            readAndCheckImage();
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+
+    }
+
+    private void check(boolean ok, String msg) {
+        if (!ok) { throw new RuntimeException(msg); }
+    }
+
+    public static void main(String[] args) {
+        (new TIFFDirectoryWriteReadTest()).run();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/imageio/plugins/tiff/TIFFFieldTest.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,502 @@
+/*
+ * 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     8152183
+ * @author  a.stepanov
+ * @summary Some checks for TIFFField methods
+ * @run     main TIFFFieldTest
+ */
+
+import java.util.List;
+import java.util.ArrayList;
+import javax.imageio.metadata.IIOMetadataNode;
+import javax.imageio.plugins.tiff.*;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+
+public class TIFFFieldTest {
+
+    private final static String NAME = "tag"; // tag name
+    private final static int    NUM  = 12345; // tag number
+    private final static int MIN_TYPE = TIFFTag.MIN_DATATYPE;
+    private final static int MAX_TYPE = TIFFTag.MAX_DATATYPE;
+    private final static String CONSTRUCT = "can construct TIFFField with ";
+
+    private void check(boolean ok, String msg) {
+        if (!ok) { throw new RuntimeException(msg); }
+    }
+
+    private void testConstructors() {
+
+        // test constructors
+
+        TIFFTag tag = new TIFFTag(
+            NAME, NUM, 1 << TIFFTag.TIFF_SHORT | 1 << TIFFTag.TIFF_LONG);
+        TIFFField f;
+
+        // constructor: TIFFField(tag, value)
+        boolean ok = false;
+        try { new TIFFField(null, 0); }
+        catch (NullPointerException e) { ok = true; }
+        check(ok, CONSTRUCT + "null tag");
+
+        ok = false;
+        try { new TIFFField(tag, -1); }
+        catch (IllegalArgumentException e) { ok = true; }
+        check(ok, CONSTRUCT + "invalid count");
+
+        // check value type recognition
+        int v = 1 << 16;
+        f = new TIFFField(tag, v - 1);
+        check(f.getType() == TIFFTag.TIFF_SHORT, "must be treated as short");
+        check(f.isIntegral(), "must be integral");
+        f = new TIFFField(tag, v);
+        check(f.getType() == TIFFTag.TIFF_LONG, "must be treated as long");
+
+        // other checks
+        check(f.getAsLongs().length == 1, "invalid long[] size");
+        check(f.isIntegral(), "must be integral");
+        check((f.getDirectory() == null) && !f.hasDirectory(),
+            "must not have directory");
+        check(f.getValueAsString(0).equals(String.valueOf(v)),
+            "invalid string representation of value");
+        check(f.getTag().getNumber() == f.getTagNumber(),
+            "invalid tag number");
+        check(f.getCount() == 1, "invalid count");
+        check(f.getTagNumber() == NUM, "invalid tag number");
+
+        // constructor: TIFFField(tag, type, count)
+        int type = TIFFTag.TIFF_SHORT;
+
+        ok = false;
+        try { new TIFFField(null, type, 1); }
+        catch (NullPointerException e) { ok = true; }
+        check(ok, CONSTRUCT + "null tag");
+
+        ok = false;
+        try { new TIFFField(tag, MAX_TYPE + 1, 1); }
+        catch (IllegalArgumentException e) { ok = true; }
+        check(ok, CONSTRUCT + "invalid type tag");
+
+        // check that count == 1 for TIFF_IFD_POINTER
+        ok = false;
+        try { new TIFFField(tag, TIFFTag.TIFF_IFD_POINTER, 0); }
+        catch (IllegalArgumentException e) { ok = true; }
+        check(ok, "only count = 1 should be allowed for IFDPointer");
+
+        ok = false;
+        try { new TIFFField(tag, TIFFTag.TIFF_IFD_POINTER, 2); }
+        catch (IllegalArgumentException e) { ok = true; }
+        check(ok, "only count = 1 should be allowed for IFDPointer");
+
+        // check that count == 0 is not allowed for TIFF_RATIONAL, TIFF_SRATIONAL
+        // (see fix for JDK-8149120)
+        ok = false;
+        try { new TIFFField(tag, TIFFTag.TIFF_RATIONAL, 0); }
+        catch (IllegalArgumentException e) { ok = true; }
+        check(ok, "count = 0 should not be allowed for Rational");
+
+        ok = false;
+        try { new TIFFField(tag, TIFFTag.TIFF_SRATIONAL, 0); }
+        catch (IllegalArgumentException e) { ok = true; }
+        check(ok, "count = 0 should not be allowed for SRational");
+
+        ok = false;
+        try { new TIFFField(tag, type, -1); }
+        catch (IllegalArgumentException e) { ok = true; }
+        check(ok, CONSTRUCT + "with invalid data count");
+
+        f = new TIFFField(tag, type, 0);
+        check(f.getCount() == 0, "invalid count");
+        check(!f.hasDirectory(), "must not have directory");
+
+        // constructor: TIFFField(tag, type, count, data)
+        double a[] = {0.1, 0.2, 0.3};
+        ok = false;
+        try { new TIFFField(null, TIFFTag.TIFF_DOUBLE, a.length, a); }
+        catch (NullPointerException e) { ok = true; }
+        check(ok, CONSTRUCT + "null tag");
+
+        ok = false;
+        try { new TIFFField(tag, type, a.length - 1, a); }
+        catch (IllegalArgumentException e) { ok = true; }
+        check(ok, CONSTRUCT + "invalid data count");
+
+        String a2[] = {"one", "two"};
+        ok = false;
+        try { new TIFFField(tag, type, 2, a2); }
+        catch (IllegalArgumentException e) { ok = true; }
+        check(ok, CONSTRUCT + "invalid data type");
+        check((f.getDirectory() == null) && !f.hasDirectory(),
+            "must not have directory");
+
+        // constructor: TIFFField(tag, type, offset, dir)
+        List<TIFFTag> tags = new ArrayList<>();
+        tags.add(tag);
+        TIFFTagSet sets[] = {new TIFFTagSet(tags)};
+        TIFFDirectory dir = new TIFFDirectory(sets, null);
+
+        ok = false;
+        try { new TIFFField(null, type, 4L, dir); }
+        catch (NullPointerException e) { ok = true; }
+        check(ok, CONSTRUCT + "null tag");
+
+        ok = false;
+        try { new TIFFField(tag, type, 0L, dir); }
+        catch (IllegalArgumentException e) { ok = true; }
+        check(ok, CONSTRUCT + "non-positive offset");
+
+        long offset = 4;
+
+        for (int t = MIN_TYPE; t <= MAX_TYPE; t++) {
+
+            tag = new TIFFTag(NAME, NUM, 1 << t);
+
+            // only TIFF_LONG and TIFF_IFD_POINTER types are allowed
+            if (t == TIFFTag.TIFF_LONG || t == TIFFTag.TIFF_IFD_POINTER) {
+
+                f = new TIFFField(tag, t, offset, dir);
+                check(f.hasDirectory(), "must have directory");
+
+                check(f.getDirectory().getTag(NUM).getName().equals(NAME),
+                    "invalid tag name");
+
+                check(f.getCount() == 1, "invalid count");
+                check(f.getAsLong(0) == offset, "invalid offset");
+            } else {
+                ok = false;
+                try { new TIFFField(tag, t, offset, dir); }
+                catch (IllegalArgumentException e) { ok = true; }
+                check(ok, CONSTRUCT + "invalid data type");
+            }
+        }
+
+        type = TIFFTag.TIFF_IFD_POINTER;
+        tag = new TIFFTag(NAME, NUM, 1 << type);
+        ok = false;
+        try { new TIFFField(tag, type, offset, null); }
+        catch (NullPointerException e) { ok = true; }
+        check(ok, CONSTRUCT + "null TIFFDirectory");
+
+        type = TIFFTag.TIFF_LONG;
+        tag = new TIFFTag(NAME, NUM, 1 << type);
+        ok = false;
+        try { new TIFFField(tag, type, offset, null); }
+        catch (NullPointerException e) { ok = true; }
+        check(ok, CONSTRUCT + "null TIFFDirectory");
+    }
+
+    private void testTypes() {
+
+        // test getTypeName(), getTypeByName() methods
+
+        boolean ok = false;
+        try { TIFFField.getTypeName(MIN_TYPE - 1); }
+        catch (IllegalArgumentException e) { ok = true; }
+        check(ok, "invalid data type number used");
+
+        ok = false;
+        try { TIFFField.getTypeName(MAX_TYPE + 1); }
+        catch (IllegalArgumentException e) { ok = true; }
+        check(ok, "invalid data type number used");
+
+        for (int type = MIN_TYPE; type <= MAX_TYPE; type++) {
+            String name = TIFFField.getTypeName(type);
+            check(TIFFField.getTypeByName(name) == type, "invalid type");
+        }
+
+        for (int type = MIN_TYPE; type <= MAX_TYPE; type++) {
+
+            TIFFTag tag = new TIFFTag(NAME, NUM, 1 << type);
+            TIFFField f = new TIFFField(tag, type, 1);
+            check(f.getType() == type, "invalid type");
+
+            // check that invalid data types can not be used
+            for (int type2 = MIN_TYPE; type2 <= MAX_TYPE; ++type2) {
+                if (type2 != type) {
+                    ok = false;
+                    try { new TIFFField(tag, type2, 1); } // invalid type
+                    catch (IllegalArgumentException e) { ok = true; }
+                    check(ok, "invalid type was successfully set");
+                }
+            }
+        }
+    }
+
+    private void testGetAs() {
+
+        // test getAs...() methods
+
+        int type = TIFFTag.TIFF_SHORT;
+        TIFFTag tag = new TIFFTag(NAME, NUM, 1 << TIFFTag.TIFF_SHORT);
+
+        short v = 123;
+        TIFFField f = new TIFFField(tag, v);
+
+        check(f.getAsInt(0)    ==    (int) v, "invalid int value");
+        check(f.getAsLong(0)   ==   (long) v, "invalid long value");
+        check(f.getAsFloat(0)  ==  (float) v, "invalid float value");
+        check(f.getAsDouble(0) == (double) v, "invalid double value");
+        check(f.getValueAsString(0).equals(Short.toString(v)),
+            "invalid string representation");
+
+        check(f.getAsInts().length == 1, "inavlid array size");
+        check((int) v == f.getAsInts()[0], "invalid int value");
+
+        float fa[] = {0.01f, 1.01f};
+        type = TIFFTag.TIFF_FLOAT;
+        f = new TIFFField(
+            new TIFFTag(NAME, NUM, 1 << type), type, fa.length, fa);
+        check(f.getCount() == fa.length, "invalid count");
+        float fa2[] = f.getAsFloats();
+        check(fa2.length == fa.length, "invalid array size");
+
+        for (int i = 0; i < fa.length; i++) {
+            check(fa2[i] == fa[i], "invalid value");
+            check(f.getAsDouble(i) == fa[i], "invalid value");
+            check(f.getAsInt(i) == (int) fa[i], "invalid value"); // cast to int
+            check(f.getValueAsString(i).equals(Float.toString(fa[i])),
+            "invalid string representation");
+        }
+
+        byte ba[] = {-1, -10, -100};
+        type = TIFFTag.TIFF_BYTE;
+        f = new TIFFField(
+            new TIFFTag(NAME, NUM, 1 << type), type, ba.length, ba);
+        check(f.getCount() == ba.length, "invalid count");
+        byte ba2[] = f.getAsBytes();
+        check(ba2.length == ba.length, "invalid count");
+
+        for (int i = 0; i < ba.length; i++) {
+            check(ba[i] == ba2[i], "invalid value");
+            check(ba[i] == (byte) f.getAsDouble(i), "invalid value");
+            check(ba[i] == (byte) f.getAsLong(i),   "invalid value");
+
+            int unsigned = ba[i] & 0xff;
+            check(f.getAsInt(i) == unsigned, "must be treated as unsigned");
+        }
+
+        char ca[] = {'a', 'z', 0xffff};
+        type = TIFFTag.TIFF_SHORT;
+        f = new TIFFField(
+            new TIFFTag(NAME, NUM, 1 << type), type, ca.length, ca);
+        check(f.getCount() == ca.length, "invalid count");
+        char ca2[] = f.getAsChars();
+        check(ba2.length == ba.length, "invalid count");
+
+        for (int i = 0; i < ca.length; i++) {
+            check(ca[i] == ca2[i], "invalid value");
+            check(ca[i] == (char) f.getAsDouble(i), "invalid value");
+            check(ca[i] == (char) f.getAsLong(i), "invalid value");
+            check(ca[i] == (char) f.getAsInt(i), "invalid value");
+        }
+
+        type = TIFFTag.TIFF_DOUBLE;
+        double da[] = {0.1, 0.2, 0.3};
+        f = new TIFFField(
+            new TIFFTag(NAME, NUM, 1 << type), type, da.length, da);
+        check(!f.isIntegral(), "isIntegral must be false");
+
+        double da2[] = f.getAsDoubles();
+        check(f.getData() instanceof double[], "invalid data type");
+        double da3[] = (double[]) f.getData();
+        check((da.length == da2.length) &&
+              (da.length == da2.length) &&
+              (da.length == f.getCount()),
+               "invalid data count");
+        for (int i = 0; i < da.length; ++i) {
+            check(da[i] == da2[i], "invalid data");
+            check(da[i] == da3[i], "invalid data");
+        }
+
+        boolean ok = false;
+        try { f.getAsShorts(); }
+        catch (ClassCastException e) { ok = true; }
+        check(ok, "invalid data cast");
+
+        ok = false;
+        try { f.getAsRationals(); }
+        catch (ClassCastException e) { ok = true; }
+        check(ok, "invalid data cast");
+
+        ok = false;
+        try { TIFFField.createArrayForType(TIFFTag.MIN_DATATYPE - 1, 1); }
+        catch (IllegalArgumentException e) { ok = true; }
+        check(ok, "can create array with invalid datatype");
+
+        ok = false;
+        try { TIFFField.createArrayForType(TIFFTag.MAX_DATATYPE + 1, 1); }
+        catch (IllegalArgumentException e) { ok = true; }
+        check(ok, "can create array with invalid datatype");
+
+        ok = false;
+        try { TIFFField.createArrayForType(TIFFTag.TIFF_FLOAT, -1); }
+        catch (IllegalArgumentException e) { ok = true; }
+        check(ok, "can create array with negative count");
+
+        int n = 3;
+        Object
+            RA  = TIFFField.createArrayForType(TIFFTag.TIFF_RATIONAL,  n),
+            SRA = TIFFField.createArrayForType(TIFFTag.TIFF_SRATIONAL, n);
+        check(RA  instanceof long[][], "invalid data type");
+        check(SRA instanceof  int[][], "invalid data type");
+
+        long ra[][] = (long[][]) RA;
+        int sra[][] = (int[][]) SRA;
+        check((ra.length == n) && (sra.length == n), "invalid data size");
+        for (int i = 0; i < n; i++) {
+            check((ra[i].length == 2) && (sra[i].length == 2),
+                "invalid data size");
+            ra[i][0]  =  1;  ra[i][1]  = 5 + i;
+            sra[i][0] = -1;  sra[i][1] = 5 + i;
+        }
+
+        type = TIFFTag.TIFF_RATIONAL;
+        TIFFField f1 = new TIFFField(
+            new TIFFTag(NAME, NUM, 1 << type), type, n, ra);
+        type = TIFFTag.TIFF_SRATIONAL;
+        TIFFField f2 = new TIFFField(
+            new TIFFTag(NAME, NUM, 1 << type), type, n, sra);
+
+        check((f1.getCount() == ra.length) && (f2.getCount() == sra.length),
+            "invalid data count");
+
+        check(f1.getAsRationals().length  == n, "invalid data count");
+        check(f2.getAsSRationals().length == n, "invalid data count");
+        for (int i = 0; i < n; i++) {
+            long r[] = f1.getAsRational(i);
+            check(r.length == 2, "invalid data format");
+            check((r[0] == 1) && (r[1] == i + 5), "invalid data");
+
+            int sr[] = f2.getAsSRational(i);
+            check(sr.length == 2, "invalid data format");
+            check((sr[0] == -1) && (sr[1] == i + 5), "invalid data");
+
+            // check string representation
+            String s = Long.toString(r[0]) + "/" + Long.toString(r[1]);
+            check(s.equals(f1.getValueAsString(i)),
+                "invalid string representation");
+
+            s = Integer.toString(sr[0]) + "/" + Integer.toString(sr[1]);
+            check(s.equals(f2.getValueAsString(i)),
+                "invalid string representation");
+
+            // see the documentation for getAsInt:
+            // TIFF_SRATIONAL or TIFF_RATIONAL format are evaluated
+            // by dividing the numerator into the denominator using
+            // double-precision arithmetic and then casting to int
+            check(f1.getAsInt(i) == (int)(r[0] / r[1]),
+                "invalid result for getAsInt");
+            check(f2.getAsInt(i) == (int)(r[0] / r[1]),
+                "invalid result for getAsInt");
+        }
+
+        ok = false;
+        try { f1.getAsRational(ra.length); }
+        catch (ArrayIndexOutOfBoundsException e) { ok = true; }
+        check(ok, "invalid index");
+
+        String sa[] = {"-1.e-25", "22", "-1.23E5"};
+        type = TIFFTag.TIFF_ASCII;
+        f = new TIFFField(
+            new TIFFTag(NAME, NUM, 1 << type), type, sa.length, sa);
+
+        // test clone() method
+        TIFFField cloned = null;
+        try { cloned = f.clone(); } catch (CloneNotSupportedException e) {
+            throw new RuntimeException(e);
+        }
+
+        check(f.getCount() == cloned.getCount(), "invalid cloned field count");
+
+        check(f.getCount() == sa.length, "invalid data count");
+        for (int i = 0; i < sa.length; i++) {
+            check(sa[i].equals(f.getAsString(i)), "invalid data");
+            // see docs: "data in TIFF_ASCII format will be parsed as by
+            // the Double.parseDouble method, with the result cast to int"
+            check(f.getAsInt(i) ==
+                (int) Double.parseDouble(sa[i]), "invalid data");
+            check(f.getAsDouble(i) == Double.parseDouble(sa[i]), "invalid data");
+
+            check(sa[i].equals(cloned.getAsString(i)), "invalid cloned data");
+        }
+    }
+
+    private void testCreateFromNode() {
+
+        int type = TIFFTag.TIFF_LONG;
+
+        List<TIFFTag> tags = new ArrayList<>();
+        int v = 1234567;
+        TIFFTag tag = new TIFFTag(NAME, NUM, 1 << type);
+        tags.add(tag);
+        TIFFTagSet ts = new TIFFTagSet(tags);
+
+        boolean ok = false;
+        try { TIFFField.createFromMetadataNode(ts, null); }
+        catch (NullPointerException e) { ok = true; }
+        check(ok, "can create TIFFField from a null node");
+
+        TIFFField f = new TIFFField(tag, v);
+        Node node = f.getAsNativeNode();
+        check(node.getNodeName().equals(f.getClass().getSimpleName()),
+            "invalid node name");
+
+        NamedNodeMap attrs = node.getAttributes();
+        for (int i = 0; i < attrs.getLength(); i++) {
+            String an = attrs.item(i).getNodeName().toLowerCase();
+            String av = attrs.item(i).getNodeValue();
+            if (an.contains("name")) {
+                check(av.equals(NAME), "invalid tag name");
+            } else if (an.contains("number")) {
+                check(av.equals(Integer.toString(NUM)), "invalid tag number");
+            }
+        }
+
+        // invalid node
+        IIOMetadataNode nok = new IIOMetadataNode("NOK");
+
+        ok = false;
+        try { TIFFField.createFromMetadataNode(ts, nok); }
+        catch (IllegalArgumentException e) { ok = true; }
+        check(ok, CONSTRUCT + "invalid node name");
+
+        TIFFField f2 = TIFFField.createFromMetadataNode(ts, node);
+        check(f2.getType() == type, "invalid type");
+        check(f2.getTagNumber() == NUM, "invalid tag number");
+        check(f2.getTag().getName().equals(NAME), "invalid tag name");
+        check(f2.getCount()  == 1, "invalid count");
+        check(f2.getAsInt(0) == v, "invalid value");
+    }
+
+    public static void main(String[] args) {
+
+        TIFFFieldTest test = new TIFFFieldTest();
+        test.testConstructors();
+        test.testCreateFromNode();
+        test.testTypes();
+        test.testGetAs();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/imageio/plugins/tiff/TIFFImageReadParamTest.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,275 @@
+/*
+ * 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     8149028
+ * @author  a.stepanov
+ * @summary check TIFFDirectory manipulation
+ *          by means of TIFFImageReadParam
+ * @run     main TIFFImageReadParamTest
+ */
+
+
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.image.BufferedImage;
+import java.io.*;
+import javax.imageio.*;
+import javax.imageio.metadata.IIOMetadata;
+import javax.imageio.plugins.tiff.*;
+import javax.imageio.stream.ImageInputStream;
+import javax.imageio.stream.ImageOutputStream;
+
+public class TIFFImageReadParamTest {
+
+    private final static String FILENAME = "test.tiff";
+    private final static int SZ = 100;
+    private final static Color C = Color.RED;
+
+    private final static String GEO_DATA = "test params";
+    private final static int GEO_N = GeoTIFFTagSet.TAG_GEO_ASCII_PARAMS;
+
+    private final static String EXIF_DATA = "2000:01:01 00:00:01";
+    private final static int EXIF_N = ExifTIFFTagSet.TAG_DATE_TIME_ORIGINAL;
+
+    private final static String GPS_DATA =
+        ExifGPSTagSet.STATUS_MEASUREMENT_IN_PROGRESS;
+    private final static int GPS_N = ExifGPSTagSet.TAG_GPS_STATUS;
+
+    private final static short FAX_DATA =
+        FaxTIFFTagSet.CLEAN_FAX_DATA_ERRORS_UNCORRECTED;
+    private final static int FAX_N = FaxTIFFTagSet.TAG_CLEAN_FAX_DATA;
+
+    private ImageWriter getTIFFWriter() {
+
+        java.util.Iterator<ImageWriter> writers =
+            ImageIO.getImageWritersByFormatName("TIFF");
+        if (!writers.hasNext()) {
+            throw new RuntimeException("No writers available for TIFF format");
+        }
+        return writers.next();
+    }
+
+    private ImageReader getTIFFReader() {
+
+        java.util.Iterator<ImageReader> readers =
+            ImageIO.getImageReadersByFormatName("TIFF");
+        if (!readers.hasNext()) {
+            throw new RuntimeException("No readers available for TIFF format");
+        }
+        return readers.next();
+    }
+
+    private void check(boolean ok, String msg) {
+        if (!ok) { throw new RuntimeException(msg); }
+    }
+
+    private void addASCIIField(TIFFDirectory d,
+                               String        name,
+                               String        data,
+                               int           num) {
+
+        String a[] = {data};
+        d.addTIFFField(new TIFFField(
+            new TIFFTag(name, num, 1 << TIFFTag.TIFF_ASCII),
+                TIFFTag.TIFF_ASCII, 1, a));
+    }
+
+    private void checkASCIIValue(TIFFDirectory d,
+                                 String        what,
+                                 String        data,
+                                 int           num) {
+
+        TIFFField f = d.getTIFFField(num);
+        check(f.getType() == TIFFTag.TIFF_ASCII, "field type != ASCII");
+        check(f.getCount() == 1, "invalid " + what + " data count");
+        check(f.getValueAsString(0).equals(data),
+            "invalid " + what + " data");
+    }
+
+
+    private void writeImage() throws Exception {
+
+        OutputStream s = new BufferedOutputStream(new FileOutputStream(FILENAME));
+        try (ImageOutputStream ios = ImageIO.createImageOutputStream(s)) {
+            ImageWriter writer = getTIFFWriter();
+            writer.setOutput(ios);
+
+            BufferedImage img =
+                new BufferedImage(SZ, SZ, BufferedImage.TYPE_INT_RGB);
+            Graphics g = img.getGraphics();
+            g.setColor(C);
+            g.fillRect(0, 0, SZ, SZ);
+            g.dispose();
+
+            IIOMetadata metadata = writer.getDefaultImageMetadata(
+                new ImageTypeSpecifier(img), writer.getDefaultWriteParam());
+
+            TIFFDirectory dir = TIFFDirectory.createFromMetadata(metadata);
+
+            // add some extension tags
+            addASCIIField(dir, "GeoAsciiParamsTag", GEO_DATA, GEO_N);
+            addASCIIField(dir, "DateTimeOriginal", EXIF_DATA, EXIF_N);
+            addASCIIField(dir, "GPSStatus", GPS_DATA, GPS_N);
+
+            dir.addTIFFField(new TIFFField(new TIFFTag(
+                "CleanFaxData", FAX_N, 1 << TIFFTag.TIFF_SHORT), FAX_DATA));
+
+            IIOMetadata data = dir.getAsMetadata();
+
+            writer.write(new IIOImage(img, null, data));
+
+            ios.flush();
+            writer.dispose();
+        }
+    }
+
+    private void checkImage(BufferedImage img) {
+
+        check(img.getWidth() == SZ, "invalid image width");
+        check(img.getHeight() == SZ, "invalid image height");
+        Color c = new Color(img.getRGB(SZ / 2, SZ / 2));
+        check(c.equals(C), "invalid image color");
+    }
+
+    private TIFFDirectory getDir(TIFFTagSet[] add,
+                                 TIFFTagSet[] remove) throws Exception {
+
+        ImageReader reader = getTIFFReader();
+
+        ImageInputStream s = ImageIO.createImageInputStream(new File(FILENAME));
+        reader.setInput(s, false, true);
+
+        int ni = reader.getNumImages(true);
+        check(ni == 1, "invalid number of images: " + ni);
+
+        TIFFImageReadParam param = new TIFFImageReadParam();
+        for (TIFFTagSet ts: add) { param.addAllowedTagSet(ts); }
+        for (TIFFTagSet ts: remove) { param.removeAllowedTagSet(ts); }
+
+        IIOImage img = reader.readAll(0, param);
+
+        // just in case, check image
+        checkImage((BufferedImage) img.getRenderedImage());
+
+        IIOMetadata metadata = img.getMetadata();
+        TIFFDirectory dir = TIFFDirectory.createFromMetadata(metadata);
+
+        reader.dispose();
+        s.close();
+
+        return dir;
+    }
+
+    private void simpleChecks() {
+
+        TIFFImageReadParam param = new TIFFImageReadParam();
+
+        java.util.List<TIFFTagSet> allowed = param.getAllowedTagSets();
+
+        // see docs
+        check(allowed.contains(BaselineTIFFTagSet.getInstance()),
+            "must contain BaselineTIFFTagSet");
+        check(allowed.contains(FaxTIFFTagSet.getInstance()),
+            "must contain FaxTIFFTagSet");
+        check(allowed.contains(ExifParentTIFFTagSet.getInstance()),
+            "must contain ExifParentTIFFTagSet");
+        check(allowed.contains(GeoTIFFTagSet.getInstance()),
+            "must contain GeoTIFFTagSet");
+
+        TIFFTagSet gps = ExifGPSTagSet.getInstance();
+        param.addAllowedTagSet(gps);
+        check(param.getAllowedTagSets().contains(gps),
+            "must contain ExifGPSTagSet");
+
+        param.removeAllowedTagSet(gps);
+        check(!param.getAllowedTagSets().contains(gps),
+            "must not contain ExifGPSTagSet");
+
+        // check that repeating remove goes properly
+        param.removeAllowedTagSet(gps);
+
+        boolean ok = false;
+        try { param.addAllowedTagSet(null); }
+        catch (IllegalArgumentException e) { ok = true; }
+        check(ok, "must not be able to add null tag set");
+
+        ok = false;
+        try { param.removeAllowedTagSet(null); }
+        catch (IllegalArgumentException e) { ok = true; }
+        check(ok, "must not be able to remove null tag set");
+    }
+
+    private void run() {
+
+        simpleChecks();
+
+        try {
+
+            writeImage();
+
+            TIFFTagSet
+                empty[] = {},
+                geo[]   = {  GeoTIFFTagSet.getInstance() },
+                exif[]  = { ExifTIFFTagSet.getInstance() },
+                gps[]   = {  ExifGPSTagSet.getInstance() },
+                fax[]   = {  FaxTIFFTagSet.getInstance() };
+
+            // default param state
+            TIFFDirectory dir = getDir(empty, empty);
+            // Geo and Fax are default allowed tag sets
+            check(dir.containsTIFFField(GEO_N), "must contain Geo field");
+            checkASCIIValue(dir, "Geo", GEO_DATA, GEO_N);
+            check(dir.containsTIFFField(FAX_N), "must contain Fax field");
+            check(
+                (dir.getTIFFField(FAX_N).getCount() == 1) &&
+                (dir.getTIFFField(FAX_N).getAsInt(0) == FAX_DATA),
+                "invalid Fax field value");
+
+            // corresponding tag sets are non-default
+            check(!dir.containsTIFFField(EXIF_N), "must not contain Geo field");
+            check(!dir.containsTIFFField(GPS_N), "must not contain GPS field");
+
+            // remove Fax
+            dir = getDir(empty, fax);
+            check(!dir.containsTIFFField(FAX_N), "must not contain Fax field");
+
+            // add EXIF, remove Geo
+            dir = getDir(exif, geo);
+            check(dir.containsTIFFField(EXIF_N), "must contain EXIF field");
+            checkASCIIValue(dir, "EXIF", EXIF_DATA, EXIF_N);
+            check(!dir.containsTIFFField(GEO_N), "must not contain Geo field");
+
+            // add GPS
+            dir = getDir(gps, empty);
+            check(dir.containsTIFFField(GPS_N), "must contain GPS field");
+            checkASCIIValue(dir, "GPS", GPS_DATA, GPS_N);
+
+        } catch (Exception e) { throw new RuntimeException(e); }
+    }
+
+    public static void main(String[] args) {
+        (new TIFFImageReadParamTest()).run();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/imageio/stream/NullStreamCheckTest.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,202 @@
+/*
+ * 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     8044289
+ * @summary Test verifies that when some of the read() and write() methods
+ *          are not able to get stream from createImageInputStream() and
+ *          createImageOutputStream() are we doing null check for stream
+ *          and throwing IOException as per specification.
+ * @run     main NullStreamCheckTest
+ */
+
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import javax.imageio.ImageIO;
+import javax.imageio.spi.IIORegistry;
+import javax.imageio.spi.ImageInputStreamSpi;
+import javax.imageio.spi.ImageOutputStreamSpi;
+
+public class NullStreamCheckTest {
+
+    // get ImageIORegistry default instance.
+    private static final IIORegistry localRegistry = IIORegistry.
+            getDefaultInstance();
+    // stream variables needed for input and output.
+    static LocalOutputStream outputStream = new LocalOutputStream();
+    static LocalInputStream inputStream = new LocalInputStream();
+
+    static final int width = 50, height = 50;
+
+    // input and output BufferedImage needed while read and write.
+    static BufferedImage inputImage = new BufferedImage(width, height,
+            BufferedImage.TYPE_INT_ARGB);
+
+    // creates test file needed for read and write in local directory.
+    private static File createTestFile(String name) throws IOException {
+        String sep = System.getProperty("file.separator");
+        String dir = System.getProperty("test.src", ".");
+        String filePath = dir+sep;
+        File directory = new File(filePath);
+        File tmpTestFile = File.createTempFile(name, ".png", directory);
+        directory.delete();
+        return tmpTestFile;
+    }
+
+    /* if we catch expected IOException message return
+     * false otherwise return true.
+     */
+    private static boolean verifyOutputExceptionMessage(IOException ex) {
+        String message = ex.getMessage();
+        return (!message.equals("Can't create an ImageOutputStream!"));
+    }
+
+    /* if we catch expected IOException message return
+     * false otherwise return true.
+     */
+    private static boolean verifyInputExceptionMessage(IOException ex) {
+        String message = ex.getMessage();
+        return (!message.equals("Can't create an ImageInputStream!"));
+    }
+
+    private static void verifyFileWrite() throws IOException {
+        File outputTestFile = createTestFile("outputTestFile");
+        try {
+            ImageIO.write(inputImage, "png", outputTestFile);
+        } catch (IOException ex) {
+            if (verifyOutputExceptionMessage(ex))
+                throw ex;
+        } finally {
+            outputTestFile.delete();
+        }
+    }
+
+    private static void verifyStreamWrite() throws IOException {
+        try {
+            ImageIO.write(inputImage, "png", outputStream);
+        } catch (IOException ex) {
+            if (verifyOutputExceptionMessage(ex))
+                throw ex;
+        } finally {
+            try {
+                outputStream.close();
+            } catch (IOException ex) {
+                throw ex;
+            }
+        }
+    }
+
+    private static void verifyFileRead() throws IOException {
+        File inputTestFile = createTestFile("inputTestFile");
+        try {
+            ImageIO.read(inputTestFile);
+        } catch (IOException ex) {
+            if (verifyInputExceptionMessage(ex))
+                throw ex;
+        } finally {
+            inputTestFile.delete();
+        }
+    }
+
+    private static void verifyStreamRead() throws IOException {
+        try {
+            ImageIO.read(inputStream);
+        } catch (IOException ex) {
+            if (verifyInputExceptionMessage(ex))
+                throw ex;
+        } finally {
+            try {
+                inputStream.close();
+            } catch (IOException ex) {
+                throw ex;
+            }
+        }
+    }
+
+    private static void verifyUrlRead() throws IOException {
+        URL url;
+        File inputTestUrlFile = createTestFile("inputTestFile");
+        try {
+            try {
+                url = inputTestUrlFile.toURI().toURL();
+            } catch (MalformedURLException ex) {
+                throw ex;
+            }
+
+            try {
+                ImageIO.read(url);
+            } catch (IOException ex) {
+                if (verifyInputExceptionMessage(ex))
+                    throw ex;
+            }
+        } finally {
+            inputTestUrlFile.delete();
+        }
+    }
+
+    public static void main(String[] args) throws IOException,
+                                                  MalformedURLException {
+
+        /* deregister ImageOutputStreamSpi so that we creatImageOutputStream
+         * returns null while writing.
+         */
+        localRegistry.deregisterAll(ImageOutputStreamSpi.class);
+        /* verify possible ImageIO.write() scenario's for null stream output
+         * from createImageOutputStream() API in ImageIO class.
+         */
+        verifyFileWrite();
+        verifyStreamWrite();
+
+        /* deregister ImageInputStreamSpi so that we creatImageInputStream
+         * returns null while reading.
+         */
+        localRegistry.deregisterAll(ImageInputStreamSpi.class);
+        /* verify possible ImageIO.read() scenario's for null stream output
+         * from createImageInputStream API in ImageIO class.
+         */
+        verifyFileRead();
+        verifyStreamRead();
+        verifyUrlRead();
+    }
+
+    static class LocalOutputStream extends OutputStream {
+
+        @Override
+        public void write(int i) throws IOException {
+        }
+    }
+
+    static class LocalInputStream extends InputStream {
+
+        @Override
+        public int read() throws IOException {
+            return 0;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/ServerName/BestEffortOnLazyConnected.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,337 @@
+/*
+ * 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.
+ */
+
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
+/**
+ * @test
+ * @bug 8144566
+ * @summary Custom HostnameVerifier disables SNI extension
+ * @run main/othervm BestEffortOnLazyConnected
+ */
+
+import java.io.*;
+import java.nio.*;
+import java.nio.channels.*;
+import java.util.*;
+import java.net.*;
+import javax.net.ssl.*;
+
+public class BestEffortOnLazyConnected {
+
+    /*
+     * =============================================================
+     * Set the various variables needed for the tests, then
+     * specify what tests to run on each side.
+     */
+
+    /*
+     * Should we run the client or server in a separate thread?
+     * Both sides can throw exceptions, but do you have a preference
+     * as to which side should be the main thread.
+     */
+    private static final boolean separateServerThread = true;
+
+    /*
+     * Where do we find the keystores?
+     */
+    private static final String pathToStores = "../etc";
+    private static final String keyStoreFile = "keystore";
+    private static final String trustStoreFile = "truststore";
+    private static final String passwd = "passphrase";
+
+    /*
+     * Is the server ready to serve?
+     */
+    private static volatile boolean serverReady = false;
+
+    /*
+     * Turn on SSL debugging?
+     */
+    private static final boolean debug = false;
+
+    /*
+     * the fully qualified domain name of localhost
+     */
+    private static String hostname = null;
+
+    /*
+     * If the client or server is doing some kind of object creation
+     * that the other side depends on, and that thread prematurely
+     * exits, you may experience a hang.  The test harness will
+     * terminate all hung threads after its timeout has expired,
+     * currently 3 minutes by default, but you might try to be
+     * smart about it....
+     */
+
+    /*
+     * Define the server side of the test.
+     *
+     * If the server prematurely exits, serverReady will be set to true
+     * to avoid infinite hangs.
+     */
+    private void doServerSide() throws Exception {
+        SSLServerSocketFactory sslssf =
+            (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
+        try (SSLServerSocket sslServerSocket =
+                (SSLServerSocket) sslssf.createServerSocket(serverPort)) {
+
+            serverPort = sslServerSocket.getLocalPort();
+
+            /*
+             * Signal Client, we're ready for his connect.
+             */
+            serverReady = true;
+
+            try (SSLSocket sslSocket = (SSLSocket)sslServerSocket.accept()) {
+                InputStream sslIS = sslSocket.getInputStream();
+                OutputStream sslOS = sslSocket.getOutputStream();
+
+                sslIS.read();
+                sslOS.write(85);
+                sslOS.flush();
+
+                ExtendedSSLSession session =
+                        (ExtendedSSLSession)sslSocket.getSession();
+                if (session.getRequestedServerNames().isEmpty()) {
+                    throw new Exception("No expected Server Name Indication");
+                }
+            }
+        }
+    }
+
+    /*
+     * Define the client side of the test.
+     *
+     * If the server prematurely exits, serverReady will be set to true
+     * to avoid infinite hangs.
+     */
+    private void doClientSide() throws Exception {
+
+        /*
+         * Wait for server to get started.
+         */
+        while (!serverReady) {
+            Thread.sleep(50);
+        }
+
+        SSLSocketFactory sslsf =
+            (SSLSocketFactory) SSLSocketFactory.getDefault();
+
+        try (SSLSocket sslSocket = (SSLSocket)sslsf.createSocket()) {
+
+            sslSocket.connect(new InetSocketAddress(hostname, serverPort), 0);
+
+            InputStream sslIS = sslSocket.getInputStream();
+            OutputStream sslOS = sslSocket.getOutputStream();
+
+            sslOS.write(280);
+            sslOS.flush();
+            sslIS.read();
+        }
+    }
+
+
+    /*
+     * =============================================================
+     * The remainder is just support stuff
+     */
+
+    // use any free port by default
+    private volatile int serverPort = 0;
+
+    private volatile Exception serverException = null;
+    private volatile Exception clientException = null;
+
+    public static void main(String[] args) throws Exception {
+        String keyFilename =
+            System.getProperty("test.src", ".") + "/" + pathToStores +
+                "/" + keyStoreFile;
+        String trustFilename =
+            System.getProperty("test.src", ".") + "/" + pathToStores +
+                "/" + trustStoreFile;
+
+        System.setProperty("javax.net.ssl.keyStore", keyFilename);
+        System.setProperty("javax.net.ssl.keyStorePassword", passwd);
+        System.setProperty("javax.net.ssl.trustStore", trustFilename);
+        System.setProperty("javax.net.ssl.trustStorePassword", passwd);
+
+        if (debug) {
+            System.setProperty("javax.net.debug", "all");
+        }
+
+        try {
+            hostname = InetAddress.getLocalHost().getCanonicalHostName();
+        } catch (UnknownHostException uhe) {
+            System.out.println(
+                "Ignore the test as the local hostname cannot be determined");
+
+            return;
+        }
+
+        System.out.println(
+                "The fully qualified domain name of the local host is " +
+                hostname);
+        // Ignore the test if the hostname does not sound like a domain name.
+        if ((hostname == null) || hostname.isEmpty() ||
+                hostname.startsWith("localhost") ||
+                Character.isDigit(hostname.charAt(hostname.length() - 1))) {
+
+            System.out.println("Ignore the test as the local hostname " +
+                    "cannot be determined as fully qualified domain name");
+
+            return;
+        }
+
+        /*
+         * Start the tests.
+         */
+        new BestEffortOnLazyConnected();
+    }
+
+    private Thread clientThread = null;
+    private Thread serverThread = null;
+
+    /*
+     * Primary constructor, used to drive remainder of the test.
+     *
+     * Fork off the other side, then do your work.
+     */
+    BestEffortOnLazyConnected() throws Exception {
+        try {
+            if (separateServerThread) {
+                startServer(true);
+                startClient(false);
+            } else {
+                startClient(true);
+                startServer(false);
+            }
+        } catch (Exception e) {
+            // swallow for now.  Show later
+        }
+
+        /*
+         * Wait for other side to close down.
+         */
+        if (separateServerThread) {
+            serverThread.join();
+        } else {
+            clientThread.join();
+        }
+
+        /*
+         * When we get here, the test is pretty much over.
+         * Which side threw the error?
+         */
+        Exception local;
+        Exception remote;
+        String whichRemote;
+
+        if (separateServerThread) {
+            remote = serverException;
+            local = clientException;
+            whichRemote = "server";
+        } else {
+            remote = clientException;
+            local = serverException;
+            whichRemote = "client";
+        }
+
+        /*
+         * If both failed, return the curthread's exception, but also
+         * print the remote side Exception
+         */
+        if ((local != null) && (remote != null)) {
+            System.out.println(whichRemote + " also threw:");
+            remote.printStackTrace();
+            System.out.println();
+            throw local;
+        }
+
+        if (remote != null) {
+            throw remote;
+        }
+
+        if (local != null) {
+            throw local;
+        }
+    }
+
+    private void startServer(boolean newThread) throws Exception {
+        if (newThread) {
+            serverThread = new Thread() {
+                public void run() {
+                    try {
+                        doServerSide();
+                    } catch (Exception e) {
+                        /*
+                         * Our server thread just died.
+                         *
+                         * Release the client, if not active already...
+                         */
+                        System.err.println("Server died...");
+                        serverReady = true;
+                        serverException = e;
+                    }
+                }
+            };
+            serverThread.start();
+        } else {
+            try {
+                doServerSide();
+            } catch (Exception e) {
+                serverException = e;
+            } finally {
+                serverReady = true;
+            }
+        }
+    }
+
+    private void startClient(boolean newThread) throws Exception {
+        if (newThread) {
+            clientThread = new Thread() {
+                public void run() {
+                    try {
+                        doClientSide();
+                    } catch (Exception e) {
+                        /*
+                         * Our client thread just died.
+                         */
+                        System.err.println("Client died...");
+                        clientException = e;
+                    }
+                }
+            };
+            clientThread.start();
+        } else {
+            try {
+                doClientSide();
+            } catch (Exception e) {
+                clientException = e;
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/AudioFloatConverter/Bits16ToFromFloatArray.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,101 @@
+/*
+ * 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.util.Arrays;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioFormat.Encoding;
+
+import com.sun.media.sound.AudioFloatConverter;
+
+import static javax.sound.sampled.AudioFormat.Encoding.*;
+
+/**
+ * @test
+ * @bug 8152501
+ * @modules java.desktop/com.sun.media.sound
+ */
+public final class Bits16ToFromFloatArray {
+
+    private static final int SIZE = 16;
+
+    private static final float[] FLOATS = {-1.0f, 0, 1.0f};
+
+    private static short MID_U = (short) (Short.MAX_VALUE + 1);
+    private static short MAX_U = -1;
+
+    // BIG ENDIAN
+    private static final byte[] SIGNED_BIG = {
+            (byte) (Short.MIN_VALUE >> 8), (byte) (Short.MIN_VALUE & 0xff), 0,
+            0, (byte) (Short.MAX_VALUE >> 8), (byte) (Short.MAX_VALUE & 0xff)
+    };
+
+    private static final byte[] UNSIGNED_BIG = {
+            0, 0, (byte) (MID_U >> 8), (byte) (MID_U & 0xff),
+            (byte) (MAX_U >> 8), (byte) (MAX_U >> 8)
+    };
+
+    // LITTLE ENDIAN
+    private static final byte[] SIGNED_LITTLE = {
+            (byte) (Short.MIN_VALUE & 0xff), (byte) (Short.MIN_VALUE >> 8), 0,
+            0, (byte) (Short.MAX_VALUE & 0xff), (byte) (Short.MAX_VALUE >> 8)
+    };
+
+    private static final byte[] UNSIGNED_LITTLE = {
+            0, 0, (byte) (MID_U & 0xff), (byte) (MID_U >> 8),
+            (byte) (MAX_U >> 8), (byte) (MAX_U >> 8)
+    };
+
+    public static void main(final String[] args) {
+        test(PCM_UNSIGNED, UNSIGNED_BIG, true);
+        test(PCM_UNSIGNED, UNSIGNED_LITTLE, false);
+        test(PCM_SIGNED, SIGNED_LITTLE, false);
+        test(PCM_SIGNED, SIGNED_BIG, true);
+    }
+
+    private static void test(final Encoding enc, final byte[] expected,
+                             boolean end) {
+        System.err.println("enc = " + enc);
+        AudioFormat af = new AudioFormat(enc, 44100, SIZE, 1, SIZE / 8, 44100,
+                                         end);
+        byte[] bytes = new byte[FLOATS.length * af.getFrameSize()];
+        AudioFloatConverter conv = AudioFloatConverter.getConverter(af);
+
+        conv.toByteArray(FLOATS, bytes);
+
+        if (!Arrays.equals(bytes, expected)) {
+            System.err.println("Actual: " + Arrays.toString(bytes));
+            System.err.println("Expected: " + Arrays.toString(expected));
+            throw new RuntimeException();
+        }
+
+        float[] floats = new float[bytes.length / af.getFrameSize()];
+        conv.toFloatArray(bytes, floats);
+
+        if (!Arrays.equals(floats, FLOATS)) {
+            System.err.println("Actual: " + Arrays.toString(floats));
+            System.err.println("Expected: " + Arrays.toString(FLOATS));
+            throw new RuntimeException();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/AudioFloatConverter/Bits24ToFromFloatArray.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,126 @@
+/*
+ * 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.util.Arrays;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioFormat.Encoding;
+
+import com.sun.media.sound.AudioFloatConverter;
+
+import static javax.sound.sampled.AudioFormat.Encoding.PCM_SIGNED;
+import static javax.sound.sampled.AudioFormat.Encoding.PCM_UNSIGNED;
+
+/**
+ * @test
+ * @bug 8152501
+ * @modules java.desktop/com.sun.media.sound
+ */
+public final class Bits24ToFromFloatArray {
+
+    private static final int SIZE = 24;
+
+    private static final float[] FLOATS = {-1.0f, 0, 1.0f};
+
+    private static int MIN_S = -8_388_608;
+    private static int MAX_S = 8_388_607;
+
+    private static int MID_U = 0xFFFFFF / 2 + 1;
+    private static int MAX_U = 0xFFFFFF;
+
+    // BIG ENDIAN
+    private static final byte[] SIGNED_BIG = {
+            (byte) ((MIN_S >> 16) & 0xff),
+            (byte) ((MIN_S >> 8) & 0xff),
+            (byte) ((MIN_S >> 0) & 0xff),
+            0, 0, 0,
+            (byte) ((MAX_S >> 16) & 0xff),
+            (byte) ((MAX_S >> 8) & 0xff),
+            (byte) ((MAX_S >> 0) & 0xff),
+    };
+
+    private static final byte[] UNSIGNED_BIG = {
+            0, 0, 0,
+            (byte) ((MID_U >> 16) & 0xff),
+            (byte) ((MID_U >> 8) & 0xff),
+            (byte) ((MID_U >> 0) & 0xff),
+            (byte) ((MAX_U >> 16) & 0xff),
+            (byte) ((MAX_U >> 8) & 0xff),
+            (byte) ((MAX_U >> 0) & 0xff),
+
+    };
+
+    // LITTLE ENDIAN
+    private static final byte[] SIGNED_LITTLE = {
+            (byte) ((MIN_S >> 0) & 0xff),
+            (byte) ((MIN_S >> 8) & 0xff),
+            (byte) ((MIN_S >> 16) & 0xff),
+            0, 0, 0,
+            (byte) ((MAX_S >> 0) & 0xff),
+            (byte) ((MAX_S >> 8) & 0xff),
+            (byte) ((MAX_S >> 16) & 0xff),
+            };
+
+    private static final byte[] UNSIGNED_LITTLE = {
+            0, 0, 0,
+            (byte) ((MID_U >> 0) & 0xff),
+            (byte) ((MID_U >> 8) & 0xff),
+            (byte) ((MID_U >> 16) & 0xff),
+            (byte) ((MAX_U >> 0) & 0xff),
+            (byte) ((MAX_U >> 8) & 0xff),
+            (byte) ((MAX_U >> 16) & 0xff),
+            };
+
+    public static void main(final String[] args) {
+        test(PCM_UNSIGNED, UNSIGNED_BIG, true);
+        test(PCM_UNSIGNED, UNSIGNED_LITTLE, false);
+        test(PCM_SIGNED, SIGNED_LITTLE, false);
+        test(PCM_SIGNED, SIGNED_BIG, true);
+    }
+
+    private static void test(final Encoding enc, final byte[] expected,
+                             boolean end) {
+        System.err.println(enc);
+        AudioFormat af = new AudioFormat(enc, 44100, SIZE, 1, SIZE / 8, 44100,
+                                         end);
+        byte[] bytes = new byte[FLOATS.length * af.getFrameSize()];
+        AudioFloatConverter conv = AudioFloatConverter.getConverter(af);
+
+        conv.toByteArray(FLOATS, bytes);
+
+        if (!Arrays.equals(bytes, expected)) {
+            System.err.println("Actual: " + Arrays.toString(bytes));
+            System.err.println("Expected: " + Arrays.toString(expected));
+            throw new RuntimeException();
+        }
+
+        float[] floats = new float[bytes.length / af.getFrameSize()];
+        conv.toFloatArray(bytes, floats);
+
+        if (!Arrays.equals(floats, FLOATS)) {
+            System.err.println("Actual: " + Arrays.toString(floats));
+            System.err.println("Expected: " + Arrays.toString(FLOATS));
+            throw new RuntimeException();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/AudioFloatConverter/Bits32ToFromFloatArray.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,130 @@
+/*
+ * 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.util.Arrays;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioFormat.Encoding;
+
+import com.sun.media.sound.AudioFloatConverter;
+
+import static javax.sound.sampled.AudioFormat.Encoding.PCM_SIGNED;
+import static javax.sound.sampled.AudioFormat.Encoding.PCM_UNSIGNED;
+
+/**
+ * @test
+ * @bug 8152501
+ * @modules java.desktop/com.sun.media.sound
+ */
+public final class Bits32ToFromFloatArray {
+
+    private static final int SIZE = 32;
+
+    private static final float[] FLOATS = {-1.0f, 0, 1.0f};
+
+    private static int MID_U = (int) (Integer.MAX_VALUE + 1);
+    private static int MAX_U = -1;
+
+    // BIG ENDIAN
+    private static final byte[] SIGNED_BIG = {
+            (byte) ((Integer.MIN_VALUE >> 24) & 0xff),
+            (byte) ((Integer.MIN_VALUE >> 16) & 0xff),
+            (byte) ((Integer.MIN_VALUE >> 8) & 0xff),
+            (byte) ((Integer.MIN_VALUE >> 0) & 0xff),
+            0, 0, 0, 0,
+            (byte) ((Integer.MAX_VALUE >> 24) & 0xff),
+            (byte) ((Integer.MAX_VALUE >> 16) & 0xff),
+            (byte) ((Integer.MAX_VALUE >> 8) & 0xff),
+            (byte) ((Integer.MAX_VALUE >> 0) & 0xff),
+    };
+
+    private static final byte[] UNSIGNED_BIG = {
+            0, 0, 0, 0,
+            (byte) ((MID_U >> 24) & 0xff),
+            (byte) ((MID_U >> 16) & 0xff),
+            (byte) ((MID_U >> 8) & 0xff),
+            (byte) ((MID_U >> 0) & 0xff),
+            (byte) ((MAX_U >> 24) & 0xff),
+            (byte) ((MAX_U >> 16) & 0xff),
+            (byte) ((MAX_U >> 8) & 0xff),
+            (byte) ((MAX_U >> 0) & 0xff),
+
+    };
+
+    // LITTLE ENDIAN
+    private static final byte[] SIGNED_LITTLE = {
+            (byte) ((Integer.MIN_VALUE >> 0) & 0xff),
+            (byte) ((Integer.MIN_VALUE >> 8) & 0xff),
+            (byte) ((Integer.MIN_VALUE >> 16) & 0xff),
+            (byte) ((Integer.MIN_VALUE >> 24) & 0xff),
+            0, 0, 0, 0,
+            (byte) ((Integer.MAX_VALUE >> 0) & 0xff),
+            (byte) ((Integer.MAX_VALUE >> 8) & 0xff),
+            (byte) ((Integer.MAX_VALUE >> 16) & 0xff),
+            (byte) ((Integer.MAX_VALUE >> 24) & 0xff),
+            };
+
+    private static final byte[] UNSIGNED_LITTLE = {
+            0, 0, 0, 0,
+            (byte) ((MID_U >> 0) & 0xff),
+            (byte) ((MID_U >> 8) & 0xff),
+            (byte) ((MID_U >> 16) & 0xff),
+            (byte) ((MID_U >> 24) & 0xff),
+            (byte) ((MAX_U >> 0) & 0xff),
+            (byte) ((MAX_U >> 8) & 0xff),
+            (byte) ((MAX_U >> 16) & 0xff),
+            (byte) ((MAX_U >> 24) & 0xff),
+            };
+
+    public static void main(final String[] args) {
+        test(PCM_UNSIGNED, UNSIGNED_BIG, true);
+        test(PCM_UNSIGNED, UNSIGNED_LITTLE, false);
+        test(PCM_SIGNED, SIGNED_LITTLE, false);
+        test(PCM_SIGNED, SIGNED_BIG, true);
+    }
+
+    private static void test(final Encoding enc, final byte[] expected,
+                             boolean end) {
+        AudioFormat af = new AudioFormat(enc, 44100, SIZE, 1, SIZE / 8, 44100,
+                                         end);
+        byte[] bytes = new byte[FLOATS.length * af.getFrameSize()];
+        AudioFloatConverter conv = AudioFloatConverter.getConverter(af);
+
+        conv.toByteArray(FLOATS, bytes);
+
+        if (!Arrays.equals(bytes, expected)) {
+            System.err.println("Actual: " + Arrays.toString(bytes));
+            System.err.println("Expected: " + Arrays.toString(expected));
+            throw new RuntimeException();
+        }
+
+        float[] floats = new float[bytes.length / af.getFrameSize()];
+        conv.toFloatArray(bytes, floats);
+
+        if (!Arrays.equals(floats, FLOATS)) {
+            System.err.println("Actual: " + Arrays.toString(floats));
+            System.err.println("Expected: " + Arrays.toString(FLOATS));
+            throw new RuntimeException();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/AudioFloatConverter/Bits64ToFromFloatArray.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,142 @@
+/*
+ * 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.util.Arrays;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioFormat.Encoding;
+
+import com.sun.media.sound.AudioFloatConverter;
+
+import static javax.sound.sampled.AudioFormat.Encoding.PCM_SIGNED;
+import static javax.sound.sampled.AudioFormat.Encoding.PCM_UNSIGNED;
+
+/**
+ * @test
+ * @bug 8152501
+ * @modules java.desktop/com.sun.media.sound
+ */
+public final class Bits64ToFromFloatArray {
+
+    private static final int SIZE = 64;
+
+    private static final float[] FLOATS = {-1.0f, 0, 1.0f};
+
+    private static long MID_U = (long) (Long.MAX_VALUE + 1);
+    private static long MAX_U = -1;
+
+    // BIG ENDIAN
+    private static final byte[] SIGNED_BIG = {
+            (byte) ((Long.MIN_VALUE >> 56) & 0xff),
+            (byte) ((Long.MIN_VALUE >> 48) & 0xff),
+            (byte) ((Long.MIN_VALUE >> 40) & 0xff),
+            (byte) ((Long.MIN_VALUE >> 32) & 0xff),
+            0, 0, 0, 0, // current javasound impl will ignore this
+            0, 0, 0, 0,
+            0, 0, 0, 0,
+            (byte) ((Long.MAX_VALUE >> 56) & 0xff),
+            (byte) ((Long.MAX_VALUE >> 48) & 0xff),
+            (byte) ((Long.MAX_VALUE >> 40) & 0xff),
+            (byte) ((Long.MAX_VALUE >> 32) & 0xff),
+            0, 0, 0, 0, // current javasound impl will ignore this
+    };
+
+    private static final byte[] UNSIGNED_BIG = {
+            0, 0, 0, 0,
+            0, 0, 0, 0,
+            (byte) ((MID_U >> 56) & 0xff),
+            (byte) ((MID_U >> 48) & 0xff),
+            (byte) ((MID_U >> 40) & 0xff),
+            (byte) ((MID_U >> 32) & 0xff),
+            0, 0, 0, 0, // current javasound impl will ignore this
+            (byte) ((MAX_U >> 56) & 0xff),
+            (byte) ((MAX_U >> 48) & 0xff),
+            (byte) ((MAX_U >> 40) & 0xff),
+            (byte) ((MAX_U >> 32) & 0xff),
+            0, 0, 0, 0, // current javasound impl will ignore this
+    };
+
+    // LITTLE ENDIAN
+    private static final byte[] SIGNED_LITTLE = {
+            0, 0, 0, 0, // current javasound impl will ignore this
+            (byte) ((Long.MIN_VALUE >> 32) & 0xff),
+            (byte) ((Long.MIN_VALUE >> 40) & 0xff),
+            (byte) ((Long.MIN_VALUE >> 48) & 0xff),
+            (byte) ((Long.MIN_VALUE >> 56) & 0xff),
+            0, 0, 0, 0,
+            0, 0, 0, 0,
+            0, 0, 0, 0, // current javasound impl will ignore this
+            (byte) ((Long.MAX_VALUE >> 32) & 0xff),
+            (byte) ((Long.MAX_VALUE >> 40) & 0xff),
+            (byte) ((Long.MAX_VALUE >> 48) & 0xff),
+            (byte) ((Long.MAX_VALUE >> 56) & 0xff),
+            };
+
+    private static final byte[] UNSIGNED_LITTLE = {
+            0, 0, 0, 0,
+            0, 0, 0, 0,
+            0, 0, 0, 0, // current javasound impl will ignore this
+            (byte) ((MID_U >> 32) & 0xff),
+            (byte) ((MID_U >> 40) & 0xff),
+            (byte) ((MID_U >> 48) & 0xff),
+            (byte) ((MID_U >> 56) & 0xff),
+            0, 0, 0, 0, // current javasound impl will ignore this
+            (byte) ((MAX_U >> 32) & 0xff),
+            (byte) ((MAX_U >> 40) & 0xff),
+            (byte) ((MAX_U >> 48) & 0xff),
+            (byte) ((MAX_U >> 56) & 0xff),
+            };
+
+    public static void main(final String[] args) {
+        test(PCM_UNSIGNED, UNSIGNED_BIG, true);
+        test(PCM_UNSIGNED, UNSIGNED_LITTLE, false);
+        test(PCM_SIGNED, SIGNED_LITTLE, false);
+        test(PCM_SIGNED, SIGNED_BIG, true);
+    }
+
+    private static void test(final Encoding enc, final byte[] expected,
+                             boolean end) {
+        System.err.println(enc);
+        AudioFormat af = new AudioFormat(enc, 44100, SIZE, 1, SIZE / 8, 44100,
+                                         end);
+        byte[] bytes = new byte[FLOATS.length * af.getFrameSize()];
+        AudioFloatConverter conv = AudioFloatConverter.getConverter(af);
+
+        conv.toByteArray(FLOATS, bytes);
+
+        if (!Arrays.equals(bytes, expected)) {
+            System.err.println("Actual:   " + Arrays.toString(bytes));
+            System.err.println("Expected: " + Arrays.toString(expected));
+            throw new RuntimeException();
+        }
+
+        float[] floats = new float[bytes.length / af.getFrameSize()];
+        conv.toFloatArray(bytes, floats);
+
+        if (!Arrays.equals(floats, FLOATS)) {
+            System.err.println("Actual: " + Arrays.toString(floats));
+            System.err.println("Expected: " + Arrays.toString(FLOATS));
+            throw new RuntimeException();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/AudioFloatConverter/Bits8ToFromFloatArray.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,78 @@
+/*
+ * 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.util.Arrays;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioFormat.Encoding;
+
+import com.sun.media.sound.AudioFloatConverter;
+
+import static javax.sound.sampled.AudioFormat.Encoding.*;
+
+/**
+ * @test
+ * @bug 8152501
+ * @modules java.desktop/com.sun.media.sound
+ */
+public final class Bits8ToFromFloatArray {
+
+    private static final int SIZE = 8;
+
+    private static final float[] FLOATS = {-1.0f, 0, 1.0f};
+
+    private static final byte[] SIGNED = {Byte.MIN_VALUE, 0, Byte.MAX_VALUE};
+
+    private static final byte[] UNSIGNED = {
+            0, (byte) (Byte.MAX_VALUE + 1), (byte) -1
+    };
+
+    public static void main(final String[] args) {
+        test(PCM_UNSIGNED, UNSIGNED);
+        test(PCM_SIGNED, SIGNED);
+    }
+
+    private static void test(final Encoding enc, final byte[] expected) {
+        AudioFormat af = new AudioFormat(enc, 44100, SIZE, 1, SIZE / 8, 44100,
+                                         true);
+        byte[] bytes = new byte[FLOATS.length * af.getFrameSize()];
+        AudioFloatConverter conv = AudioFloatConverter.getConverter(af);
+
+        conv.toByteArray(FLOATS, bytes);
+
+        if (!Arrays.equals(bytes, expected)) {
+            System.err.println("Actual: " + Arrays.toString(bytes));
+            System.err.println("Expected: " + Arrays.toString(expected));
+            throw new RuntimeException();
+        }
+
+        float[] floats = new float[bytes.length / af.getFrameSize()];
+        conv.toFloatArray(bytes, floats);
+
+        if (!Arrays.equals(floats, FLOATS)) {
+            System.err.println("Actual: " + Arrays.toString(floats));
+            System.err.println("Expected: " + Arrays.toString(FLOATS));
+            throw new RuntimeException();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JFileChooser/DeserializedJFileChooser/DeserializedJFileChooserTest.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,75 @@
+/*
+ * 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 8146301
+ * @summary Enter key does not work in a deserialized JFileChooser.
+ * @run main DeserializedJFileChooserTest
+ */
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.KeyEvent;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
+public class DeserializedJFileChooserTest {
+
+    private static int state = -1;
+    private static JFileChooser deserialized;
+
+    public static void main(String[] args) throws Exception {
+        SwingUtilities.invokeLater( () -> {
+            try {
+                JFileChooser jfc = new JFileChooser();
+                ByteArrayOutputStream bos = new ByteArrayOutputStream();
+                ObjectOutputStream oos = new ObjectOutputStream(bos);
+                oos.writeObject(jfc);
+                oos.close();
+                ByteArrayInputStream bis =
+                        new ByteArrayInputStream(bos.toByteArray());
+                ObjectInputStream ois = new ObjectInputStream(bis);
+                deserialized = (JFileChooser) ois.readObject();
+                state = deserialized.showOpenDialog(null);
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+        });
+        Robot robot = new Robot();
+        robot.setAutoDelay(50);
+        robot.waitForIdle();
+        robot.keyPress(KeyEvent.VK_A);
+        robot.keyRelease(KeyEvent.VK_A);
+        robot.keyPress(KeyEvent.VK_ENTER);
+        robot.keyRelease(KeyEvent.VK_ENTER);
+        robot.waitForIdle();
+        robot.delay(1000);
+        if (state != JFileChooser.APPROVE_OPTION) {
+            deserialized.cancelSelection();
+            throw new RuntimeException("Failed");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JInternalFrame/DockIconRepaint/DockIconRepaint.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,127 @@
+/*
+ * 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.awt.Color;
+import java.awt.EventQueue;
+import java.awt.Graphics;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.Robot;
+import java.beans.PropertyVetoException;
+
+import javax.swing.JDesktopPane;
+import javax.swing.JFrame;
+import javax.swing.JInternalFrame;
+import javax.swing.JPanel;
+
+/**
+ * @test
+ * @bug 8144166
+ * @requires (os.family == "mac")
+ */
+public final class DockIconRepaint {
+
+    private static volatile Color color;
+
+    private static JFrame frame;
+
+    private static JInternalFrame jif;
+
+    private static Robot robot;
+
+    private static Point iconLoc;
+
+    private static Rectangle iconBounds;
+
+    public static void main(final String[] args) throws Exception {
+        robot = new Robot();
+        EventQueue.invokeAndWait(DockIconRepaint::createUI);
+        try {
+            robot.waitForIdle();
+            color = Color.BLUE;
+            test();
+            color = Color.RED;
+            test();
+            color = Color.GREEN;
+            test();
+        } finally {
+            frame.dispose();
+        }
+    }
+
+    private static void test() throws Exception {
+        // maximize the frame to force repaint
+        EventQueue.invokeAndWait(() -> {
+            try {
+                jif.setIcon(false);
+                jif.setMaximum(true);
+            } catch (PropertyVetoException e) {
+                throw new RuntimeException(e);
+            }
+        });
+        robot.waitForIdle();
+        Thread.sleep(1000);
+        // minimize the frame to dock, the icon should be up2date
+        EventQueue.invokeAndWait(() -> {
+            try {
+                jif.setIcon(true);
+            } catch (PropertyVetoException e) {
+                throw new RuntimeException(e);
+            }
+            iconLoc = jif.getDesktopIcon().getLocationOnScreen();
+            iconBounds = jif.getDesktopIcon().getBounds();
+        });
+        robot.waitForIdle();
+        Thread.sleep(1000);
+
+        final Color c = robot.getPixelColor(iconLoc.x + iconBounds.width / 2,
+                                            iconLoc.y + iconBounds.height / 2);
+        if (c.getRGB() != color.getRGB()) {
+            System.err.println("Exp: " + Integer.toHexString(color.getRGB()));
+            System.err.println("Actual: " + Integer.toHexString(c.getRGB()));
+            throw new RuntimeException("Wrong color.");
+        }
+    }
+
+    private static void createUI() {
+        frame = new JFrame();
+        frame.setUndecorated(true);
+        frame.setSize(300, 300);
+        frame.setLocationRelativeTo(null);
+        final JDesktopPane pane = new JDesktopPane();
+        final JPanel panel = new JPanel() {
+            @Override
+            protected void paintComponent(Graphics g) {
+                g.setColor(color);
+                g.fillRect(0, 0, getWidth(), getHeight());
+            }
+        };
+        jif = new JInternalFrame();
+        jif.add(panel);
+        jif.setVisible(true);
+        jif.setSize(300, 300);
+        pane.add(jif);
+        frame.add(pane);
+        frame.setVisible(true);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JPopupMenu/6949414/JPopupMenuEndlessLoopTest.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,59 @@
+/*
+ * 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 javax.swing.JMenu;
+import javax.swing.JMenuItem;
+import javax.swing.JPopupMenu;
+import javax.swing.MenuElement;
+import javax.swing.MenuSelectionManager;
+import javax.swing.SwingUtilities;
+
+/**
+ * @test
+ * @bug 6949414 6424606
+ * @summary JMenu.buildMenuElementArray() endless loop
+ * @run main/timeout=5 JPopupMenuEndlessLoopTest
+ */
+public class JPopupMenuEndlessLoopTest {
+
+    public static void main(String[] args) throws Exception {
+        SwingUtilities.invokeAndWait(() -> {
+
+            JPopupMenu popup = new JPopupMenu("Popup Menu");
+            JMenu menu = new JMenu("Menu");
+            menu.add(new JMenuItem("Menu Item"));
+            popup.add(menu);
+            menu.doClick();
+            MenuElement[] elems = MenuSelectionManager
+                    .defaultManager().getSelectedPath();
+
+            if (elems == null || elems.length == 0) {
+                throw new RuntimeException("Empty Selection");
+            }
+
+            if (elems[0] != popup || elems[1] != menu) {
+                throw new RuntimeException("Necessary menus are not selected!");
+            }
+        });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JTabbedPane/8137169/ScrollableTabbedPaneTest.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,182 @@
+/*
+ * 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 8137169
+ * @summary verifies TabbedScrollPane minimum height for all Look and Feels
+ * @library ../../regtesthelpers
+ * @build Util
+ * @run main ScrollableTabbedPaneTest
+ */
+
+import java.awt.Robot;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JTabbedPane;
+import javax.swing.SwingConstants;
+import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
+import javax.swing.UnsupportedLookAndFeelException;
+
+public class ScrollableTabbedPaneTest {
+
+    private static JFrame frame;
+    private static JTabbedPane pane;
+    private static Robot robot;
+    private static volatile String errorString = "";
+
+    public static void main(String[] args) throws Exception {
+        robot = new Robot();
+        robot.delay(1000);
+        UIManager.LookAndFeelInfo[] lookAndFeelArray
+                = UIManager.getInstalledLookAndFeels();
+        for (UIManager.LookAndFeelInfo lookAndFeelItem : lookAndFeelArray) {
+            executeCase(lookAndFeelItem.getClassName(),
+                        lookAndFeelItem.getName());
+        }
+        if (!"".equals(errorString)) {
+            throw new RuntimeException("Error Log:\n" + errorString);
+        }
+    }
+
+    private static void executeCase(String lookAndFeelString, String shortLAF)
+            throws Exception {
+        if (tryLookAndFeel(lookAndFeelString)) {
+            createUI(shortLAF);
+            stepsToExecute(shortLAF);
+
+            createLeftUI(shortLAF);
+            stepsToExecute(shortLAF);
+
+            createRightUI(shortLAF);
+            stepsToExecute(shortLAF);
+        }
+    }
+
+    private static void stepsToExecute(String shortLAF) throws Exception {
+        robot.delay(100);
+        runTestCase(shortLAF);
+        robot.delay(1000);
+        cleanUp();
+        robot.delay(1000);
+    }
+
+    private static boolean tryLookAndFeel(String lookAndFeelString)
+            throws Exception {
+        try {
+            UIManager.setLookAndFeel(
+                    lookAndFeelString);
+
+        } catch (UnsupportedLookAndFeelException
+                | ClassNotFoundException
+                | InstantiationException
+                | IllegalAccessException e) {
+            return false;
+        }
+        return true;
+    }
+
+    private static void cleanUp() throws Exception {
+        SwingUtilities.invokeAndWait(new Runnable() {
+            @Override
+            public void run() {
+                frame.dispose();
+            }
+        });
+    }
+
+    private static void createUI(final String shortLAF)
+            throws Exception {
+        SwingUtilities.invokeAndWait(new Runnable() {
+            @Override
+            public void run() {
+                frame = new JFrame(shortLAF);
+                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+                frame.setVisible(true);
+                pane = new JTabbedPane();
+                pane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
+                frame.add(pane);
+                frame.setSize(500, 500);
+            }
+        });
+    }
+    private static void createLeftUI(final String shortLAF)
+            throws Exception {
+        SwingUtilities.invokeAndWait(new Runnable() {
+            @Override
+            public void run() {
+                frame = new JFrame(shortLAF);
+                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+                frame.setVisible(true);
+                pane = new JTabbedPane();
+                pane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
+                pane.setTabPlacement(SwingConstants.LEFT);
+                frame.add(pane);
+                frame.setSize(500, 500);
+            }
+        });
+    }
+
+    private static void createRightUI(final String shortLAF)
+            throws Exception {
+        SwingUtilities.invokeAndWait(new Runnable() {
+            @Override
+            public void run() {
+                frame = new JFrame(shortLAF);
+                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+                frame.setVisible(true);
+                pane = new JTabbedPane();
+                pane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
+                pane.setTabPlacement(SwingConstants.RIGHT);
+                frame.add(pane);
+                frame.setSize(500, 500);
+            }
+        });
+    }
+
+    private static void runTestCase(String shortLAF) throws Exception {
+        SwingUtilities.invokeAndWait(new Runnable() {
+            @Override
+            public void run() {
+                int i = 0;
+                int value= 0;
+                do {
+                    String title = "Tab" + (i + 1);
+                    pane.addTab(title, new JPanel());
+                    int tempValue = pane.getMinimumSize().height;
+                    if(value==0) {
+                        value = tempValue;
+                    }
+                    if(value != tempValue) {
+                        String error = "[" + shortLAF
+                            + "]: [Error]: TabbedScrollPane fails";
+                    errorString += error;
+                    }
+
+                    ++i;
+                } while (i < 10);
+            }
+        });
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/LookAndFeel/6897701/JMenuItemsTest.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,130 @@
+/*
+ * 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 6897701
+ * @summary Verify JMenu and JMenuItem Disabled state for Nimbus LAF
+ * @run main JMenuItemsTest
+ */
+import java.awt.Color;
+import java.awt.Rectangle;
+import java.awt.image.BufferedImage;
+import javax.swing.JFrame;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JMenuItem;
+import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
+
+public class JMenuItemsTest {
+
+    private static JFrame mainFrame;
+    private static JMenu disabledMenu;
+    private static JMenuItem disabledMenuItem;
+
+    public JMenuItemsTest() {
+        createUI();
+    }
+
+    private void createUI() {
+
+        mainFrame = new JFrame("Test");
+
+        disabledMenu = new JMenu("Disabled Menu");
+        disabledMenu.setForeground(Color.BLUE);
+        disabledMenu.setEnabled(false);
+
+        disabledMenuItem = new JMenuItem("Disabled MenuItem");
+        disabledMenuItem.setForeground(Color.BLUE);
+        disabledMenuItem.setEnabled(false);
+
+        JMenuBar menuBar = new JMenuBar();
+        menuBar = new JMenuBar();
+        menuBar.add(disabledMenu);
+        menuBar.add(disabledMenuItem);
+
+        mainFrame.add(menuBar);
+        mainFrame.pack();
+        mainFrame.setVisible(true);
+    }
+
+    private void dispose() {
+        mainFrame.dispose();
+    }
+
+    private void testDisabledStateOfJMenu() {
+
+        // Test disabled JMenu state
+        Rectangle rect = disabledMenu.getBounds();
+        BufferedImage image = new BufferedImage(rect.width, rect.height,
+                BufferedImage.TYPE_INT_ARGB);
+        disabledMenu.paint(image.getGraphics());
+        int y = image.getHeight() / 2;
+        for (int x = 0; x < image.getWidth(); x++) {
+            Color c = new Color(image.getRGB(x, y));
+            if (c.equals(Color.BLUE)) {
+                dispose();
+                throw new RuntimeException("JMenu Disabled"
+                        + " State not Valid.");
+            }
+        }
+
+    }
+
+    private void testDisabledStateOfJMenuItem() {
+
+        // Test disabled JMenuItem state
+        Rectangle rect = disabledMenuItem.getBounds();
+        BufferedImage image = new BufferedImage(rect.width, rect.height,
+                BufferedImage.TYPE_INT_ARGB);
+        disabledMenuItem.paint(image.getGraphics());
+        int y = image.getHeight() / 2;
+        for (int x = 0; x < image.getWidth(); x++) {
+            Color c = new Color(image.getRGB(x, y));
+            if (c.equals(Color.BLUE)) {
+                dispose();
+                throw new RuntimeException("JMenuItem Disabled"
+                        + " State not Valid.");
+            }
+        }
+
+    }
+
+    public static void main(String[] args) throws Exception {
+        UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel");
+        SwingUtilities.invokeAndWait(() -> {
+
+            try {
+                JMenuItemsTest obj = new JMenuItemsTest();
+                obj.testDisabledStateOfJMenu();
+                obj.testDisabledStateOfJMenuItem();
+                obj.dispose();
+
+            } catch (Exception ex) {
+                throw ex;
+            }
+
+        });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/text/html/CSS/ColorValue/RGBColorValueTest.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,55 @@
+/*
+ * 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
+ * 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.
+ */
+
+/*
+ * @test
+ * @bug 8149631
+ * @summary rgb(...) CSS color values are not parsed properly
+ * @run main RGBColorValueTest
+ */
+
+import javax.swing.text.AttributeSet;
+import javax.swing.text.html.StyleSheet;
+
+import static javax.swing.text.html.CSS.Attribute.*;
+
+public class RGBColorValueTest {
+
+    public static void main(String[] args) {
+        StyleSheet styleSheet = new StyleSheet();
+        AttributeSet attributeSet = styleSheet.
+             getDeclaration("border-color: rgb(1, 2, 3)    rgb(1, 2, 4);");
+        if (!attributeSet.getAttribute(BORDER_TOP_COLOR).toString()
+                                                  .equals("rgb(1, 2, 3)") ||
+            !attributeSet.getAttribute(BORDER_BOTTOM_COLOR).toString()
+                                                  .equals("rgb(1, 2, 3)") ||
+            !attributeSet.getAttribute(BORDER_RIGHT_COLOR).toString()
+                                                  .equals("rgb(1, 2, 4)") ||
+            !attributeSet.getAttribute(BORDER_LEFT_COLOR).toString()
+                                                  .equals("rgb(1, 2, 4)") ) {
+            throw new RuntimeException("Failed");
+        }
+    }
+}
--- a/jdk/test/jdk/internal/jrtfs/WithSecurityManager.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/test/jdk/internal/jrtfs/WithSecurityManager.java	Wed Jul 05 21:37:42 2017 +0200
@@ -31,6 +31,7 @@
 import java.nio.file.FileSystems;
 import java.nio.file.Path;
 import java.nio.file.Paths;
+import java.util.Collections;
 
 public class WithSecurityManager {
     public static void main(String[] args) throws Exception {
@@ -61,7 +62,7 @@
 
         // check FileSystems.newFileSystem
         try {
-            FileSystems.newFileSystem(URI.create("jrt:/"), null);
+            FileSystems.newFileSystem(URI.create("jrt:/"), Collections.emptyMap());
             if (!allow) throw new RuntimeException("access not expected");
         } catch (SecurityException se) {
             if (allow)
--- a/jdk/test/jdk/internal/jrtfs/remote/Main.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/test/jdk/internal/jrtfs/remote/Main.java	Wed Jul 05 21:37:42 2017 +0200
@@ -30,6 +30,7 @@
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
+import java.util.Collections;
 import java.util.stream.Stream;
 
 /**
@@ -69,11 +70,12 @@
     private static FileSystem createFsWithURLClassloader(String javaHome) throws IOException{
         URL url = Paths.get(javaHome, "jrt-fs.jar").toUri().toURL();
         URLClassLoader loader = new URLClassLoader(new URL[] { url });
-        return FileSystems.newFileSystem(URI.create("jrt:/"), null, loader);
+        return FileSystems.newFileSystem(URI.create("jrt:/"),
+                                                    Collections.emptyMap(),
+                                                    loader);
     }
 
     private static FileSystem createFsByInstalledProvider() throws IOException {
         return FileSystems.getFileSystem(URI.create("jrt:/"));
     }
 }
-
--- a/jdk/test/jdk/internal/jrtfs/remote/RemoteRuntimeImageTest.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/test/jdk/internal/jrtfs/remote/RemoteRuntimeImageTest.java	Wed Jul 05 21:37:42 2017 +0200
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8141609
+ * @bug 8141609 8154403
  * @summary Verify JDK 8 can use jrt-fs.jar to work with jrt file system.
  * @run main RemoteRuntimeImageTest
  */
@@ -63,7 +63,6 @@
 
         String java = jdk8Path.resolve("bin/java").toAbsolutePath().toString();
         String javac = jdk8Path.resolve("bin/javac").toAbsolutePath().toString();
-
         Files.createDirectories(Paths.get(".", CLASSES_DIR));
         String jrtJar = Paths.get(TEST_JAVAHOME, JRTFS_JAR).toAbsolutePath().toString();
 
@@ -121,4 +120,3 @@
         return version.startsWith("\"1.8");
     }
 }
-
--- a/jdk/test/sanity/client/lib/SwingSet3/README	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/test/sanity/client/lib/SwingSet3/README	Wed Jul 05 21:37:42 2017 +0200
@@ -1,4 +1,4 @@
 This content of this src folder was originally taken from SwingSet3 demo project: https://java.net/projects/swingset3/.
 Then it was modified to increase testability and remove extra content and extra dependencies.
 
-Do NOT modify files in it.
\ No newline at end of file
+This is NOT the official location of the SwingSet3 demo.
\ No newline at end of file
--- a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/button/ButtonDemo.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/button/ButtonDemo.java	Wed Jul 05 21:37:42 2017 +0200
@@ -215,7 +215,6 @@
 
         javax.swing.SwingUtilities.invokeLater(() -> {
             JFrame frame = new JFrame(DEMO_TITLE);
-            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
             frame.add(buttonDemo);
             frame.pack();
             frame.setVisible(true);
--- a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/ComboBoxDemo.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/ComboBoxDemo.java	Wed Jul 05 21:37:42 2017 +0200
@@ -120,7 +120,6 @@
     public static void main(String[] args) {
         JFrame frame = new JFrame(DEMO_TITLE);
 
-        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         frame.getContentPane().add(new ComboBoxDemo());
         frame.setPreferredSize(new Dimension(800, 600));
         frame.pack();
--- a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/list/ListDemo.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/list/ListDemo.java	Wed Jul 05 21:37:42 2017 +0200
@@ -90,7 +90,6 @@
     public static void main(String[] args) {
         JFrame frame = new JFrame(DEMO_TITLE);
 
-        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         frame.getContentPane().add(new ListDemo());
         frame.setPreferredSize(new Dimension(800, 600));
         frame.pack();
--- a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/optionpane/OptionPaneDemo.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/optionpane/OptionPaneDemo.java	Wed Jul 05 21:37:42 2017 +0200
@@ -93,7 +93,6 @@
     public static void main(String[] args) {
         JFrame frame = new JFrame(DEMO_TITLE);
 
-        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         frame.getContentPane().add(new OptionPaneDemo());
         frame.setPreferredSize(new Dimension(800, 600));
         frame.pack();
--- a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/progressbar/ProgressBarDemo.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/progressbar/ProgressBarDemo.java	Wed Jul 05 21:37:42 2017 +0200
@@ -64,7 +64,6 @@
     public static void main(String[] args) {
         JFrame frame = new JFrame(DEMO_TITLE);
 
-        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         frame.getContentPane().add(new ProgressBarDemo());
         frame.setPreferredSize(new Dimension(800, 600));
         frame.pack();
--- a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/scrollpane/ScrollPaneDemo.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/scrollpane/ScrollPaneDemo.java	Wed Jul 05 21:37:42 2017 +0200
@@ -64,7 +64,6 @@
     public static void main(String[] args) {
         JFrame frame = new JFrame(DEMO_TITLE);
 
-        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         frame.getContentPane().add(new ScrollPaneDemo());
         frame.setPreferredSize(new Dimension(800, 600));
         frame.pack();
--- a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/spinner/SpinnerDemo.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/spinner/SpinnerDemo.java	Wed Jul 05 21:37:42 2017 +0200
@@ -58,7 +58,6 @@
 
     public static void main(String[] args) {
         JFrame frame = new JFrame(DEMO_TITLE);
-        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         frame.getContentPane().add(new SpinnerDemo());
         frame.setPreferredSize(new Dimension(800, 600));
         frame.pack();
--- a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/splitpane/SplitPaneDemo.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/splitpane/SplitPaneDemo.java	Wed Jul 05 21:37:42 2017 +0200
@@ -86,7 +86,6 @@
     public static void main(String[] args) {
         JFrame frame = new JFrame(DEMO_TITLE);
 
-        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         frame.getContentPane().add(new SplitPaneDemo());
         frame.setPreferredSize(new Dimension(800, 600));
         frame.pack();
--- a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/textfield/TextFieldDemo.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/textfield/TextFieldDemo.java	Wed Jul 05 21:37:42 2017 +0200
@@ -115,7 +115,6 @@
     public static void main(String[] args) {
         JFrame frame = new JFrame(DEMO_TITLE);
 
-        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         frame.getContentPane().add(new TextFieldDemo());
         frame.setPreferredSize(new Dimension(800, 600));
         frame.pack();
--- a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/ToggleButtonDemo.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/ToggleButtonDemo.java	Wed Jul 05 21:37:42 2017 +0200
@@ -151,7 +151,6 @@
     public static void main(String[] args) {
         JFrame frame = new JFrame(ToggleButtonDemo.class.getAnnotation(DemoProperties.class).value());
 
-        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         frame.getContentPane().add(new ToggleButtonDemo());
         frame.setPreferredSize(new Dimension(800, 600));
         frame.pack();
--- a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/tree/TreeDemo.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/tree/TreeDemo.java	Wed Jul 05 21:37:42 2017 +0200
@@ -65,7 +65,6 @@
     public static void main(String[] args) {
         JFrame frame = new JFrame(DEMO_TITLE);
 
-        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         frame.getContentPane().add(new TreeDemo());
         frame.setPreferredSize(new Dimension(800, 600));
         frame.pack();
--- a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/window/WindowDemo.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/window/WindowDemo.java	Wed Jul 05 21:37:42 2017 +0200
@@ -150,7 +150,6 @@
             JFrame frame = new JFrame();
             WindowDemo demo = new WindowDemo();
             frame.add(demo);
-            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
             frame.pack();
             frame.setVisible(true);
             demo.start();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/net/www/protocol/https/HttpsURLConnection/ImpactOnSNI.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,390 @@
+/*
+ * 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.
+ */
+
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
+/*
+ * @test
+ * @bug 8144566
+ * @summary Custom HostnameVerifier disables SNI extension
+ * @run main/othervm ImpactOnSNI
+ */
+
+import java.io.*;
+import java.net.*;
+import javax.net.ssl.*;
+
+public class ImpactOnSNI {
+
+    /*
+     * =============================================================
+     * Set the various variables needed for the tests, then
+     * specify what tests to run on each side.
+     */
+
+    /*
+     * Should we run the client or server in a separate thread?
+     * Both sides can throw exceptions, but do you have a preference
+     * as to which side should be the main thread.
+     */
+    private static final boolean separateServerThread = true;
+
+    /*
+     * Where do we find the keystores?
+     */
+    private static final String pathToStores =
+                                        "../../../../../../javax/net/ssl/etc";
+    private static final String keyStoreFile = "keystore";
+    private static final String trustStoreFile = "truststore";
+    private static final String passwd = "passphrase";
+
+    /*
+     * Is the server ready to serve?
+     */
+    private static volatile boolean serverReady = false;
+
+    /*
+     * Is the connection ready to close?
+     */
+    private static volatile boolean closeReady = false;
+
+    /*
+     * Turn on SSL debugging?
+     */
+    private static final boolean debug = false;
+
+    /*
+     * Message posted
+     */
+    private static final String postMsg = "HTTP post on a https server";
+
+    /*
+     * the fully qualified domain name of localhost
+     */
+    private static String hostname = null;
+
+    /*
+     * If the client or server is doing some kind of object creation
+     * that the other side depends on, and that thread prematurely
+     * exits, you may experience a hang.  The test harness will
+     * terminate all hung threads after its timeout has expired,
+     * currently 3 minutes by default, but you might try to be
+     * smart about it....
+     */
+
+    /*
+     * Define the server side of the test.
+     *
+     * If the server prematurely exits, serverReady will be set to true
+     * to avoid infinite hangs.
+     */
+    private void doServerSide() throws Exception {
+        SSLServerSocketFactory sslssf =
+            (SSLServerSocketFactory)SSLServerSocketFactory.getDefault();
+        try (SSLServerSocket sslServerSocket =
+                (SSLServerSocket)sslssf.createServerSocket(serverPort)) {
+
+            serverPort = sslServerSocket.getLocalPort();
+
+            /*
+             * Signal Client, we're ready for his connect.
+             */
+            serverReady = true;
+
+            /*
+             * Accept connections
+             */
+            try (SSLSocket sslSocket = (SSLSocket)sslServerSocket.accept()) {
+                InputStream sslIS = sslSocket.getInputStream();
+                OutputStream sslOS = sslSocket.getOutputStream();
+                BufferedReader br =
+                        new BufferedReader(new InputStreamReader(sslIS));
+                PrintStream ps = new PrintStream(sslOS);
+
+                // process HTTP POST request from client
+                System.out.println("status line: " + br.readLine());
+                String msg = null;
+                while ((msg = br.readLine()) != null && msg.length() > 0);
+
+                msg = br.readLine();
+                if (msg.equals(postMsg)) {
+                    ps.println("HTTP/1.1 200 OK\n\n");
+                } else {
+                    ps.println("HTTP/1.1 500 Not OK\n\n");
+                }
+                ps.flush();
+
+                ExtendedSSLSession session =
+                        (ExtendedSSLSession)sslSocket.getSession();
+                if (session.getRequestedServerNames().isEmpty()) {
+                    throw new Exception("No expected Server Name Indication");
+                }
+
+                // close the socket
+                while (!closeReady) {
+                    Thread.sleep(50);
+                }
+            }
+        }
+    }
+
+    /*
+     * Define the client side of the test.
+     *
+     * If the server prematurely exits, serverReady will be set to true
+     * to avoid infinite hangs.
+     */
+    private void doClientSide() throws Exception {
+        /*
+         * Wait for server to get started.
+         */
+        while (!serverReady) {
+            Thread.sleep(50);
+        }
+
+        // Send HTTP POST request to server
+        URL url = new URL("https://" + hostname + ":" + serverPort);
+
+        HttpsURLConnection.setDefaultHostnameVerifier(new NameVerifier());
+        HttpsURLConnection http = (HttpsURLConnection)url.openConnection();
+        http.setDoOutput(true);
+
+        http.setRequestMethod("POST");
+        PrintStream ps = new PrintStream(http.getOutputStream());
+        try {
+            ps.println(postMsg);
+            ps.flush();
+            if (http.getResponseCode() != 200) {
+                throw new RuntimeException("test Failed");
+            }
+        } finally {
+            ps.close();
+            http.disconnect();
+            closeReady = true;
+        }
+    }
+
+    private static class NameVerifier implements HostnameVerifier {
+        public boolean verify(String hostname, SSLSession session) {
+            return true;
+        }
+    }
+
+    /*
+     * =============================================================
+     * The remainder is just support stuff
+     */
+
+    // use any free port by default
+    private volatile int serverPort = 0;
+
+    private volatile Exception serverException = null;
+    private volatile Exception clientException = null;
+
+    public static void main(String[] args) throws Exception {
+        String keyFilename =
+            System.getProperty("test.src", "./") + "/" + pathToStores +
+                "/" + keyStoreFile;
+        String trustFilename =
+            System.getProperty("test.src", "./") + "/" + pathToStores +
+                "/" + trustStoreFile;
+
+        System.setProperty("javax.net.ssl.keyStore", keyFilename);
+        System.setProperty("javax.net.ssl.keyStorePassword", passwd);
+        System.setProperty("javax.net.ssl.trustStore", trustFilename);
+        System.setProperty("javax.net.ssl.trustStorePassword", passwd);
+
+        if (debug) {
+            System.setProperty("javax.net.debug", "all");
+        }
+
+        try {
+            hostname = InetAddress.getLocalHost().getCanonicalHostName();
+        } catch (UnknownHostException uhe) {
+            System.out.println(
+                "Ignore the test as the local hostname cannot be determined");
+
+            return;
+        }
+
+        System.out.println(
+                "The fully qualified domain name of the local host is " +
+                hostname);
+        // Ignore the test if the hostname does not sound like a domain name.
+        if ((hostname == null) || hostname.isEmpty() ||
+                hostname.startsWith("localhost") ||
+                Character.isDigit(hostname.charAt(hostname.length() - 1))) {
+
+            System.out.println("Ignore the test as the local hostname " +
+                    "cannot be determined as fully qualified domain name");
+
+            return;
+        }
+
+        /*
+         * Start the tests.
+         */
+        new ImpactOnSNI();
+    }
+
+    private Thread clientThread = null;
+    private Thread serverThread = null;
+
+    /*
+     * Primary constructor, used to drive remainder of the test.
+     *
+     * Fork off the other side, then do your work.
+     */
+    ImpactOnSNI() throws Exception {
+        Exception startException = null;
+        try {
+            if (separateServerThread) {
+                startServer(true);
+                startClient(false);
+            } else {
+                startClient(true);
+                startServer(false);
+            }
+        } catch (Exception e) {
+            startException = e;
+        }
+
+        /*
+         * Wait for other side to close down.
+         */
+        if (separateServerThread) {
+            if (serverThread != null) {
+                serverThread.join();
+            }
+        } else {
+            if (clientThread != null) {
+                clientThread.join();
+            }
+        }
+
+        /*
+         * When we get here, the test is pretty much over.
+         * Which side threw the error?
+         */
+        Exception local;
+        Exception remote;
+
+        if (separateServerThread) {
+            remote = serverException;
+            local = clientException;
+        } else {
+            remote = clientException;
+            local = serverException;
+        }
+
+        Exception exception = null;
+
+        /*
+         * Check various exception conditions.
+         */
+        if ((local != null) && (remote != null)) {
+            // If both failed, return the curthread's exception.
+            local.initCause(remote);
+            exception = local;
+        } else if (local != null) {
+            exception = local;
+        } else if (remote != null) {
+            exception = remote;
+        } else if (startException != null) {
+            exception = startException;
+        }
+
+        /*
+         * If there was an exception *AND* a startException,
+         * output it.
+         */
+        if (exception != null) {
+            if (exception != startException && startException != null) {
+                exception.addSuppressed(startException);
+            }
+            throw exception;
+        }
+
+        // Fall-through: no exception to throw!
+    }
+
+    private void startServer(boolean newThread) throws Exception {
+        if (newThread) {
+            serverThread = new Thread() {
+                @Override
+                public void run() {
+                    try {
+                        doServerSide();
+                    } catch (Exception e) {
+                        /*
+                         * Our server thread just died.
+                         *
+                         * Release the client, if not active already...
+                         */
+                        System.err.println("Server died...");
+                        serverReady = true;
+                        serverException = e;
+                    }
+                }
+            };
+            serverThread.start();
+        } else {
+            try {
+                doServerSide();
+            } catch (Exception e) {
+                serverException = e;
+            } finally {
+                serverReady = true;
+            }
+        }
+    }
+
+    private void startClient(boolean newThread) throws Exception {
+        if (newThread) {
+            clientThread = new Thread() {
+                @Override
+                public void run() {
+                    try {
+                        doClientSide();
+                    } catch (Exception e) {
+                        /*
+                         * Our client thread just died.
+                         */
+                        System.err.println("Client died...");
+                        clientException = e;
+                    }
+                }
+            };
+            clientThread.start();
+        } else {
+            try {
+                doClientSide();
+            } catch (Exception e) {
+                clientException = e;
+            }
+        }
+    }
+}
--- a/jdk/test/sun/security/provider/DSA/TestDSA2.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/test/sun/security/provider/DSA/TestDSA2.java	Wed Jul 05 21:37:42 2017 +0200
@@ -60,8 +60,8 @@
         boolean[] expectedToPass = { true, true, true, true,
                                      true, true, true, true };
         test(1024, expectedToPass);
-        boolean[] expectedToPass2 = { true, true, true, true,
-                                      true, true, true, true };
+        boolean[] expectedToPass2 = { true, false, true, true,
+                                      true, false, true, true };
         test(2048, expectedToPass2);
     }
 
--- a/jdk/test/sun/security/rsa/SpecTest.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/test/sun/security/rsa/SpecTest.java	Wed Jul 05 21:37:42 2017 +0200
@@ -20,32 +20,32 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
+
+/**
+ * @test
+ * @bug 8044199 8137231
+ * @key intermittent
+ * @summary Check same KeyPair's private key and public key have same modulus.
+ * also check public key's public exponent equals to given spec's public
+ * exponent. Only key size 1024 is tested with RSAKeyGenParameterSpec.F0 (3).
+ * @run main SpecTest 512
+ * @run main SpecTest 768
+ * @run main SpecTest 1024
+ * @run main SpecTest 1024 3
+ * @run main SpecTest 2048
+ * @run main/timeout=240 SpecTest 4096
+ * @run main/timeout=240 SpecTest 5120
+ */
 import java.math.BigInteger;
-import java.security.InvalidAlgorithmParameterException;
 import java.security.KeyPair;
 import java.security.KeyPairGenerator;
-import java.security.NoSuchAlgorithmException;
-import java.security.NoSuchProviderException;
 import java.security.interfaces.RSAKey;
 import java.security.interfaces.RSAPrivateKey;
 import java.security.interfaces.RSAPublicKey;
 import java.security.spec.RSAKeyGenParameterSpec;
 
-/**
- * @test
- * @bug 8044199
- * @key intermittent
- * @summary Check same KeyPair's private key and public key have same modulus.
- *  also check public key's public exponent equals to given spec's public
- *  exponent.
- * @run main SpecTest 512
- * @run main SpecTest 768
- * @run main SpecTest 1024
- * @run main SpecTest 2048
- * @run main/timeout=240 SpecTest 4096
- * @run main/timeout=240 SpecTest 5120
- */
 public class SpecTest {
+
     /**
      * ALGORITHM name, fixed as RSA.
      */
@@ -70,14 +70,14 @@
         // test the getModulus method
         if ((priv instanceof RSAKey) && (pub instanceof RSAKey)) {
             if (!priv.getModulus().equals(pub.getModulus())) {
-                System.err.println("priv.getModulus() = " + priv.getModulus());
-                System.err.println("pub.getModulus() = " + pub.getModulus());
+                System.out.println("priv.getModulus() = " + priv.getModulus());
+                System.out.println("pub.getModulus() = " + pub.getModulus());
                 passed = false;
             }
 
             if (!pubExponent.equals(pub.getPublicExponent())) {
-                System.err.println("pubExponent = " + pubExponent);
-                System.err.println("pub.getPublicExponent() = "
+                System.out.println("pubExponent = " + pubExponent);
+                System.out.println("pub.getPublicExponent() = "
                         + pub.getPublicExponent());
                 passed = false;
             }
@@ -85,36 +85,26 @@
         return passed;
     }
 
-    public static void main(String[] args) {
-        int failCount = 0;
+    public static void main(String[] args) throws Exception {
 
-        // Test key size.
-        int size = Integer.parseInt(args[0]);
+        int size = 0;
 
-        try {
-            KeyPairGenerator kpg1 = KeyPairGenerator.getInstance(KEYALG, PROVIDER);
-            kpg1.initialize(new RSAKeyGenParameterSpec(size,
-                    RSAKeyGenParameterSpec.F4));
-            if (!specTest(kpg1.generateKeyPair(),
-                    RSAKeyGenParameterSpec.F4)) {
-                failCount++;
-            }
-
-            KeyPairGenerator kpg2 = KeyPairGenerator.getInstance(KEYALG, PROVIDER);
-            kpg2.initialize(new RSAKeyGenParameterSpec(size,
-                    RSAKeyGenParameterSpec.F0));
-            if (!specTest(kpg2.generateKeyPair(), RSAKeyGenParameterSpec.F0)) {
-                failCount++;
-            }
-        } catch (NoSuchAlgorithmException | NoSuchProviderException
-                | InvalidAlgorithmParameterException ex) {
-            ex.printStackTrace(System.err);
-            failCount++;
+        if (args.length >= 1) {
+            size = Integer.parseInt(args[0]);
+        } else {
+            throw new RuntimeException("Missing keysize to test with");
         }
 
-        if (failCount != 0) {
-            throw new RuntimeException("There are " + failCount
-                    + " tests failed.");
+        BigInteger publicExponent
+                = (args.length >= 2) ? new BigInteger(args[1]) : RSAKeyGenParameterSpec.F4;
+
+        System.out.println("Running test with key size: " + size
+                + " and public exponent: " + publicExponent);
+
+        KeyPairGenerator kpg1 = KeyPairGenerator.getInstance(KEYALG, PROVIDER);
+        kpg1.initialize(new RSAKeyGenParameterSpec(size, publicExponent));
+        if (!specTest(kpg1.generateKeyPair(), publicExponent)) {
+            throw new RuntimeException("Test failed.");
         }
     }
 }
--- a/jdk/test/sun/security/ssl/SSLContextImpl/MD2InTrustAnchor.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/test/sun/security/ssl/SSLContextImpl/MD2InTrustAnchor.java	Wed Jul 05 21:37:42 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
@@ -37,106 +37,88 @@
  * @run main/othervm MD2InTrustAnchor PKIX TLSv1.2
  * @run main/othervm MD2InTrustAnchor SunX509 TLSv1.2
  */
-
-import java.net.*;
-import java.util.*;
-import java.io.*;
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
 import javax.net.ssl.*;
 import java.security.Security;
 import java.security.KeyStore;
 import java.security.KeyFactory;
 import java.security.cert.Certificate;
 import java.security.cert.CertificateFactory;
-import java.security.spec.*;
-import java.security.interfaces.*;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.spec.PKCS8EncodedKeySpec;
 import java.util.Base64;
+import java.util.concurrent.CountDownLatch;
 
 public class MD2InTrustAnchor {
 
     /*
-     * =============================================================
-     * Set the various variables needed for the tests, then
-     * specify what tests to run on each side.
-     */
-
-    /*
-     * Should we run the client or server in a separate thread?
-     * Both sides can throw exceptions, but do you have a preference
-     * as to which side should be the main thread.
-     */
-    static boolean separateServerThread = false;
-
-    /*
      * Certificates and key used in the test.
      */
-
     // It's a trust anchor signed with MD2 hash function.
-    static String trustedCertStr =
-        "-----BEGIN CERTIFICATE-----\n" +
-        "MIICkjCCAfugAwIBAgIBADANBgkqhkiG9w0BAQIFADA7MQswCQYDVQQGEwJVUzEN\n" +
-        "MAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwHhcN\n" +
-        "MTExMTE4MTExNDA0WhcNMzIxMDI4MTExNDA0WjA7MQswCQYDVQQGEwJVUzENMAsG\n" +
-        "A1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwgZ8wDQYJ\n" +
-        "KoZIhvcNAQEBBQADgY0AMIGJAoGBAPGyB9tugUGgxtdeqe0qJEwf9x1Gy4BOi1yR\n" +
-        "wzDZY4H5LquvIfQ2V3J9X1MQENVsFvkvp65ZcFcy+ObOucXUUPFcd/iw2DVb5QXA\n" +
-        "ffyeVqWD56GPi8Qe37wrJO3L6fBhN9oxp/BbdRLgjU81zx8qLEyPODhPMxV4OkcA\n" +
-        "SDwZTSxxAgMBAAGjgaUwgaIwHQYDVR0OBBYEFLOAtr/YrYj9H04EDLA0fd14jisF\n" +
-        "MGMGA1UdIwRcMFqAFLOAtr/YrYj9H04EDLA0fd14jisFoT+kPTA7MQswCQYDVQQG\n" +
-        "EwJVUzENMAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2\n" +
-        "Y2WCAQAwDwYDVR0TAQH/BAUwAwEB/zALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQEC\n" +
-        "BQADgYEAr8ExpXu/FTIRiMzPm0ubqwME4lniilwQUiEOD/4DbksNjEIcUyS2hIk1\n" +
-        "qsmjJz3SHBnwhxl9dhJVwk2tZLkPGW86Zn0TPVRsttK4inTgCC9GFGeqQBdrU/uf\n" +
-        "lipBzXWljrfbg4N/kK8m2LabtKUMMnGysM8rN0Fx2PYm5xxGvtM=\n" +
-        "-----END CERTIFICATE-----";
+    private static final String TRUSTED_CERT_STR = "-----BEGIN CERTIFICATE-----\n"
+            + "MIICkjCCAfugAwIBAgIBADANBgkqhkiG9w0BAQIFADA7MQswCQYDVQQGEwJVUzEN\n"
+            + "MAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwHhcN\n"
+            + "MTExMTE4MTExNDA0WhcNMzIxMDI4MTExNDA0WjA7MQswCQYDVQQGEwJVUzENMAsG\n"
+            + "A1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwgZ8wDQYJ\n"
+            + "KoZIhvcNAQEBBQADgY0AMIGJAoGBAPGyB9tugUGgxtdeqe0qJEwf9x1Gy4BOi1yR\n"
+            + "wzDZY4H5LquvIfQ2V3J9X1MQENVsFvkvp65ZcFcy+ObOucXUUPFcd/iw2DVb5QXA\n"
+            + "ffyeVqWD56GPi8Qe37wrJO3L6fBhN9oxp/BbdRLgjU81zx8qLEyPODhPMxV4OkcA\n"
+            + "SDwZTSxxAgMBAAGjgaUwgaIwHQYDVR0OBBYEFLOAtr/YrYj9H04EDLA0fd14jisF\n"
+            + "MGMGA1UdIwRcMFqAFLOAtr/YrYj9H04EDLA0fd14jisFoT+kPTA7MQswCQYDVQQG\n"
+            + "EwJVUzENMAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2\n"
+            + "Y2WCAQAwDwYDVR0TAQH/BAUwAwEB/zALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQEC\n"
+            + "BQADgYEAr8ExpXu/FTIRiMzPm0ubqwME4lniilwQUiEOD/4DbksNjEIcUyS2hIk1\n"
+            + "qsmjJz3SHBnwhxl9dhJVwk2tZLkPGW86Zn0TPVRsttK4inTgCC9GFGeqQBdrU/uf\n"
+            + "lipBzXWljrfbg4N/kK8m2LabtKUMMnGysM8rN0Fx2PYm5xxGvtM=\n"
+            + "-----END CERTIFICATE-----";
 
     // The certificate issued by above trust anchor, signed with MD5
-    static String targetCertStr =
-        "-----BEGIN CERTIFICATE-----\n" +
-        "MIICeDCCAeGgAwIBAgIBAjANBgkqhkiG9w0BAQQFADA7MQswCQYDVQQGEwJVUzEN\n" +
-        "MAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwHhcN\n" +
-        "MTExMTE4MTExNDA2WhcNMzEwODA1MTExNDA2WjBPMQswCQYDVQQGEwJVUzENMAsG\n" +
-        "A1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UxEjAQBgNV\n" +
-        "BAMTCWxvY2FsaG9zdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwDnm96mw\n" +
-        "fXCH4bgXk1US0VcJsQVxUtGMyncAveMuzBzNzOmKZPeqyYX1Fuh4q+cuza03WTJd\n" +
-        "G9nOkNr364e3Rn1aaHjCMcBmFflObnGnhhufNmIGYogJ9dJPmhUVPEVAXrMG+Ces\n" +
-        "NKy2E8woGnLMrqu6yiuTClbLBPK8fWzTXrECAwEAAaN4MHYwCwYDVR0PBAQDAgPo\n" +
-        "MB0GA1UdDgQWBBSdRrpocLPJXyGfDmMWJrcEf29WGDAfBgNVHSMEGDAWgBSzgLa/\n" +
-        "2K2I/R9OBAywNH3deI4rBTAnBgNVHSUEIDAeBggrBgEFBQcDAQYIKwYBBQUHAwIG\n" +
-        "CCsGAQUFBwMDMA0GCSqGSIb3DQEBBAUAA4GBAKJ71ZiCUykkJrCLYUxlFlhvUcr9\n" +
-        "sTcOc67QdroW5f412NI15SXWDiley/JOasIiuIFPjaJBjOKoHOvTjG/snVu9wEgq\n" +
-        "YNR8dPsO+NM8r79C6jO+Jx5fYAC7os2XxS75h3NX0ElJcbwIXGBJ6xRrsFh/BGYH\n" +
-        "yvudOlX4BkVR0l1K\n" +
-        "-----END CERTIFICATE-----";
+    private static final String TARGET_CERT_STR = "-----BEGIN CERTIFICATE-----\n"
+            + "MIICeDCCAeGgAwIBAgIBAjANBgkqhkiG9w0BAQQFADA7MQswCQYDVQQGEwJVUzEN\n"
+            + "MAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwHhcN\n"
+            + "MTExMTE4MTExNDA2WhcNMzEwODA1MTExNDA2WjBPMQswCQYDVQQGEwJVUzENMAsG\n"
+            + "A1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UxEjAQBgNV\n"
+            + "BAMTCWxvY2FsaG9zdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwDnm96mw\n"
+            + "fXCH4bgXk1US0VcJsQVxUtGMyncAveMuzBzNzOmKZPeqyYX1Fuh4q+cuza03WTJd\n"
+            + "G9nOkNr364e3Rn1aaHjCMcBmFflObnGnhhufNmIGYogJ9dJPmhUVPEVAXrMG+Ces\n"
+            + "NKy2E8woGnLMrqu6yiuTClbLBPK8fWzTXrECAwEAAaN4MHYwCwYDVR0PBAQDAgPo\n"
+            + "MB0GA1UdDgQWBBSdRrpocLPJXyGfDmMWJrcEf29WGDAfBgNVHSMEGDAWgBSzgLa/\n"
+            + "2K2I/R9OBAywNH3deI4rBTAnBgNVHSUEIDAeBggrBgEFBQcDAQYIKwYBBQUHAwIG\n"
+            + "CCsGAQUFBwMDMA0GCSqGSIb3DQEBBAUAA4GBAKJ71ZiCUykkJrCLYUxlFlhvUcr9\n"
+            + "sTcOc67QdroW5f412NI15SXWDiley/JOasIiuIFPjaJBjOKoHOvTjG/snVu9wEgq\n"
+            + "YNR8dPsO+NM8r79C6jO+Jx5fYAC7os2XxS75h3NX0ElJcbwIXGBJ6xRrsFh/BGYH\n"
+            + "yvudOlX4BkVR0l1K\n"
+            + "-----END CERTIFICATE-----";
 
     // Private key in the format of PKCS#8.
-    static String targetPrivateKey =
-        "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMA55vepsH1wh+G4\n" +
-        "F5NVEtFXCbEFcVLRjMp3AL3jLswczczpimT3qsmF9RboeKvnLs2tN1kyXRvZzpDa\n" +
-        "9+uHt0Z9Wmh4wjHAZhX5Tm5xp4YbnzZiBmKICfXST5oVFTxFQF6zBvgnrDSsthPM\n" +
-        "KBpyzK6rusorkwpWywTyvH1s016xAgMBAAECgYEAn9bF3oRkdDoBU0i/mcww5I+K\n" +
-        "SH9tFt+WQbiojjz9ac49trkvUfu7MO1Jui2+QbrvaSkyj+HYGFOJd1wMsPXeB7ck\n" +
-        "5mOIYV4uZK8jfNMSQ8v0tFEeIPp5lKdw1XnrQfSe+abo2eL5Lwso437Y4s3w37+H\n" +
-        "aY3d76hR5qly+Ys+Ww0CQQDjeOoX89d/xhRqGXKjCx8ImE/dPmsI8O27cwtKrDYJ\n" +
-        "6t0v/xryVIdvOYcRBvKnqEogOH7T1kI+LnWKUTJ2ehJ7AkEA2FVloPVqCehXcc7e\n" +
-        "z3TDpU9w1B0JXklcV5HddYsRqp9RukN/VK4szKE7F1yoarIUtfE9Lr9082Jwyp3M\n" +
-        "L11xwwJBAKsZ+Hur3x0tUY29No2Nf/pnFyvEF57SGwA0uPmiL8Ol9lpz+UDudDEl\n" +
-        "hIM6Rqv12kwCMuQE9i7vo1o3WU3k5KECQEqhg1L49yD935TqiiFFpe0Ur9btQXse\n" +
-        "kdXAA4d2d5zGI7q/aGD9SYU6phkUJSHR16VA2RuUfzMrpb+wmm1IrmMCQFtLoKRT\n" +
-        "A5kokFb+E3Gplu29tJvCUpfwgBFRS+wmkvtiaU/tiyDcVgDO+An5DwedxxdVzqiE\n" +
-        "njWHoKY3axDQ8OU=\n";
+    private static final String TARGET_PRIV_KEY_STR = "MIICdwIBADANBgkqhkiG9w0B\n"
+            + "AQEFAASCAmEwggJdAgEAAoGBAMA55vepsH1wh+G4F5NVEtFXCbEFcVLRjMp3AL3j\n"
+            + "LswczczpimT3qsmF9RboeKvnLs2tN1kyXRvZzpDa9+uHt0Z9Wmh4wjHAZhX5Tm5x\n"
+            + "p4YbnzZiBmKICfXST5oVFTxFQF6zBvgnrDSsthPMKBpyzK6rusorkwpWywTyvH1s\n"
+            + "016xAgMBAAECgYEAn9bF3oRkdDoBU0i/mcww5I+KSH9tFt+WQbiojjz9ac49trkv\n"
+            + "Ufu7MO1Jui2+QbrvaSkyj+HYGFOJd1wMsPXeB7ck5mOIYV4uZK8jfNMSQ8v0tFEe\n"
+            + "IPp5lKdw1XnrQfSe+abo2eL5Lwso437Y4s3w37+HaY3d76hR5qly+Ys+Ww0CQQDj\n"
+            + "eOoX89d/xhRqGXKjCx8ImE/dPmsI8O27cwtKrDYJ6t0v/xryVIdvOYcRBvKnqEog\n"
+            + "OH7T1kI+LnWKUTJ2ehJ7AkEA2FVloPVqCehXcc7ez3TDpU9w1B0JXklcV5HddYsR\n"
+            + "qp9RukN/VK4szKE7F1yoarIUtfE9Lr9082Jwyp3ML11xwwJBAKsZ+Hur3x0tUY29\n"
+            + "No2Nf/pnFyvEF57SGwA0uPmiL8Ol9lpz+UDudDElhIM6Rqv12kwCMuQE9i7vo1o3\n"
+            + "WU3k5KECQEqhg1L49yD935TqiiFFpe0Ur9btQXsekdXAA4d2d5zGI7q/aGD9SYU6\n"
+            + "phkUJSHR16VA2RuUfzMrpb+wmm1IrmMCQFtLoKRTA5kokFb+E3Gplu29tJvCUpfw\n"
+            + "gBFRS+wmkvtiaU/tiyDcVgDO+An5DwedxxdVzqiEnjWHoKY3axDQ8OU=";
 
-
-    static char passphrase[] = "passphrase".toCharArray();
+    private static final char PASSPHRASE[] = "passphrase".toCharArray();
 
     /*
      * Is the server ready to serve?
      */
-    volatile static boolean serverReady = false;
+    private static volatile CountDownLatch sync = new CountDownLatch(1);
 
     /*
      * Turn on SSL debugging?
      */
-    static boolean debug = false;
+    private static final boolean DEBUG = false;
 
     /*
      * Define the server side of the test.
@@ -144,29 +126,30 @@
      * If the server prematurely exits, serverReady will be set to true
      * to avoid infinite hangs.
      */
-    void doServerSide() throws Exception {
-        SSLContext context = generateSSLContext(trustedCertStr, targetCertStr,
-                                            targetPrivateKey);
+    private void doServerSide() throws Exception {
+        SSLContext context = generateSSLContext(TRUSTED_CERT_STR, TARGET_CERT_STR,
+                TARGET_PRIV_KEY_STR);
         SSLServerSocketFactory sslssf = context.getServerSocketFactory();
-        SSLServerSocket sslServerSocket =
-            (SSLServerSocket)sslssf.createServerSocket(serverPort);
-        sslServerSocket.setNeedClientAuth(true);
-        serverPort = sslServerSocket.getLocalPort();
+        try (SSLServerSocket sslServerSocket
+                = (SSLServerSocket) sslssf.createServerSocket(serverPort)) {
+            sslServerSocket.setNeedClientAuth(true);
+            serverPort = sslServerSocket.getLocalPort();
+            /*
+            * Signal Client, we're ready for his connect.
+             */
+            System.out.println("Signal server ready");
+            sync.countDown();
 
-        /*
-         * Signal Client, we're ready for his connect.
-         */
-        serverReady = true;
+            System.out.println("Waiting for client connection");
+            try (SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept()) {
+                InputStream sslIS = sslSocket.getInputStream();
+                OutputStream sslOS = sslSocket.getOutputStream();
 
-        SSLSocket sslSocket = (SSLSocket)sslServerSocket.accept();
-        InputStream sslIS = sslSocket.getInputStream();
-        OutputStream sslOS = sslSocket.getOutputStream();
-
-        sslIS.read();
-        sslOS.write('A');
-        sslOS.flush();
-
-        sslSocket.close();
+                sslIS.read();
+                sslOS.write('A');
+                sslOS.flush();
+            }
+        }
     }
 
     /*
@@ -175,33 +158,31 @@
      * If the server prematurely exits, serverReady will be set to true
      * to avoid infinite hangs.
      */
-    void doClientSide() throws Exception {
+    private void doClientSide() throws Exception {
 
         /*
          * Wait for server to get started.
          */
-        while (!serverReady) {
-            Thread.sleep(50);
-        }
+        System.out.println("Waiting for server ready");
+        sync.await();
 
-        SSLContext context = generateSSLContext(trustedCertStr, targetCertStr,
-                                            targetPrivateKey);
+        SSLContext context = generateSSLContext(TRUSTED_CERT_STR, TARGET_CERT_STR,
+                TARGET_PRIV_KEY_STR);
         SSLSocketFactory sslsf = context.getSocketFactory();
 
-        SSLSocket sslSocket =
-            (SSLSocket)sslsf.createSocket("localhost", serverPort);
-
-        // enable the specified TLS protocol
-        sslSocket.setEnabledProtocols(new String[] {tlsProtocol});
+        System.out.println("Connect to server on port: " + serverPort);
+        try (SSLSocket sslSocket
+                = (SSLSocket) sslsf.createSocket("localhost", serverPort)) {
+            // enable the specified TLS protocol
+            sslSocket.setEnabledProtocols(new String[]{tlsProtocol});
 
-        InputStream sslIS = sslSocket.getInputStream();
-        OutputStream sslOS = sslSocket.getOutputStream();
+            InputStream sslIS = sslSocket.getInputStream();
+            OutputStream sslOS = sslSocket.getOutputStream();
 
-        sslOS.write('B');
-        sslOS.flush();
-        sslIS.read();
-
-        sslSocket.close();
+            sslOS.write('B');
+            sslOS.flush();
+            sslIS.read();
+        }
     }
 
     /*
@@ -240,10 +221,10 @@
         if (keyCertStr != null) {
             // generate the private key.
             PKCS8EncodedKeySpec priKeySpec = new PKCS8EncodedKeySpec(
-                                Base64.getMimeDecoder().decode(keySpecStr));
+                    Base64.getMimeDecoder().decode(keySpecStr));
             KeyFactory kf = KeyFactory.getInstance("RSA");
-            RSAPrivateKey priKey =
-                    (RSAPrivateKey)kf.generatePrivate(priKeySpec);
+            RSAPrivateKey priKey
+                    = (RSAPrivateKey) kf.generatePrivate(priKeySpec);
 
             // generate certificate chain
             is = new ByteArrayInputStream(keyCertStr.getBytes());
@@ -257,7 +238,7 @@
             chain[0] = keyCert;
 
             // import the key entry.
-            ks.setKeyEntry("Whatever", priKey, passphrase, chain);
+            ks.setKeyEntry("Whatever", priKey, PASSPHRASE, chain);
         }
 
         // create SSL context
@@ -267,7 +248,7 @@
         SSLContext ctx = SSLContext.getInstance(tlsProtocol);
         if (keyCertStr != null && !keyCertStr.isEmpty()) {
             KeyManagerFactory kmf = KeyManagerFactory.getInstance("NewSunX509");
-            kmf.init(ks, passphrase);
+            kmf.init(ks, PASSPHRASE);
 
             ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
             ks = null;
@@ -278,12 +259,10 @@
         return ctx;
     }
 
+    // use any free port by default
+    private volatile int serverPort = 0;
 
-    // use any free port by default
-    volatile int serverPort = 0;
-
-    volatile Exception serverException = null;
-    volatile Exception clientException = null;
+    private volatile Exception serverException = null;
 
     public static void main(String[] args) throws Exception {
         // MD5 is used in this test case, don't disable MD5 algorithm.
@@ -292,140 +271,61 @@
         Security.setProperty("jdk.tls.disabledAlgorithms",
                 "SSLv3, RC4, DH keySize < 768");
 
-        if (debug)
+        if (DEBUG) {
             System.setProperty("javax.net.debug", "all");
+        }
 
         /*
          * Get the customized arguments.
          */
         parseArguments(args);
-
         /*
          * Start the tests.
          */
-        new MD2InTrustAnchor();
+        new MD2InTrustAnchor().runTest();
     }
 
-    Thread clientThread = null;
-    Thread serverThread = null;
+    private Thread serverThread = null;
 
     /*
-     * Primary constructor, used to drive remainder of the test.
+     * Used to drive remainder of the test.
      *
      * Fork off the other side, then do your work.
      */
-    MD2InTrustAnchor() throws Exception {
-        try {
-            if (separateServerThread) {
-                startServer(true);
-                startClient(false);
-            } else {
-                startClient(true);
-                startServer(false);
-            }
-        } catch (Exception e) {
-            // swallow for now.  Show later
-        }
+    public void runTest() throws Exception {
+        startServerThread();
+        doClientSide();
 
         /*
          * Wait for other side to close down.
          */
-        if (separateServerThread) {
-            serverThread.join();
-        } else {
-            clientThread.join();
-        }
-
-        /*
-         * When we get here, the test is pretty much over.
-         * Which side threw the error?
-         */
-        Exception local;
-        Exception remote;
-        String whichRemote;
+        serverThread.join();
 
-        if (separateServerThread) {
-            remote = serverException;
-            local = clientException;
-            whichRemote = "server";
-        } else {
-            remote = clientException;
-            local = serverException;
-            whichRemote = "client";
-        }
-
-        /*
-         * If both failed, return the curthread's exception, but also
-         * print the remote side Exception
-         */
-        if ((local != null) && (remote != null)) {
-            System.out.println(whichRemote + " also threw:");
-            remote.printStackTrace();
-            System.out.println();
-            throw local;
-        }
-
-        if (remote != null) {
-            throw remote;
-        }
-
-        if (local != null) {
-            throw local;
+        if (serverException != null) {
+            throw serverException;
         }
     }
 
-    void startServer(boolean newThread) throws Exception {
-        if (newThread) {
-            serverThread = new Thread() {
-                public void run() {
-                    try {
-                        doServerSide();
-                    } catch (Exception e) {
-                        /*
-                         * Our server thread just died.
-                         *
-                         * Release the client, if not active already...
-                         */
-                        System.err.println("Server died...");
-                        serverReady = true;
-                        serverException = e;
-                    }
+    private void startServerThread() {
+        serverThread = new Thread() {
+            @Override
+            public void run() {
+                try {
+                    doServerSide();
+                } catch (Exception e) {
+                    /*
+                     * Our server thread just died.
+                     *
+                     * Release the client, if not active already...
+                     */
+                    System.err.println("Server died...");
+                    e.printStackTrace(System.out);
+                    serverException = e;
+                    sync.countDown();
                 }
-            };
-            serverThread.start();
-        } else {
-            try {
-                doServerSide();
-            } catch (Exception e) {
-                serverException = e;
-            } finally {
-                serverReady = true;
             }
-        }
-    }
+        };
 
-    void startClient(boolean newThread) throws Exception {
-        if (newThread) {
-            clientThread = new Thread() {
-                public void run() {
-                    try {
-                        doClientSide();
-                    } catch (Exception e) {
-                        /*
-                         * Our client thread just died.
-                         */
-                        System.err.println("Client died...");
-                        clientException = e;
-                    }
-                }
-            };
-            clientThread.start();
-        } else {
-            try {
-                doClientSide();
-            } catch (Exception e) {
-                clientException = e;
-            }
-        }
+        serverThread.start();
     }
 }
--- a/jdk/test/tools/jimage/JImageTest.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/test/tools/jimage/JImageTest.java	Wed Jul 05 21:37:42 2017 +0200
@@ -110,54 +110,5 @@
                 .dir(helper.createNewExtractedDir("modules"))
                 .image(image.resolve("lib").resolve("modules"))
                 .extract().assertSuccess();
-
-        Path recreatedImage = JImageGenerator.getJImageTask()
-                .dir(extractedDir)
-                .image(helper.createNewRecreatedDir(extractedDir.getFileName().toString()))
-                .recreate().assertSuccess();
-        JImageValidator.validate(recreatedImage, bootClasses, Collections.emptyList());
-
-        // Check replacing the boot image by recreated one
-        Path destFile = image.resolve("lib").resolve("modules");
-        Files.copy(recreatedImage, destFile, REPLACE_EXISTING);
-        JImageValidator validator = new JImageValidator(module, Collections.emptyList(),
-                image.toFile(), Collections.emptyList(), Collections.emptyList());
-        validator.validate();
-
-        Path recreatedImage2 = JImageGenerator.getJImageTask()
-                .dir(extractedDir)
-                .option("--compress").option("2")
-                .image(helper.createNewRecreatedDir(extractedDir.getFileName().toString()))
-                .recreate().assertSuccess();
-        JImageValidator.validate(recreatedImage2, bootClasses, Collections.emptyList());
-
-        Path recreatedImage3 = JImageGenerator.getJImageTask()
-                .dir(extractedDir)
-                .option("--strip-debug")
-                .image(helper.createNewRecreatedDir(extractedDir.getFileName().toString()))
-                .recreate().assertSuccess();
-        JImageValidator.validate(recreatedImage3, bootClasses, Collections.emptyList());
-
-        Path recreatedImage4 = JImageGenerator.getJImageTask()
-                .dir(extractedDir)
-                .option("--exclude-resources")
-                .option("*.jcov, */META-INF/*")
-                .image(helper.createNewRecreatedDir(extractedDir.getFileName().toString()))
-                .recreate().assertSuccess();
-        List<String> unexpectedPaths = new ArrayList<>();
-        unexpectedPaths.add(".jcov");
-        unexpectedPaths.add("/META-INF/");
-        JImageValidator.validate(recreatedImage4, bootClasses, unexpectedPaths);
-
-        Path recreatedImage5 = JImageGenerator.getJImageTask()
-                .dir(extractedDir)
-                .option("--compress")
-                .option("2")
-                .option("--strip-debug")
-                .option("--exclude-resources")
-                .option("*.jcov, */META-INF/*")
-                .image(helper.createNewRecreatedDir(extractedDir.getFileName().toString()))
-                .recreate().assertSuccess();
-        JImageValidator.validate(recreatedImage5, bootClasses, unexpectedPaths);
     }
 }
--- a/jdk/test/tools/jimage/JImageToolTest.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/test/tools/jimage/JImageToolTest.java	Wed Jul 05 21:37:42 2017 +0200
@@ -63,11 +63,7 @@
             String jimage = jimagePath.toAbsolutePath().toString();
             String bootimage = modulesimagePath.toAbsolutePath().toString();
             String extractDir = Paths.get(".", "extract").toAbsolutePath().toString();
-            String recreateImage = Paths.get(".", "recreate").toAbsolutePath().toString();
-            String relativeRecreateImage = Paths.get(".", "recreate2").toString();
             jimage("extract", "--dir", extractDir, bootimage);
-            jimage("recreate", "--dir", extractDir, recreateImage);
-            jimage("recreate", "--dir", extractDir, relativeRecreateImage);
             System.out.println("Test successful");
          } else {
             System.out.println("Test skipped, not an images build");
--- a/jdk/test/tools/jlink/plugins/InstalledModuleDescriptors/src/m1/p1/Main.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/test/tools/jlink/plugins/InstalledModuleDescriptors/src/m1/p1/Main.java	Wed Jul 05 21:37:42 2017 +0200
@@ -29,6 +29,7 @@
 import java.nio.file.FileSystems;
 import java.nio.file.Files;
 import java.nio.file.Path;
+import java.util.Collections;
 import java.util.Set;
 
 public class Main {
@@ -40,7 +41,8 @@
         validate(Main.class.getModule().getDescriptor());
 
         // read m1/module-info.class
-        FileSystem fs = FileSystems.newFileSystem(URI.create("jrt:/"), null);
+        FileSystem fs = FileSystems.newFileSystem(URI.create("jrt:/"),
+                                                  Collections.emptyMap());
         Path path = fs.getPath("/", "modules", "m1", "module-info.class");
         validate(ModuleDescriptor.read(Files.newInputStream(path)));
     }
--- a/jdk/test/tools/launcher/Arrrghs.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/test/tools/launcher/Arrrghs.java	Wed Jul 05 21:37:42 2017 +0200
@@ -489,7 +489,7 @@
             return;
         }
 
-        TestResult tr = null;
+        TestResult tr;
 
         // a missing class
         createJar("MIA", new File("some.jar"), new File("Foo"),
@@ -592,7 +592,7 @@
         if (!isEnglishLocale()) { // only english version
             return;
         }
-        TestResult tr = null;
+        TestResult tr;
         // a missing class
         createJar("MIA", new File("some.jar"), new File("Foo"),
                 (String[])null);
--- a/jdk/test/tools/launcher/DefaultLocaleTestRun.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/test/tools/launcher/DefaultLocaleTestRun.java	Wed Jul 05 21:37:42 2017 +0200
@@ -41,7 +41,7 @@
             System.out.println("Test passes vacuously on non-windows");
             return;
         }
-        TestResult tr = null;
+        TestResult tr;
         tr = doExec(javaCmd,
                 "-cp", TEST_CLASSES_DIR.getAbsolutePath(),
                 "DefaultLocaleTest", "-w", "x.out");
--- a/jdk/test/tools/launcher/ExecutionEnvironment.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/test/tools/launcher/ExecutionEnvironment.java	Wed Jul 05 21:37:42 2017 +0200
@@ -120,15 +120,14 @@
      */
     @Test
     void testEcoFriendly() {
-        TestResult tr = null;
-
         Map<String, String> env = new HashMap<>();
         for (String x : LD_PATH_STRINGS) {
             String pairs[] = x.split("=");
             env.put(pairs[0], pairs[1]);
         }
 
-        tr = doExec(env, javaCmd, "-jar", testJarFile.getAbsolutePath());
+        TestResult tr =
+            doExec(env, javaCmd, "-jar", testJarFile.getAbsolutePath());
 
         if (!tr.isNotZeroOutput()) {
             flagError(tr, "Error: No output at all. Did the test execute ?");
@@ -180,7 +179,7 @@
      */
     @Test
     void testJavaLibraryPath() {
-        TestResult tr = null;
+        TestResult tr;
 
         Map<String, String> env = new HashMap<>();
 
@@ -240,17 +239,14 @@
      */
     @Test
     void testVmSelection() {
-
-        TestResult tr = null;
-
         if (haveClientVM) {
-            tr = doExec(javaCmd, "-client", "-version");
+            TestResult tr = doExec(javaCmd, "-client", "-version");
             if (!tr.matches(".*Client VM.*")) {
                 flagError(tr, "the expected vm -client did not launch");
             }
         }
         if (haveServerVM) {
-            tr = doExec(javaCmd, "-server", "-version");
+            TestResult tr = doExec(javaCmd, "-server", "-version");
             if (!tr.matches(".*Server VM.*")) {
                 flagError(tr, "the expected vm -server did not launch");
             }
--- a/jdk/test/tools/launcher/FXLauncherTest.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/test/tools/launcher/FXLauncherTest.java	Wed Jul 05 21:37:42 2017 +0200
@@ -239,7 +239,7 @@
             createFile(ManifestFile, createManifestContents(StdMainClass, fxMC));
             createJar(FXtestJar, ManifestFile);
             String sTestJar = FXtestJar.getAbsolutePath();
-            TestResult tr;
+            final TestResult tr;
             if (useCP) {
                 tr = doExec(javaCmd, "-cp", sTestJar, StdMainClass, APP_PARMS[0], APP_PARMS[1]);
             } else {
@@ -290,7 +290,7 @@
             createFile(ManifestFile, createManifestContents(ExtMainClass, fxMC));
             createJar(FXtestJar, ManifestFile);
             String sTestJar = FXtestJar.getAbsolutePath();
-            TestResult tr;
+            final TestResult tr;
             if (useCP) {
                 tr = doExec(javaCmd, "-cp", sTestJar, ExtMainClass, APP_PARMS[0], APP_PARMS[1]);
             } else {
@@ -359,7 +359,7 @@
         createFile(ManifestFile, createManifestContents(NonFXMainClass, null));
         createJar(FXtestJar, ManifestFile);
         String sTestJar = FXtestJar.getAbsolutePath();
-        TestResult tr;
+        final TestResult tr;
 
         if (useCP) {
             tr = doExec(javaCmd, "-verbose:class", "-cp", sTestJar, NonFXMainClass, APP_PARMS[0], APP_PARMS[1]);
--- a/jdk/test/tools/launcher/I18NTest.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/test/tools/launcher/I18NTest.java	Wed Jul 05 21:37:42 2017 +0200
@@ -60,7 +60,7 @@
 
         // compile the generate code using the javac compiler vs. the api, to
         // as a bonus point to see if the argument is passed correctly
-        TestResult tr = null;
+        TestResult tr;
         tr = doExec(javacCmd, fileName + JAVA_FILE_EXT);
         if (!tr.isOK()) {
             System.out.println(tr);
--- a/jdk/test/tools/launcher/MiscTests.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/test/tools/launcher/MiscTests.java	Wed Jul 05 21:37:42 2017 +0200
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 6856415 8154212
+ * @bug 6856415 8154212 8154470
  * @summary Miscellaneous tests, Exceptions
  * @compile -XDignore.symbol.file MiscTests.java
  * @run main MiscTests
@@ -95,30 +95,34 @@
 
         TestResult tr = doExec(javaCmd,
                 "-Djava.security.manager", "-jar", testJar.getName(), "foo.bak");
-        for (String s : tr.testOutput) {
-            System.out.println(s);
-        }
         if (!tr.contains("java.security.AccessControlException:" +
                 " access denied (\"java.lang.RuntimePermission\"" +
                 " \"accessClassInPackage.sun.security.pkcs11\")")) {
-            System.out.println(tr.status);
+            System.out.println(tr);
         }
     }
 
-    static void testJLDEnvWithTool() {
-        final Map<String, String> envMap = new HashMap<>();
-        envMap.put("_JAVA_LAUNCHER_DEBUG", "true");
-        TestResult tr = doExec(envMap, javacCmd, "-version");
-        tr.checkPositive();
-        if (!tr.isOK()) {
-           System.out.println(tr);
+    static void testJLDEnv() {
+        final Map<String, String> envToSet = new HashMap<>();
+        envToSet.put("_JAVA_LAUNCHER_DEBUG", "true");
+        for (String cmd : new String[] { javaCmd, javacCmd }) {
+            TestResult tr = doExec(envToSet, cmd, "-version");
+            tr.checkPositive();
+            String javargs = cmd.equals(javacCmd) ? "on" : "off";
+            String progname = cmd.equals(javacCmd) ? "javac" : "java";
+            if (!tr.isOK()
+                || !tr.matches("\\s*debug:on$")
+                || !tr.matches("\\s*javargs:" + javargs + "$")
+                || !tr.matches("\\s*program name:" + progname + "$")) {
+                System.out.println(tr);
+            }
         }
     }
 
     public static void main(String... args) throws IOException {
         testWithClassPathSetViaProperty();
         test6856415();
-        testJLDEnvWithTool();
+        testJLDEnv();
         if (testExitValue != 0) {
             throw new Error(testExitValue + " tests failed");
         }
--- a/jdk/test/tools/launcher/Settings.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/test/tools/launcher/Settings.java	Wed Jul 05 21:37:42 2017 +0200
@@ -55,9 +55,9 @@
         }
     }
 
-    static void checkNoContains(TestResult tr, String str) {
-        if (tr.contains(str)) {
-            System.out.println(tr.status);
+    static void checkNotContains(TestResult tr, String str) {
+        if (!tr.notContains(str)) {
+            System.out.println(tr);
             throw new RuntimeException(str + " found");
         }
     }
@@ -77,84 +77,77 @@
         if (getArch().equals("ppc64") || getArch().equals("ppc64le")) {
             stackSize = "800";
         }
-        TestResult tr = null;
+        TestResult tr;
         tr = doExec(javaCmd, "-Xms64m", "-Xmx512m",
                 "-Xss" + stackSize + "k", "-XshowSettings", "-jar", testJar.getAbsolutePath());
         containsAllOptions(tr);
         if (!tr.isOK()) {
-            System.out.println(tr.status);
+            System.out.println(tr);
             throw new RuntimeException("test fails");
         }
         tr = doExec(javaCmd, "-Xms65536k", "-Xmx712m",
                 "-Xss" + stackSize + "000", "-XshowSettings", "-jar", testJar.getAbsolutePath());
         containsAllOptions(tr);
         if (!tr.isOK()) {
-            System.out.println(tr.status);
+            System.out.println(tr);
             throw new RuntimeException("test fails");
         }
     }
 
     static void runTestOptionAll() throws IOException {
         init();
-        TestResult tr = null;
-        tr = doExec(javaCmd, "-XshowSettings:all");
+        TestResult tr = doExec(javaCmd, "-XshowSettings:all");
         containsAllOptions(tr);
     }
 
     static void runTestOptionVM() throws IOException {
-        TestResult tr = null;
-        tr = doExec(javaCmd, "-XshowSettings:vm");
+        TestResult tr = doExec(javaCmd, "-XshowSettings:vm");
         checkContains(tr, VM_SETTINGS);
-        checkNoContains(tr, PROP_SETTINGS);
-        checkNoContains(tr, LOCALE_SETTINGS);
+        checkNotContains(tr, PROP_SETTINGS);
+        checkNotContains(tr, LOCALE_SETTINGS);
     }
 
     static void runTestOptionProperty() throws IOException {
-        TestResult tr = null;
-        tr = doExec(javaCmd, "-XshowSettings:properties");
-        checkNoContains(tr, VM_SETTINGS);
+        TestResult tr = doExec(javaCmd, "-XshowSettings:properties");
+        checkNotContains(tr, VM_SETTINGS);
         checkContains(tr, PROP_SETTINGS);
-        checkNoContains(tr, LOCALE_SETTINGS);
+        checkNotContains(tr, LOCALE_SETTINGS);
     }
 
     static void runTestOptionLocale() throws IOException {
-        TestResult tr = null;
-        tr = doExec(javaCmd, "-XshowSettings:locale");
-        checkNoContains(tr, VM_SETTINGS);
-        checkNoContains(tr, PROP_SETTINGS);
+        TestResult tr = doExec(javaCmd, "-XshowSettings:locale");
+        checkNotContains(tr, VM_SETTINGS);
+        checkNotContains(tr, PROP_SETTINGS);
         checkContains(tr, LOCALE_SETTINGS);
     }
 
     static void runTestBadOptions() throws IOException {
-        TestResult tr = null;
-        tr = doExec(javaCmd, "-XshowSettingsBadOption");
-        checkNoContains(tr, VM_SETTINGS);
-        checkNoContains(tr, PROP_SETTINGS);
-        checkNoContains(tr, LOCALE_SETTINGS);
+        TestResult tr = doExec(javaCmd, "-XshowSettingsBadOption");
+        checkNotContains(tr, VM_SETTINGS);
+        checkNotContains(tr, PROP_SETTINGS);
+        checkNotContains(tr, LOCALE_SETTINGS);
         checkContains(tr, "Unrecognized option: -XshowSettingsBadOption");
     }
 
     static void runTest7123582() throws IOException {
-        TestResult tr = null;
-        tr = doExec(javaCmd, "-XshowSettings", "-version");
+        TestResult tr = doExec(javaCmd, "-XshowSettings", "-version");
         if (!tr.isOK()) {
-            System.out.println(tr.status);
+            System.out.println(tr);
             throw new RuntimeException("test fails");
         }
         containsAllOptions(tr);
     }
 
-    public static void main(String... args) {
-        try {
-            runTestOptionAll();
-            runTestOptionDefault();
-            runTestOptionVM();
-            runTestOptionProperty();
-            runTestOptionLocale();
-            runTestBadOptions();
-            runTest7123582();
-        } catch (IOException ioe) {
-            throw new RuntimeException(ioe);
+    public static void main(String... args) throws IOException {
+        runTestOptionAll();
+        runTestOptionDefault();
+        runTestOptionVM();
+        runTestOptionProperty();
+        runTestOptionLocale();
+        runTestBadOptions();
+        runTest7123582();
+        if (testExitValue != 0) {
+            throw new Error(testExitValue + " tests failed");
         }
     }
 }
--- a/jdk/test/tools/launcher/TestHelper.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/test/tools/launcher/TestHelper.java	Wed Jul 05 21:37:42 2017 +0200
@@ -603,23 +603,23 @@
             return true;
         }
 
-        boolean matches(String stringToMatch) {
+        boolean matches(String regexToMatch) {
             for (String x : testOutput) {
-                if (x.matches(stringToMatch)) {
+                if (x.matches(regexToMatch)) {
                     return true;
                 }
             }
-            appendError("string <" + stringToMatch + "> not found");
+            appendError("regex <" + regexToMatch + "> not matched");
             return false;
         }
 
-        boolean notMatches(String stringToMatch) {
+        boolean notMatches(String regexToMatch) {
             for (String x : testOutput) {
-                if (!x.matches(stringToMatch)) {
+                if (!x.matches(regexToMatch)) {
                     return true;
                 }
             }
-            appendError("string <" + stringToMatch + "> found");
+            appendError("regex <" + regexToMatch + "> matched");
             return false;
         }
     }
--- a/jdk/test/tools/launcher/TestSpecialArgs.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/test/tools/launcher/TestSpecialArgs.java	Wed Jul 05 21:37:42 2017 +0200
@@ -241,7 +241,7 @@
 
     @Test
     void testNMArgumentProcessing() throws FileNotFoundException {
-        TestResult tr = null;
+        TestResult tr;
         // the direct invokers of the VM
         String options[] = {
             "-version", "-fullversion", "-help", "-?", "-X"
--- a/jdk/test/tools/launcher/TooSmallStackSize.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/test/tools/launcher/TooSmallStackSize.java	Wed Jul 05 21:37:42 2017 +0200
@@ -85,11 +85,10 @@
      */
     static String checkStack(String stackSize) {
         String min_stack_allowed;
-        TestResult tr;
 
         if (verbose)
             System.out.println("*** Testing " + stackSize);
-        tr = doExec(javaCmd, "-Xss" + stackSize, "-version");
+        TestResult tr = doExec(javaCmd, "-Xss" + stackSize, "-version");
         if (verbose)
             printTestOutput(tr);
 
@@ -114,11 +113,9 @@
      * Run the JVM with the minimum allowed stack size. This should always succeed.
      */
     static void checkMinStackAllowed(String stackSize) {
-        TestResult tr = null;
-
         if (verbose)
             System.out.println("*** Testing " + stackSize);
-        tr = doExec(javaCmd, "-Xss" + stackSize, "-version");
+        TestResult tr = doExec(javaCmd, "-Xss" + stackSize, "-version");
         if (verbose)
             printTestOutput(tr);
 
--- a/jdk/test/tools/launcher/ToolsOpts.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/test/tools/launcher/ToolsOpts.java	Wed Jul 05 21:37:42 2017 +0200
@@ -149,7 +149,7 @@
      */
     static void runTestOptions() throws IOException {
         init();
-        TestResult tr = null;
+        TestResult tr;
         int jpos = -1;
         for (String arg[] : optionPatterns) {
             jpos = indexOfJoption(arg);
--- a/jdk/test/tools/launcher/VersionCheck.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/test/tools/launcher/VersionCheck.java	Wed Jul 05 21:37:42 2017 +0200
@@ -151,12 +151,11 @@
      * of the -version output as they are inconsistent.
      */
     static boolean testToolVersion() {
-        TestResult tr = null;
         TestHelper.testExitValue = 0;
         for (File f : new File(JAVA_BIN).listFiles(new ToolFilter(BLACKLIST_VERSION))) {
             String x = f.getAbsolutePath();
             System.out.println("Testing (-version): " + x);
-            tr = doExec(x, "-version");
+            TestResult tr = doExec(x, "-version");
             tr.checkPositive();
         }
         return TestHelper.testExitValue == 0;
--- a/jdk/test/tools/launcher/modules/limitmods/LimitModsTest.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/test/tools/launcher/modules/limitmods/LimitModsTest.java	Wed Jul 05 21:37:42 2017 +0200
@@ -103,10 +103,9 @@
     public void testWithAddMods() throws Exception {
         int exitValue;
 
-        // java -limitmods java.base -addmods java.logging,jdk.unsupported -listmods
+        // java -limitmods java.base -addmods java.logging -listmods
         exitValue = executeTestJava("-limitmods", "java.base",
-                                    "-addmods",
-                                    "java.logging,jdk.unsupported",  // TODO: add bug No.
+                                    "-addmods", "java.logging",
                                     "-listmods")
             .outputTo(System.out)
             .errorTo(System.out)
--- a/jdk/test/tools/lib/tests/JImageGenerator.java	Thu Apr 21 12:57:17 2016 -0700
+++ b/jdk/test/tools/lib/tests/JImageGenerator.java	Wed Jul 05 21:37:42 2017 +0200
@@ -553,10 +553,6 @@
         public Result extract() {
             return cmd("extract", dir);
         }
-
-        public Result recreate() {
-            return cmd("recreate", image);
-        }
     }
 
     public static class JLinkTask {
--- a/make/CompileJavaModules.gmk	Thu Apr 21 12:57:17 2016 -0700
+++ b/make/CompileJavaModules.gmk	Wed Jul 05 21:37:42 2017 +0200
@@ -98,7 +98,8 @@
 
 ################################################################################
 
-java.desktop_ADD_JAVAC_FLAGS := -Xdoclint:all/protected,-reference '-Xdoclint/package:java.*,javax.*'
+java.desktop_ADD_JAVAC_FLAGS := -Xdoclint:all/protected,-reference \
+    '-Xdoclint/package:java.*,javax.*' -Xlint:-deprecation
 java.desktop_COPY := .gif .png .wav .txt .xml .css .pf
 java.desktop_CLEAN := iio-plugin.properties cursors.properties
 
--- a/make/InitSupport.gmk	Thu Apr 21 12:57:17 2016 -0700
+++ b/make/InitSupport.gmk	Wed Jul 05 21:37:42 2017 +0200
@@ -331,7 +331,7 @@
   BUILD_LOG := $(OUTPUT_ROOT)/build.log
   BUILD_TRACE_LOG := $(OUTPUT_ROOT)/build-trace-time.log
 
-  BUILD_LOG_PIPE := > >($(TEE) -a $(BUILD_LOG)) 2> >($(TEE) -a $(BUILD_LOG) >&2)
+  BUILD_LOG_PIPE := > >($(TEE) -a $(BUILD_LOG)) 2> >($(TEE) -a $(BUILD_LOG) >&2) && wait
 
   # Sanity check the spec file, so it matches this source code
   define CheckSpecSanity
--- a/make/Jprt.gmk	Thu Apr 21 12:57:17 2016 -0700
+++ b/make/Jprt.gmk	Wed Jul 05 21:37:42 2017 +0200
@@ -108,7 +108,9 @@
 SRC_JRE_MACOSX_BUNDLE_DIR := $(JRE_MACOSX_BUNDLE_DIR)
 
 # Bundle up the images
-bundles: all
+JPRT_TARGET ?= all
+ifeq ($(JPRT_TARGET), all)
+  bundles: $(JPRT_TARGET)
 	@$(call TargetEnter)
 	$(MKDIR) -p $(BUILD_OUTPUT)/bundles
 	$(CD) $(SRC_JDK_IMAGE_DIR) && $(ZIP) -y -q -r \
@@ -128,9 +130,24 @@
 	      $(BUILD_OUTPUT)/bundles/$(SYMBOLS_IMAGE_SUBDIR).zip . ; \
 	fi
 	@$(call TargetExit)
+else
+  # Just fake the bundles
+  bundles: $(JPRT_TARGET)
+	@$(call TargetEnter)
+	$(MKDIR) -p $(BUILD_OUTPUT)/bundles
+	$(CD) $(TOPDIR) &&  $(ZIP) -y -q -r \
+	    $(BUILD_OUTPUT)/bundles/$(JDK_IMAGE_SUBDIR).zip README
+	$(CD) $(TOPDIR) &&  $(ZIP) -y -q -r \
+	    $(BUILD_OUTPUT)/bundles/$(JRE_IMAGE_SUBDIR).zip README
+	$(CD) $(TOPDIR) &&  $(ZIP) -y -q -r \
+	    $(BUILD_OUTPUT)/bundles/$(TEST_IMAGE_SUBDIR).zip README
+	$(CD) $(TOPDIR) &&  $(ZIP) -y -q -r \
+	    $(BUILD_OUTPUT)/bundles/modules.zip README
+	@$(call TargetExit)
+endif
 
 # Copy images to one unified location regardless of platform etc.
-final-images: all
+final-images: $(JPRT_TARGET)
 	@$(call TargetEnter)
 	$(RM) -r $(BUILD_OUTPUT)/final-images
 	$(MKDIR) -p $(BUILD_OUTPUT)/final-images/$(JDK_IMAGE_SUBDIR)
--- a/make/Main.gmk	Thu Apr 21 12:57:17 2016 -0700
+++ b/make/Main.gmk	Wed Jul 05 21:37:42 2017 +0200
@@ -229,10 +229,17 @@
 
 ifeq ($(BUILD_HOTSPOT),true)
   hotspot:
-	+($(CD) $(SRC_ROOT)/make && $(MAKE) $(MAKE_ARGS) -f HotspotWrapper.gmk)
+        ifeq ($(USE_NEW_HOTSPOT_BUILD), true)
+	  +($(CD) $(HOTSPOT_TOPDIR)/makefiles && $(MAKE) $(MAKE_ARGS) -f BuildHotspot.gmk)
+        else
+	  +($(CD) $(SRC_ROOT)/make && $(MAKE) $(MAKE_ARGS) -f HotspotWrapper.gmk)
+        endif
 endif
 
-ALL_TARGETS += hotspot
+hotspot-ide-project:
+	+($(CD) $(HOTSPOT_TOPDIR)/makefiles && $(MAKE) $(MAKE_ARGS) -f ide/CreateVSProject.gmk)
+
+ALL_TARGETS += hotspot hotspot-ide-project
 
 ################################################################################
 # Build demos and samples targets
@@ -484,6 +491,8 @@
 
   $(JAVA_TARGETS): interim-langtools
 
+  hotspot-ide-project: hotspot exploded-image
+
   import-hotspot: hotspot
 
   generate-exported-symbols: java.base-libs jdk.jdwp.agent-libs
--- a/make/common/MakeBase.gmk	Thu Apr 21 12:57:17 2016 -0700
+++ b/make/common/MakeBase.gmk	Wed Jul 05 21:37:42 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
@@ -706,10 +706,10 @@
 ExecuteWithLog = \
   $(call LogCmdlines, Exececuting: [$(strip $2)]) \
   $(call WriteFile, $2, $(strip $1).cmdline) \
-  ( $(strip $2) > >($(TEE) $(strip $1).log) 2> >($(TEE) $(strip $1).log >&2) || \
+  ( ( $(strip $2) > >($(TEE) $(strip $1).log) 2> >($(TEE) $(strip $1).log >&2) || \
       ( exitcode=$(DOLLAR)? && \
       $(CP) $(strip $1).log $(MAKESUPPORT_OUTPUTDIR)/failure-logs/$(subst /,_,$(patsubst $(BUILD_OUTPUT)/%,%,$(strip $1))).log && \
-      exit $(DOLLAR)exitcode ) )
+      exit $(DOLLAR)exitcode ) ) && wait )
 
 ################################################################################
 # Find lib dir for module
@@ -732,6 +732,16 @@
   "$(subst $(SPACE),$(PATH_SEP),$(strip $(subst $(DQUOTE),,$1)))"
 
 ################################################################################
+# Check if a specified hotspot variant is being built, or at least one of a
+# list of variants. Will return 'true' or 'false'.
+# $1 - the variant to test for
+check-jvm-variant = \
+  $(strip \
+    $(if $(filter-out $(VALID_JVM_VARIANTS), $1), \
+      $(error Internal error: Invalid variant tested: $1)) \
+    $(if $(filter $1, $(JVM_VARIANTS)), true, false))
+
+################################################################################
 
 # Hook to include the corresponding custom file, if present.
 $(eval $(call IncludeCustomExtension, , common/MakeBase.gmk))
--- a/make/common/NativeCompilation.gmk	Thu Apr 21 12:57:17 2016 -0700
+++ b/make/common/NativeCompilation.gmk	Wed Jul 05 21:37:42 2017 +0200
@@ -197,14 +197,51 @@
     $1_$2_THIS_FILE = -DTHIS_FILE='"$$(<F)"'
   endif
 
+  ifeq ($$($1_$(notdir $2)_OPTIMIZATION), )
+    $1_$(notdir $2)_OPT_CFLAGS := $$($1_OPT_CFLAGS)
+    $1_$(notdir $2)_OPT_CXXFLAGS := $$($1_OPT_CXXFLAGS)
+  else
+    ifeq (NONE, $$($1_$(notdir $2)_OPTIMIZATION))
+      $1_$(notdir $2)_OPT_CFLAGS := $(C_O_FLAG_NONE)
+      $1_$(notdir $2)_OPT_CXXFLAGS := $(CXX_O_FLAG_NONE)
+    else ifeq (LOW, $$($1_$(notdir $2)_OPTIMIZATION))
+      $1_$(notdir $2)_OPT_CFLAGS := $(C_O_FLAG_NORM)
+      $1_$(notdir $2)_OPT_CXXFLAGS := $(CXX_O_FLAG_NORM)
+    else ifeq (HIGH, $$($1_$(notdir $2)_OPTIMIZATION))
+      $1_$(notdir $2)_OPT_CFLAGS := $(C_O_FLAG_HI)
+      $1_$(notdir $2)_OPT_CXXFLAGS := $(CXX_O_FLAG_HI)
+    else ifeq (HIGHEST, $$($1_$(notdir $2)_OPTIMIZATION))
+      $1_$(notdir $2)_OPT_CFLAGS := $(C_O_FLAG_HIGHEST)
+      $1_$(notdir $2)_OPT_CXXFLAGS := $(CXX_O_FLAG_HIGHEST)
+    else ifeq (HIGHEST_JVM, $$($1_$(notdir $2)_OPTIMIZATION))
+      $1_$(notdir $2)_OPT_CFLAGS := $(C_O_FLAG_HIGHEST_JVM)
+      $1_$(notdir $2)_OPT_CXXFLAGS := $(CXX_O_FLAG_HIGHEST_JVM)
+    else ifeq (SIZE, $$($1_$(notdir $2)_OPTIMIZATION))
+      $1_$(notdir $2)_OPT_CFLAGS := $(C_O_FLAG_SIZE)
+      $1_$(notdir $2)_OPT_CXXFLAGS := $(CXX_O_FLAG_SIZE)
+    else
+      $$(error Unknown value for OPTIMIZATION: $$($1_$(notdir $2)_OPTIMIZATION))
+    endif
+  endif
+
+  ifneq ($$($1_PRECOMPILED_HEADER), )
+    ifeq ($$(filter $$(notdir $2), $$($1_PRECOMPILED_HEADER_EXCLUDE)), )
+      $1_$2_USE_PCH_FLAGS := $$($1_USE_PCH_FLAGS)
+    endif
+  endif
+
   ifneq (,$$(filter %.c,$2))
     # Compile as a C file
-    $1_$2_FLAGS=$(CFLAGS_CCACHE) $4 $$($1_$(notdir $2)_CFLAGS) $$($1_$2_THIS_FILE) -c
+    $1_$2_FLAGS=$(CFLAGS_CCACHE) $$($1_$2_USE_PCH_FLAGS) $4 \
+        $$($1_$(notdir $2)_OPT_CFLAGS) \
+        $$($1_$(notdir $2)_CFLAGS) $$($1_$2_THIS_FILE) -c
     $1_$2_COMP=$5
     $1_$2_DEP_FLAG:=$(C_FLAG_DEPS)
   else ifneq (,$$(filter %.m,$2))
     # Compile as an Objective-C file
-    $1_$2_FLAGS=-x objective-c $(CFLAGS_CCACHE) $4 $$($1_$(notdir $2)_CFLAGS) $$($1_$2_THIS_FILE) -c
+    $1_$2_FLAGS=-x objective-c $(CFLAGS_CCACHE) $$($1_$2_USE_PCH_FLAGS) $4 \
+        $$($1_$(notdir $2)_OPT_CFLAGS) \
+        $$($1_$(notdir $2)_CFLAGS) $$($1_$2_THIS_FILE) -c
     $1_$2_COMP=$5
     $1_$2_DEP_FLAG:=$(C_FLAG_DEPS)
   else ifneq (,$$(filter %.s %.S,$2))
@@ -214,7 +251,9 @@
     $1_$2_DEP_FLAG:=
   else ifneq (,$$(filter %.cpp,$2)$$(filter %.cc,$2)$$(filter %.mm,$2))
     # Compile as a C++ or Objective-C++ file
-    $1_$2_FLAGS=$(CFLAGS_CCACHE) $6 $$($1_$(notdir $2)_CXXFLAGS) $$($1_$2_THIS_FILE) -c
+    $1_$2_FLAGS=$(CFLAGS_CCACHE) $$($1_$2_USE_PCH_FLAGS) $6 \
+        $$($1_$(notdir $2)_OPT_CXXFLAGS) \
+        $$($1_$(notdir $2)_CXXFLAGS) $$($1_$2_THIS_FILE) -c
     $1_$2_COMP=$7
     $1_$2_DEP_FLAG:=$(CXX_FLAG_DEPS)
   else
@@ -245,8 +284,10 @@
       endif
     endif
 
-    ifneq ($$($1_$(notdir $2)_CFLAGS)$$($1_$(notdir $2)_CXXFLAGS), )
-      $1_$2_VARDEPS := $$($1_$(notdir $2)_CFLAGS) $$($1_$(notdir $2)_CXXFLAGS)
+    ifneq ($$(strip $$($1_$(notdir $2)_CFLAGS) $$($1_$(notdir $2)_CXXFLAGS) \
+        $$($1_$(notdir $2)_OPTIMIZATION)), )
+      $1_$2_VARDEPS := $$($1_$(notdir $2)_CFLAGS) $$($1_$(notdir $2)_CXXFLAGS) \
+          $$($1_$(notdir $2)_OPT_CFLAGS) $$($1_$(notdir $2)_OPT_CXXFLAGS)
       $1_$2_VARDEPS_FILE := $$(call DependOnVariable, $1_$2_VARDEPS, \
           $$(patsubst %$(OBJ_SUFFIX),%.vardeps,$$($1_$2_OBJ)))
     endif
@@ -323,7 +364,7 @@
 #       mapfile for the output symbols file
 #   CC the compiler to use, default is $(CC)
 #   LD the linker to use, default is $(LD)
-#   OPTIMIZATION sets optimization level to NONE, LOW, HIGH, HIGHEST
+#   OPTIMIZATION sets optimization level to NONE, LOW, HIGH, HIGHEST, HIGHEST_JVM, SIZE
 #   DISABLED_WARNINGS_<toolchain> Disable the given warnings for the specified toolchain
 #   DISABLED_WARNINGS_C_<toolchain> Disable the given warnings for the specified toolchain
 #       when compiling C code
@@ -331,7 +372,11 @@
 #       toolchain when compiling C++ code
 #   STRIP_SYMBOLS Set to true to strip the final binary if the toolchain allows for it
 #   DEBUG_SYMBOLS Set to false to disable generation of debug symbols
+#   CFLAGS_DEBUG_SYMBOLS Overrides the default cflags for enabling debug symbols
+#   CXXFLAGS_DEBUG_SYMBOLS Overrides the default cxxflags for enabling debug symbols
 #   STRIPFLAGS Optionally change the flags given to the strip command
+#   PRECOMPILED_HEADER Header file to use as precompiled header
+#   PRECOMPILED_HEADER_EXCLUDE List of source files that should not use PCH
 SetupNativeCompilation = $(NamedParamsMacroTemplate)
 define SetupNativeCompilationBody
 
@@ -556,8 +601,10 @@
   endif
 
   ifeq ($(COMPILE_WITH_DEBUG_SYMBOLS), true)
-    $1_EXTRA_CFLAGS += $(CFLAGS_DEBUG_SYMBOLS)
-    $1_EXTRA_CXXFLAGS += $(CXXFLAGS_DEBUG_SYMBOLS)
+    $$(call SetIfEmpty, $1_CFLAGS_DEBUG_SYMBOLS, $(CFLAGS_DEBUG_SYMBOLS))
+    $$(call SetIfEmpty, $1_CXXFLAGS_DEBUG_SYMBOLS, $(CXXFLAGS_DEBUG_SYMBOLS))
+    $1_EXTRA_CFLAGS += $$($1_CFLAGS_DEBUG_SYMBOLS)
+    $1_EXTRA_CXXFLAGS += $$($1_CXXFLAGS_DEBUG_SYMBOLS)
   endif
 
   ifneq (,$$($1_REORDER))
@@ -597,17 +644,23 @@
   endif
 
   ifeq (NONE, $$($1_OPTIMIZATION))
-    $1_EXTRA_CFLAGS += $(C_O_FLAG_NONE)
-    $1_EXTRA_CXXFLAGS += $(CXX_O_FLAG_NONE)
+    $1_OPT_CFLAGS := $(C_O_FLAG_NONE)
+    $1_OPT_CXXFLAGS := $(CXX_O_FLAG_NONE)
   else ifeq (LOW, $$($1_OPTIMIZATION))
-    $1_EXTRA_CFLAGS += $(C_O_FLAG_NORM)
-    $1_EXTRA_CXXFLAGS += $(CXX_O_FLAG_NORM)
+    $1_OPT_CFLAGS := $(C_O_FLAG_NORM)
+    $1_OPT_CXXFLAGS := $(CXX_O_FLAG_NORM)
   else ifeq (HIGH, $$($1_OPTIMIZATION))
-    $1_EXTRA_CFLAGS += $(C_O_FLAG_HI)
-    $1_EXTRA_CXXFLAGS += $(CXX_O_FLAG_HI)
+    $1_OPT_CFLAGS := $(C_O_FLAG_HI)
+    $1_OPT_CXXFLAGS := $(CXX_O_FLAG_HI)
   else ifeq (HIGHEST, $$($1_OPTIMIZATION))
-    $1_EXTRA_CFLAGS += $(C_O_FLAG_HIGHEST)
-    $1_EXTRA_CXXFLAGS += $(CXX_O_FLAG_HIGHEST)
+    $1_OPT_CFLAGS := $(C_O_FLAG_HIGHEST)
+    $1_OPT_CXXFLAGS := $(CXX_O_FLAG_HIGHEST)
+  else ifeq (HIGHEST_JVM, $$($1_OPTIMIZATION))
+    $1_OPT_CFLAGS := $(C_O_FLAG_HIGHEST_JVM)
+    $1_OPT_CXXFLAGS := $(CXX_O_FLAG_HIGHEST_JVM)
+  else ifeq (SIZE, $$($1_OPTIMIZATION))
+    $1_OPT_CFLAGS := $(C_O_FLAG_SIZE)
+    $1_OPT_CXXFLAGS := $(CXX_O_FLAG_SIZE)
   else ifneq (, $$($1_OPTIMIZATION))
     $$(error Unknown value for OPTIMIZATION: $$($1_OPTIMIZATION))
   endif
@@ -618,11 +671,65 @@
   # lines for all object files in this setup. This includes at least all the
   # variables used in the call to add_native_source below.
   $1_COMPILE_VARDEPS := $$($1_CFLAGS) $$($1_EXTRA_CFLAGS) $$($1_SYSROOT_CFLAGS) \
-      $$($1_CXXFLAGS) $$($1_EXTRA_CXXFLAGS) \
+      $$($1_CXXFLAGS) $$($1_EXTRA_CXXFLAGS) $$($1_OPT_CFLAGS) $$($1_OPT_CXXFLAGS) \
       $$($1_CC) $$($1_CXX) $$($1_AS) $$($1_ASFLAGS)
   $1_COMPILE_VARDEPS_FILE := $$(call DependOnVariable, $1_COMPILE_VARDEPS, \
       $$($1_OBJECT_DIR)/$$($1_NOSUFFIX).comp.vardeps)
 
+  ifneq ($$($1_PRECOMPILED_HEADER), )
+    ifeq ($(USE_PRECOMPILED_HEADER), 1)
+      ifeq ($(TOOLCHAIN_TYPE), microsoft)
+        $1_PCH_FILE := $$($1_OBJECT_DIR)/$1.pch
+        $1_GENERATED_PCH_SRC := $$($1_OBJECT_DIR)/$1_pch.cpp
+        $1_GENERATED_PCH_OBJ := $$($1_OBJECT_DIR)/$1_pch.obj
+
+        $$(eval $$(call add_native_source,$1,$$($1_GENERATED_PCH_SRC), \
+            $$($1_OBJECT_DIR),,, \
+            $$($1_CXXFLAGS) $$($1_EXTRA_CXXFLAGS) $$($1_SYSROOT_CFLAGS) \
+                -Fp$$($1_PCH_FILE) -Yc$$(notdir $$($1_PRECOMPILED_HEADER)), \
+            $$($1_CXX),,no_this_file))
+
+        $1_USE_PCH_FLAGS := \
+            -Fp$$($1_PCH_FILE) -Yu$$(notdir $$($1_PRECOMPILED_HEADER))
+
+        $$($1_ALL_OBJS): $$($1_GENERATED_PCH_OBJ)
+
+        # Explicitly add the pch obj file first to ease comparing to old
+        # hotspot build.
+        $1_ALL_OBJS := $$($1_GENERATED_PCH_OBJ) $$($1_ALL_OBJS)
+
+        $$($1_GENERATED_PCH_SRC):
+		$(ECHO) "#include \"$$(notdir $$($1_PRECOMPILED_HEADER))\"" > $$@
+
+      else ifneq ($(findstring $(TOOLCHAIN_TYPE), gcc clang), )
+        ifeq ($(TOOLCHAIN_TYPE), gcc)
+          $1_PCH_FILE := $$($1_OBJECT_DIR)/precompiled/$$(notdir $$($1_PRECOMPILED_HEADER)).gch
+          $1_USE_PCH_FLAGS := -I$$($1_OBJECT_DIR)/precompiled
+        else ifeq ($(TOOLCHAIN_TYPE), clang)
+          $1_PCH_FILE := $$($1_OBJECT_DIR)/precompiled/$$(notdir $$($1_PRECOMPILED_HEADER)).pch
+          $1_USE_PCH_FLAGS := -include-pch $$($1_PCH_FILE)
+        endif
+        $1_PCH_DEP := $$($1_PCH_FILE).d
+        $1_PCH_DEP_TARGETS := $$($1_PCH_FILE).d.targets
+
+        -include $$($1_PCH_DEP)
+        -include $$($1_PCH_DEP_TARGETS)
+
+        $$($1_PCH_FILE): $$($1_PRECOMPILED_HEADER) $$($1_COMPILE_VARDEPS_FILE)
+		$$(call LogInfo, Generating precompiled header)
+		$$(call MakeDir, $$(@D))
+		$$(call ExecuteWithLog, $$@, \
+		    $$($1_CC) $$($1_CFLAGS) $$($1_EXTRA_CFLAGS) $$($1_SYSROOT_CFLAGS) \
+		    $$($1_OPT_CFLAGS) \
+		    -x c++-header -c $(C_FLAG_DEPS) $$($1_PCH_DEP) $$< -o $$@)
+		$(SED) $(DEPENDENCY_TARGET_SED_PATTERN) $$($1_PCH_DEP) > $$($1_PCH_DEP_TARGETS)
+
+        $$($1_ALL_OBJS): $$($1_PCH_FILE)
+
+      endif
+    endif
+  endif
+
   # Now call add_native_source for each source file we are going to compile.
   $$(foreach p,$$($1_SRCS), \
       $$(eval $$(call add_native_source,$1,$$p,$$($1_OBJECT_DIR), \
--- a/make/jprt.properties	Thu Apr 21 12:57:17 2016 -0700
+++ b/make/jprt.properties	Wed Jul 05 21:37:42 2017 +0200
@@ -129,9 +129,15 @@
 jprt.build.flavor.optimizedOpen.target=jprt_bundle
 jprt.build.flavor.slowdebug.target=jprt_bundle
 
-# Use these configure args to define debug level
+# Use these configure args to define debug level or provide specific
+# configuration details not covered by Jib profiles.
 jprt.slowdebug.build.configure.args=
 jprt.fastdebug.build.configure.args=--disable-precompiled-headers
+# Don't disable precompiled headers on windows. It's simply too slow.
+jprt.windows_i586.fastdebug.build.configure.args=
+jprt.windows_x64.fastdebug.build.configure.args=
+jprt.windows_i586.fastdebugOpen.build.configure.args=
+jprt.windows_x64.fastdebugOpen.build.configure.args=
 jprt.product.build.configure.args=
 jprt.optimized.build.configure.args=--with-debug-level=optimized
 jprt.slowdebugOpen.build.configure.args=${jprt.slowdebug.build.configure.args}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jtreg-ext/requires/VMProps.java	Wed Jul 05 21:37:42 2017 +0200
@@ -0,0 +1,136 @@
+/*
+ * 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 requires;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * The Class to be invoked by jtreg prior Test Suite execution to
+ * collect information about VM.
+ * Properties set by this Class will be available in the @requires expressions.
+ */
+public class VMProps implements Callable<Map<String, String>> {
+
+    /**
+     * Collects information about VM properties.
+     * This method will be invoked by jtreg.
+     *
+     * @return Map of property-value pairs.
+     */
+    @Override
+    public Map<String, String> call() {
+        Map<String, String> map = new HashMap<>();
+        map.put("vm.flavor", vmFlavor());
+        map.put("vm.compMode", vmCompMode());
+        map.put("vm.bits", vmBits());
+        dump(map);
+        return map;
+    }
+
+    /**
+     * @return VM type value extracted from the "java.vm.name" property.
+     */
+    protected String vmFlavor() {
+        // E.g. "Java HotSpot(TM) 64-Bit Server VM"
+        String vmName = System.getProperty("java.vm.name");
+        if (vmName == null) {
+            return null;
+        }
+
+        Pattern startP = Pattern.compile(".* (\\S+) VM");
+        Matcher m = startP.matcher(vmName);
+        if (m.matches()) {
+            return m.group(1).toLowerCase();
+        }
+        return null;
+    }
+
+    /**
+     * @return VM compilation mode extracted from the "java.vm.info" property.
+     */
+    protected String vmCompMode() {
+        // E.g. "mixed mode"
+        String vmInfo = System.getProperty("java.vm.info");
+        if (vmInfo == null) {
+            return null;
+        }
+        int k = vmInfo.toLowerCase().indexOf(" mode");
+        if (k < 0) {
+            return null;
+        }
+        vmInfo = vmInfo.substring(0, k);
+        switch (vmInfo) {
+            case "mixed" : return "Xmixed";
+            case "compiled" : return "Xcomp";
+            case "interpreted" : return "Xint";
+            default: return null;
+        }
+    }
+
+    /**
+     * @return VM bitness, the value of the "sun.arch.data.model" property.
+     */
+    protected String vmBits() {
+        return System.getProperty("sun.arch.data.model");
+    }
+
+    /**
+     * Dumps the map to the file if the file name is given as the property.
+     * This functionality could be helpful to know context in the real
+     * execution.
+     *
+     * @param map
+     */
+    protected void dump(Map<String, String> map) {
+        String dumpFileName = System.getProperty("vmprops.dump");
+        if (dumpFileName == null) {
+            return;
+        }
+        List<String> lines = new ArrayList<>();
+        map.forEach((k,v) -> lines.add(k + ":" + v));
+        try {
+             Files.write(Paths.get(dumpFileName), lines);
+        } catch (IOException e) {
+            throw new RuntimeException("Failed to dump properties into '"
+                    + dumpFileName + "'", e);
+        }
+    }
+
+    /**
+     * This method is for the testing purpose only.
+     * @param args
+     */
+    public static void main(String args[]) {
+        Map<String, String> map = new VMProps().call();
+        map.forEach((k,v) -> System.out.println(k + ": '" + v + "'"));
+    }
+}