Merge
authorduke
Wed, 05 Jul 2017 20:51:27 +0200
changeset 32797 84078d1d9013
parent 32796 7117f1bfa7a4 (current diff)
parent 32793 5015aeff2351 (diff)
child 32802 27977e2abd45
Merge
jdk/src/java.base/share/native/libfdlibm/e_hypot.c
jdk/src/java.base/share/native/libfdlibm/w_hypot.c
nashorn/test/script/currently-failing/gettersetter.js
nashorn/test/script/currently-failing/property_delete.js
--- a/.hgtags-top-repo	Sat Sep 26 09:22:24 2015 -0700
+++ b/.hgtags-top-repo	Wed Jul 05 20:51:27 2017 +0200
@@ -325,3 +325,4 @@
 f7c5ae2933c0b8510a420d1713a955e4ffc7ad0b jdk9-b80
 b8afcf91331d78626a583ec1b63164468d6f4181 jdk9-b81
 42b56d1f418523ecb61a49d7493302c80c8009cc jdk9-b82
+ce5c14d97d95084504c32b9320cb33cce4235588 jdk9-b83
--- a/common/autoconf/basics.m4	Sat Sep 26 09:22:24 2015 -0700
+++ b/common/autoconf/basics.m4	Wed Jul 05 20:51:27 2017 +0200
@@ -445,6 +445,15 @@
   # Save the current directory this script was started from
   CURDIR="$PWD"
 
+  # We might need to rewrite ORIGINAL_PATH, if it includes "#", to quote them
+  # for make. We couldn't do this when we retrieved ORIGINAL_PATH, since SED
+  # was not available at that time.
+  REWRITTEN_PATH=`$ECHO "$ORIGINAL_PATH" | $SED -e 's/#/\\\\#/g'`
+  if test "x$REWRITTEN_PATH" != "x$ORIGINAL_PATH"; then
+    ORIGINAL_PATH="$REWRITTEN_PATH"
+    AC_MSG_NOTICE([Rewriting ORIGINAL_PATH to $REWRITTEN_PATH])
+  fi
+
   if test "x$OPENJDK_TARGET_OS" = "xwindows"; then
     PATH_SEP=";"
     BASIC_CHECK_PATHS_WINDOWS
@@ -935,6 +944,7 @@
   BASIC_PATH_PROGS(HG, hg)
   BASIC_PATH_PROGS(STAT, stat)
   BASIC_PATH_PROGS(TIME, time)
+  BASIC_PATH_PROGS(PATCH, [gpatch patch])
   # Check if it's GNU time
   IS_GNU_TIME=`$TIME --version 2>&1 | $GREP 'GNU time'`
   if test "x$IS_GNU_TIME" != x; then
--- a/common/autoconf/compare.sh.in	Sat Sep 26 09:22:24 2015 -0700
+++ b/common/autoconf/compare.sh.in	Wed Jul 05 20:51:27 2017 +0200
@@ -29,47 +29,50 @@
 ##########################################################################################
 # Substitutions from autoconf
 
-LEGACY_BUILD_DIR=@OPENJDK_TARGET_OS@-@OPENJDK_TARGET_CPU_LEGACY@
+export LEGACY_BUILD_DIR=@OPENJDK_TARGET_OS@-@OPENJDK_TARGET_CPU_LEGACY@
 
-OPENJDK_TARGET_OS="@OPENJDK_TARGET_OS@"
-OPENJDK_TARGET_CPU="@OPENJDK_TARGET_CPU@"
+export OPENJDK_TARGET_OS="@OPENJDK_TARGET_OS@"
+export OPENJDK_TARGET_CPU="@OPENJDK_TARGET_CPU@"
 
-AWK="@AWK@"
-CAT="@CAT@"
-CMP="@CMP@"
-CP="@CP@"
-CUT="@CUT@"
-DIFF="@DIFF@"
-DUMPBIN="@FIXPATH@ @DUMPBIN@"
-EXPR="@EXPR@"
-FILE="@FILE@"
-FIND="@FIND@"
-GREP="@GREP@"
-JAVAP="@FIXPATH@ @BOOT_JDK@/bin/javap @JAVA_TOOL_FLAGS_SMALL@"
-JIMAGE="@FIXPATH@ @BUILD_OUTPUT@/jdk/bin/jimage"
-LDD="@LDD@"
-LN="@LN@"
-MKDIR="@MKDIR@"
-NAWK="@NAWK@"
-NM="@GNM@"
-OBJDUMP="@OBJDUMP@"
-OTOOL="@OTOOL@"
-PRINTF="@PRINTF@"
-READELF="@READELF@"
-RM="@RM@"
-SED="@SED@"
-SORT="@SORT@"
-STAT="@STAT@"
-STRIP="@POST_STRIP_CMD@"
-TEE="@TEE@"
-UNIQ="@UNIQ@"
-UNPACK200="@FIXPATH@ @BOOT_JDK@/bin/unpack200"
-UNZIP="@UNZIP@"
+export AWK="@AWK@"
+export BASH="@BASH@"
+export CAT="@CAT@"
+export CMP="@CMP@"
+export CP="@CP@"
+export CUT="@CUT@"
+export DIFF="@DIFF@"
+export DUMPBIN="@FIXPATH@ @DUMPBIN@"
+export EXPR="@EXPR@"
+export FILE="@FILE@"
+export FIND="@FIND@"
+export GREP="@GREP@"
+export JAVAP="@FIXPATH@ @BOOT_JDK@/bin/javap @JAVA_TOOL_FLAGS_SMALL@"
+export JIMAGE="@FIXPATH@ @BUILD_OUTPUT@/jdk/bin/jimage"
+export LDD="@LDD@"
+export LN="@LN@"
+export MKDIR="@MKDIR@"
+export MV="@MV@"
+export NAWK="@NAWK@"
+export NM="@GNM@"
+export OBJDUMP="@OBJDUMP@"
+export OTOOL="@OTOOL@"
+export PRINTF="@PRINTF@"
+export READELF="@READELF@"
+export RM="@RM@"
+export SED="@SED@"
+export SORT="@SORT@"
+export STAT="@STAT@"
+export STRIP="@POST_STRIP_CMD@"
+export TEE="@TEE@"
+export UNIQ="@UNIQ@"
+export UNPACK200="@FIXPATH@ @BOOT_JDK@/bin/unpack200"
+export UNZIP="@UNZIP@"
 
-SRC_ROOT="@TOPDIR@"
+export SRC_ROOT="@TOPDIR@"
+export OUTPUT_ROOT="@OUTPUT_ROOT@"
 
 if [ "$OPENJDK_TARGET_OS" = "windows" ]; then
-  PATH="@VS_PATH@"
+  export PATH="@VS_PATH@"
 fi
 
 # Now locate the main script and run it.
@@ -79,4 +82,8 @@
   exit 1
 fi
 
-. "$REAL_COMPARE_SCRIPT" "$@"
+# Rotate logs
+$RM $OUTPUT_ROOT/compare.log.old 2> /dev/null
+$MV $OUTPUT_ROOT/compare.log $OUTPUT_ROOT/compare.log.old 2> /dev/null
+
+$BASH $SRC_ROOT/common/bin/logger.sh $OUTPUT_ROOT/compare.log $BASH "$REAL_COMPARE_SCRIPT" "$@"
--- a/common/autoconf/generated-configure.sh	Sat Sep 26 09:22:24 2015 -0700
+++ b/common/autoconf/generated-configure.sh	Wed Jul 05 20:51:27 2017 +0200
@@ -859,6 +859,7 @@
 XATTR
 DSYMUTIL
 IS_GNU_TIME
+PATCH
 TIME
 STAT
 HG
@@ -1174,6 +1175,7 @@
 HG
 STAT
 TIME
+PATCH
 DSYMUTIL
 XATTR
 CODESIGN
@@ -2053,6 +2055,7 @@
   HG          Override default value for HG
   STAT        Override default value for STAT
   TIME        Override default value for TIME
+  PATCH       Override default value for PATCH
   DSYMUTIL    Override default value for DSYMUTIL
   XATTR       Override default value for XATTR
   CODESIGN    Override default value for CODESIGN
@@ -4359,7 +4362,7 @@
 #CUSTOM_AUTOCONF_INCLUDE
 
 # Do not change or remove the following line, it is needed for consistency checks:
-DATE_WHEN_GENERATED=1441958217
+DATE_WHEN_GENERATED=1442820958
 
 ###############################################################################
 #
@@ -13841,6 +13844,16 @@
   # Save the current directory this script was started from
   CURDIR="$PWD"
 
+  # We might need to rewrite ORIGINAL_PATH, if it includes "#", to quote them
+  # for make. We couldn't do this when we retrieved ORIGINAL_PATH, since SED
+  # was not available at that time.
+  REWRITTEN_PATH=`$ECHO "$ORIGINAL_PATH" | $SED -e 's/#/\\\\#/g'`
+  if test "x$REWRITTEN_PATH" != "x$ORIGINAL_PATH"; then
+    ORIGINAL_PATH="$REWRITTEN_PATH"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting ORIGINAL_PATH to $REWRITTEN_PATH" >&5
+$as_echo "$as_me: Rewriting ORIGINAL_PATH to $REWRITTEN_PATH" >&6;}
+  fi
+
   if test "x$OPENJDK_TARGET_OS" = "xwindows"; then
     PATH_SEP=";"
 
@@ -18865,6 +18878,192 @@
   fi
 
 
+
+
+  # Publish this variable in the help.
+
+
+  if test "x$PATCH" = x; then
+    # The variable is not set by user, try to locate tool using the code snippet
+    for ac_prog in gpatch patch
+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_PATCH+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $PATCH in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_PATCH="$PATCH" # 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_PATCH="$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
+PATCH=$ac_cv_path_PATCH
+if test -n "$PATCH"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PATCH" >&5
+$as_echo "$PATCH" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$PATCH" && break
+done
+
+  else
+    # The variable is set, but is it from the command line or the environment?
+
+    # Try to remove the string !PATCH! from our list.
+    try_remove_var=${CONFIGURE_OVERRIDDEN_VARIABLES//!PATCH!/}
+    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 "xPATCH" != xBASH; then
+        { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Ignoring value of PATCH from the environment. Use command line variables instead." >&5
+$as_echo "$as_me: WARNING: Ignoring value of PATCH from the environment. Use command line variables instead." >&2;}
+      fi
+      # Try to locate tool using the code snippet
+      for ac_prog in gpatch patch
+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_PATCH+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $PATCH in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_PATCH="$PATCH" # 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_PATCH="$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
+PATCH=$ac_cv_path_PATCH
+if test -n "$PATCH"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PATCH" >&5
+$as_echo "$PATCH" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$PATCH" && 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 the provided tool contains a complete path.
+      tool_specified="$PATCH"
+      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 PATCH=$tool_basename" >&5
+$as_echo "$as_me: Will search for user supplied tool PATCH=$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_PATCH+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $PATCH in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_PATCH="$PATCH" # 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_PATCH="$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
+PATCH=$ac_cv_path_PATCH
+if test -n "$PATCH"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PATCH" >&5
+$as_echo "$PATCH" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+        if test "x$PATCH" = 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 PATCH=$tool_specified" >&5
+$as_echo "$as_me: Will use user supplied tool PATCH=$tool_specified" >&6;}
+        { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PATCH" >&5
+$as_echo_n "checking for PATCH... " >&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 PATCH=$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
+
+
   # Check if it's GNU time
   IS_GNU_TIME=`$TIME --version 2>&1 | $GREP 'GNU time'`
   if test "x$IS_GNU_TIME" != x; then
--- a/common/autoconf/spec.gmk.in	Sat Sep 26 09:22:24 2015 -0700
+++ b/common/autoconf/spec.gmk.in	Wed Jul 05 20:51:27 2017 +0200
@@ -36,6 +36,11 @@
 # A self-referential reference to this file.
 SPEC:=@SPEC@
 
+# SPACE is defined in MakeBase.gmk, but it is also used in := rules here for some
+# toolchains, and is needed if MakeBase.gmk is not included before this file.
+X:=
+SPACE:=$(X) $(X)
+
 # What make to use for main processing, after bootstrapping top-level Makefile.
 MAKE := @MAKE@
 
@@ -495,6 +500,7 @@
 MKDIR:=@MKDIR@
 MV:=@MV@
 NAWK:=@NAWK@
+PATCH:=@PATCH@
 PRINTF:=@PRINTF@
 PWD:=@THEPWDCMD@
 RM:=@RM@
--- a/common/bin/compare.sh	Sat Sep 26 09:22:24 2015 -0700
+++ b/common/bin/compare.sh	Wed Jul 05 20:51:27 2017 +0200
@@ -88,23 +88,19 @@
         TMP=$(LC_ALL=C $DIFF $OTHER_FILE $THIS_FILE | \
             $GREP '^[<>]' | \
             $SED -e '/[<>] \* from.*\.idl/d' \
-                 -e '/[<>] \*.*[0-9]\{4\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}-b[0-9]\{2\}.*/d' \
+                 -e '/[<>] .*[0-9]\{4\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}-b[0-9]\{2\}.*/d' \
                  -e '/[<>] \*.*[0-9]\{4\} [0-9][0-9]*:[0-9]\{2\}:[0-9]\{2\}.*/d' \
                  -e '/\/\/ Generated from input file.*/d' \
                  -e '/\/\/ This file was generated AUTOMATICALLY from a template file.*/d' \
                  -e '/\/\/ java GenerateCharacter.*/d')
     fi
     # Ignore date strings in class files.
-    # On Macosx the system sources for generated java classes produce different output on
-    # consequtive invocations seemingly randomly.
-    # For example a method parameter randomly named "thePoint" or "aPoint". Ignore this.
     # Anonymous lambda classes get randomly assigned counters in their names.
     if test "x$SUFFIX" = "xclass"; then
         # To improve performance when large diffs are found, do a rough filtering of classes
         # elibeble for these exceptions
         if $GREP -R -e '[0-9]\{4\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}-b[0-9]\{2\}' \
                 -e '[0-9]\{2\}/[0-9]\{2\}/[0-9]\{4\}' \
-                -e thePoint -e aPoint -e setItemsPtr \
                 -e 'lambda\$[a-zA-Z0-9]*\$[0-9]' ${THIS_FILE} > /dev/null; then
             $JAVAP -c -constants -l -p "${OTHER_FILE}" >  ${OTHER_FILE}.javap
             $JAVAP -c -constants -l -p "${THIS_FILE}" > ${THIS_FILE}.javap
@@ -112,9 +108,6 @@
                 $GREP '^[<>]' | \
                 $SED -e '/[<>].*[0-9]\{4\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}-b[0-9]\{2\}.*/d' \
                      -e '/[0-9]\{2\}\/[0-9]\{2\}\/[0-9]\{4\}/d' \
-                     -e '/[<>].*Point   Lcom\/apple\/jobjc\/foundation\/NSPoint;/d' \
-                     -e '/[<>].*public com\.apple\.jobjc\.Pointer<com\.apple\.jobjc\..*itemsPtr();/d' \
-                     -e '/[<>].*public void setItemsPtr(com\.apple\.jobjc\.Pointer<com\.apple\.jobjc\..*);/d' \
                      -e '/[<>].*lambda\$[a-zA-Z0-9]*\$[0-9]*/d')
         fi
     fi
@@ -313,7 +306,7 @@
         ! -name "jspawnhelper" \
         | $GREP -v "./bin/"  | $SORT | $FILTER)
 
-    echo General files...
+    echo Other files with binary differences...
     for f in $GENERAL_FILES
     do
         if [ -e $OTHER_DIR/$f ]; then
@@ -590,7 +583,7 @@
     ORIG_THIS_FILE="$THIS_FILE"
     ORIG_OTHER_FILE="$OTHER_FILE"
 
-    if [[ "$STRIP_BEFORE_COMPARE" = *"$BIN_FILE"* ]]; then
+    if [ "$STRIP_ALL" = "true" ] || [[ "$STRIP_BEFORE_COMPARE" = *"$BIN_FILE"* ]]; then
         THIS_STRIPPED_FILE=$FILE_WORK_DIR/this/$NAME
         OTHER_STRIPPED_FILE=$FILE_WORK_DIR/other/$NAME
         $MKDIR -p $FILE_WORK_DIR/this $FILE_WORK_DIR/other
@@ -722,7 +715,7 @@
         fi
     fi
 
-    if [[ "$SORT_SYMBOLS" = *"$BIN_FILE"* ]]; then
+    if [ "$SORT_ALL_SYMBOLS" = "true" ] || [[ "$SORT_SYMBOLS" = *"$BIN_FILE"* ]]; then
         SYM_SORT_CMD="sort"
     else
         SYM_SORT_CMD="cat"
@@ -810,31 +803,34 @@
         if [ -z "$FULLDUMP_DIFF_FILTER" ]; then
             FULLDUMP_DIFF_FILTER="$CAT"
         fi
-        $FULLDUMP_CMD $OTHER_FILE | eval "$FULLDUMP_DIFF_FILTER" > $WORK_FILE_BASE.fulldump.other 2>&1
-        $FULLDUMP_CMD $THIS_FILE  | eval "$FULLDUMP_DIFF_FILTER" > $WORK_FILE_BASE.fulldump.this  2>&1
+        $FULLDUMP_CMD $OTHER_FILE | eval "$FULLDUMP_DIFF_FILTER" \
+            > $WORK_FILE_BASE.fulldump.other 2>&1
+        $FULLDUMP_CMD $THIS_FILE  | eval "$FULLDUMP_DIFF_FILTER" \
+            > $WORK_FILE_BASE.fulldump.this  2>&1
 
-        LC_ALL=C $DIFF $WORK_FILE_BASE.fulldump.other $WORK_FILE_BASE.fulldump.this > $WORK_FILE_BASE.fulldump.diff
+        LC_ALL=C $DIFF $WORK_FILE_BASE.fulldump.other $WORK_FILE_BASE.fulldump.this \
+            > $WORK_FILE_BASE.fulldump.diff
 
         if [ -s $WORK_FILE_BASE.fulldump.diff ]; then
-            ELF_DIFF_SIZE=$(ls -n $WORK_FILE_BASE.fulldump.diff | awk '{print $5}')
-            ELF_MSG=$($PRINTF "%8d" $ELF_DIFF_SIZE)
-            if [[ "$ACCEPTED_ELF_DIFF" != *"$BIN_FILE"* ]]; then
-                DIFF_ELF=true
-                if [[ "$KNOWN_ELF_DIFF" != *"$BIN_FILE"* ]]; then
-                    ELF_MSG="*$ELF_MSG*"
+            FULLDUMP_DIFF_SIZE=$(ls -n $WORK_FILE_BASE.fulldump.diff | awk '{print $5}')
+            FULLDUMP_MSG=$($PRINTF "%8d" $FULLDUMP_DIFF_SIZE)
+            if [[ "$ACCEPTED_FULLDUMP_DIFF" != *"$BIN_FILE"* ]]; then
+                DIFF_FULLDUMP=true
+                if [[ "$KNOWN_FULLDUMP_DIFF" != *"$BIN_FILE"* ]]; then
+                    FULLDUMP_MSG="*$FULLDUMP_MSG*"
                     REGRESSIONS=true
                 else
-                    ELF_MSG=" $ELF_MSG "
+                    FULLDUMP_MSG=" $FULLDUMP_MSG "
                 fi
             else
-                ELF_MSG="($ELF_MSG)"
-                DIFF_ELF=
+                FULLDUMP_MSG="($FULLDUMP_MSG)"
+                DIFF_FULLDUMP=
             fi
         else
-            ELF_MSG="          "
-            DIFF_ELF=
-            if [[ "$KNOWN_DEP_DIFF $ACCEPTED_DEP_DIFF" = *"$BIN_FILE"* ]]; then
-                ELF_MSG="    !    "
+            FULLDUMP_MSG="          "
+            DIFF_FULLDUMP=
+            if [[ "$KNOWN_FULLDUMP_DIFF $ACCEPTED_FULLDUMP_DIFF" = *"$BIN_FILE"* ]]; then
+                FULLDUMP_MSG="    !    "
             fi
         fi
     fi
@@ -845,7 +841,7 @@
         # To get a raw diff with the complete disassembly, set
         # DIS_DIFF_FILTER="$CAT"
         if [ -z "$DIS_DIFF_FILTER" ]; then
-            DIS_DIFF_FILTER="$GREP -v ' # .* <.*>$'"
+            DIS_DIFF_FILTER="$GREP -v ' # .* <.*>$' | $SED -r -e 's/(\b|x)([0-9a-fA-F]+)(\b|:|>)/X/g'"
         fi
         $DIS_CMD $OTHER_FILE | $GREP -v $NAME | eval "$DIS_DIFF_FILTER" > $WORK_FILE_BASE.dis.other 2>&1
         $DIS_CMD $THIS_FILE  | $GREP -v $NAME | eval "$DIS_DIFF_FILTER" > $WORK_FILE_BASE.dis.this  2>&1
@@ -877,12 +873,12 @@
     fi
 
 
-    if [ -n "$DIFF_BIN$DIFF_SIZE$DIFF_SYM$DIFF_DEP$DIFF_ELF$DIFF_DIS" ] || [ -n "$VERBOSE" ]; then
+    if [ -n "$DIFF_BIN$DIFF_SIZE$DIFF_SYM$DIFF_DEP$DIFF_FULLDUMP$DIFF_DIS" ] || [ -n "$VERBOSE" ]; then
         if [ -n "$BIN_MSG" ]; then echo -n "$BIN_MSG:"; fi
         if [ -n "$SIZE_MSG" ]; then echo -n "$SIZE_MSG:"; fi
         if [ -n "$SYM_MSG" ]; then echo -n "$SYM_MSG:"; fi
         if [ -n "$DEP_MSG" ]; then echo -n "$DEP_MSG:"; fi
-        if [ -n "$ELF_MSG" ]; then echo -n "$ELF_MSG:"; fi
+        if [ -n "$FULLDUMP_MSG" ]; then echo -n "$FULLDUMP_MSG:"; fi
         if [ -n "$DIS_MSG" ]; then echo -n "$DIS_MSG:"; fi
         echo " $BIN_FILE"
         if [ "$SHOW_DIFFS" = "true" ]; then
@@ -1015,6 +1011,9 @@
     echo "-vv                 More verbose output, shows diff output of all comparisons"
     echo "-o [OTHER]          Compare with build in other directory. Will default to the old build directory"
     echo ""
+    echo "--sort-symbols      Sort all symbols before comparing"
+    echo "--strip             Strip all binaries before comparing"
+    echo ""
     echo "[FILTER]            List filenames in the image to compare, works for jars, zips, libs and execs"
     echo "Example:"
     echo "bash ./common/bin/compareimages.sh CodePointIM.jar"
@@ -1107,6 +1106,12 @@
             shift
             shift
             ;;
+        --sort-symbols)
+            SORT_ALL_SYMBOLS=true
+            ;;
+        --strip)
+            STRIP_ALL=true
+            ;;
         *)
             CMP_NAMES=false
             CMP_PERMS=false
@@ -1223,7 +1228,7 @@
             OTHER_JDK_BUNDLE="$OTHER/images/jdk-bundle"
             OTHER_JRE_BUNDLE="$OTHER/images/jre-bundle"
 	fi
-        echo "Also comparing macosx bundles"
+        echo "Also comparing jdk macosx bundles"
         echo "  $THIS_JDK_BUNDLE"
         echo "  $OTHER_JDK_BUNDLE"
     fi
--- a/corba/.hgtags	Sat Sep 26 09:22:24 2015 -0700
+++ b/corba/.hgtags	Wed Jul 05 20:51:27 2017 +0200
@@ -325,3 +325,4 @@
 821a0373ef2d1642a9824facb938b901ad010413 jdk9-b80
 45c35b7f5b40d5af0085e4a7b3a4d6e3e0347c35 jdk9-b81
 c20d8ebddaa6fb09cc81d3edf3d1d05f4232700a jdk9-b82
+ca8a1719588424f6e04e943790c7fcb7cb0b8c8f jdk9-b83
--- a/hotspot/.hgtags	Sat Sep 26 09:22:24 2015 -0700
+++ b/hotspot/.hgtags	Wed Jul 05 20:51:27 2017 +0200
@@ -485,3 +485,4 @@
 8e8377739c06b99b9011c003c77e0bef84c91e09 jdk9-b80
 4142c190cd5ca4fb70ec367b4f97ef936272d8ef jdk9-b81
 1c453a12be3036d482abef1dd470f8aff536b6b9 jdk9-b82
+3ed0df2c553a80e0e26b91a6ce08806ea17a066a jdk9-b83
--- a/hotspot/src/cpu/aarch64/vm/aarch64.ad	Sat Sep 26 09:22:24 2015 -0700
+++ b/hotspot/src/cpu/aarch64/vm/aarch64.ad	Wed Jul 05 20:51:27 2017 +0200
@@ -3803,81 +3803,37 @@
 
   enc_class aarch64_enc_cmpxchg(memory mem, iRegLNoSp oldval, iRegLNoSp newval) %{
     MacroAssembler _masm(&cbuf);
-    Register old_reg = as_Register($oldval$$reg);
-    Register new_reg = as_Register($newval$$reg);
-    Register base = as_Register($mem$$base);
-    Register addr_reg;
-    int index = $mem$$index;
-    int scale = $mem$$scale;
-    int disp = $mem$$disp;
-    if (index == -1) {
-       if (disp != 0) {
-        __ lea(rscratch2, Address(base, disp));
-        addr_reg = rscratch2;
-      } else {
-        // TODO
-        // should we ever get anything other than this case?
-        addr_reg = base;
-      }
-    } else {
-      Register index_reg = as_Register(index);
-      if (disp == 0) {
-        __ lea(rscratch2, Address(base, index_reg, Address::lsl(scale)));
-        addr_reg = rscratch2;
-      } else {
-        __ lea(rscratch2, Address(base, disp));
-        __ lea(rscratch2, Address(rscratch2, index_reg, Address::lsl(scale)));
-        addr_reg = rscratch2;
-      }
-    }
-    Label retry_load, done;
-    __ bind(retry_load);
-    __ ldxr(rscratch1, addr_reg);
-    __ cmp(rscratch1, old_reg);
-    __ br(Assembler::NE, done);
-    __ stlxr(rscratch1, new_reg, addr_reg);
-    __ cbnzw(rscratch1, retry_load);
-    __ bind(done);
+    guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
+    __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register,
+               &Assembler::ldxr, &MacroAssembler::cmp, &Assembler::stlxr);
   %}
 
   enc_class aarch64_enc_cmpxchgw(memory mem, iRegINoSp oldval, iRegINoSp newval) %{
     MacroAssembler _masm(&cbuf);
-    Register old_reg = as_Register($oldval$$reg);
-    Register new_reg = as_Register($newval$$reg);
-    Register base = as_Register($mem$$base);
-    Register addr_reg;
-    int index = $mem$$index;
-    int scale = $mem$$scale;
-    int disp = $mem$$disp;
-    if (index == -1) {
-       if (disp != 0) {
-        __ lea(rscratch2, Address(base, disp));
-        addr_reg = rscratch2;
-      } else {
-        // TODO
-        // should we ever get anything other than this case?
-        addr_reg = base;
-      }
-    } else {
-      Register index_reg = as_Register(index);
-      if (disp == 0) {
-        __ lea(rscratch2, Address(base, index_reg, Address::lsl(scale)));
-        addr_reg = rscratch2;
-      } else {
-        __ lea(rscratch2, Address(base, disp));
-        __ lea(rscratch2, Address(rscratch2, index_reg, Address::lsl(scale)));
-        addr_reg = rscratch2;
-      }
-    }
-    Label retry_load, done;
-    __ bind(retry_load);
-    __ ldxrw(rscratch1, addr_reg);
-    __ cmpw(rscratch1, old_reg);
-    __ br(Assembler::NE, done);
-    __ stlxrw(rscratch1, new_reg, addr_reg);
-    __ cbnzw(rscratch1, retry_load);
-    __ bind(done);
-  %}
+    guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
+    __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register,
+               &Assembler::ldxrw, &MacroAssembler::cmpw, &Assembler::stlxrw);
+  %}
+
+
+  // The only difference between aarch64_enc_cmpxchg and
+  // aarch64_enc_cmpxchg_acq is that we use load-acquire in the
+  // CompareAndSwap sequence to serve as a barrier on acquiring a
+  // lock.
+  enc_class aarch64_enc_cmpxchg_acq(memory mem, iRegLNoSp oldval, iRegLNoSp newval) %{
+    MacroAssembler _masm(&cbuf);
+    guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
+    __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register,
+               &Assembler::ldaxr, &MacroAssembler::cmp, &Assembler::stlxr);
+  %}
+
+  enc_class aarch64_enc_cmpxchgw_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{
+    MacroAssembler _masm(&cbuf);
+    guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
+    __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register,
+               &Assembler::ldaxrw, &MacroAssembler::cmpw, &Assembler::stlxrw);
+  %}
+
 
   // auxiliary used for CompareAndSwapX to set result register
   enc_class aarch64_enc_cset_eq(iRegINoSp res) %{
@@ -4398,13 +4354,10 @@
 
     // Compare object markOop with mark and if equal exchange scratch1
     // with object markOop.
-    // Note that this is simply a CAS: it does not generate any
-    // barriers.  These are separately generated by
-    // membar_acquire_lock().
     {
       Label retry_load;
       __ bind(retry_load);
-      __ ldxr(tmp, oop);
+      __ ldaxr(tmp, oop);
       __ cmp(tmp, disp_hdr);
       __ br(Assembler::NE, cas_failed);
       // use stlxr to ensure update is immediately visible
@@ -4454,7 +4407,7 @@
       {
         Label retry_load, fail;
         __ bind(retry_load);
-        __ ldxr(rscratch1, tmp);
+        __ ldaxr(rscratch1, tmp);
         __ cmp(disp_hdr, rscratch1);
         __ br(Assembler::NE, fail);
         // use stlxr to ensure update is immediately visible
@@ -8017,10 +7970,10 @@
   match(MemBarAcquireLock);
   ins_cost(VOLATILE_REF_COST);
 
-  format %{ "membar_acquire_lock" %}
-
-  ins_encode %{
-    __ membar(Assembler::LoadLoad|Assembler::LoadStore);
+  format %{ "membar_acquire_lock (elided)" %}
+
+  ins_encode %{
+    __ block_comment("membar_acquire_lock (elided)");
   %}
 
   ins_pipe(pipe_serial);
@@ -8080,10 +8033,10 @@
   match(MemBarReleaseLock);
   ins_cost(VOLATILE_REF_COST);
 
-  format %{ "membar_release_lock" %}
-
-  ins_encode %{
-    __ membar(Assembler::LoadStore|Assembler::StoreStore);
+  format %{ "membar_release_lock (elided)" %}
+
+  ins_encode %{
+    __ block_comment("membar_release_lock (elided)");
   %}
 
   ins_pipe(pipe_serial);
@@ -8369,7 +8322,11 @@
   ins_pipe(pipe_serial);
 %}
 
-// this has to be implemented as a CAS
+
+// storeLConditional is used by PhaseMacroExpand::expand_lock_node
+// when attempting to rebias a lock towards the current thread.  We
+// must use the acquire form of cmpxchg in order to guarantee acquire
+// semantics in this case.
 instruct storeLConditional(indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr)
 %{
   match(Set cr (StoreLConditional mem (Binary oldval newval)));
@@ -8381,12 +8338,14 @@
     "cmpw rscratch1, zr\t# EQ on successful write"
   %}
 
-  ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval));
+  ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval));
 
   ins_pipe(pipe_slow);
 %}
 
-// this has to be implemented as a CAS
+// storeIConditional also has acquire semantics, for no better reason
+// than matching storeLConditional.  At the time of writing this
+// comment storeIConditional was not used anywhere by AArch64.
 instruct storeIConditional(indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr)
 %{
   match(Set cr (StoreIConditional mem (Binary oldval newval)));
@@ -8398,7 +8357,7 @@
     "cmpw rscratch1, zr\t# EQ on successful write"
   %}
 
-  ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval));
+  ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval));
 
   ins_pipe(pipe_slow);
 %}
--- a/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp	Sat Sep 26 09:22:24 2015 -0700
+++ b/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp	Wed Jul 05 20:51:27 2017 +0200
@@ -917,6 +917,8 @@
 
   void cmpptr(Register src1, Address src2);
 
+  // Various forms of CAS
+
   void cmpxchgptr(Register oldv, Register newv, Register addr, Register tmp,
                   Label &suceed, Label *fail);
 
@@ -938,6 +940,23 @@
     str(rscratch2, adr);
   }
 
+  // A generic CAS; success or failure is in the EQ flag.
+  template <typename T1, typename T2>
+  void cmpxchg(Register addr, Register expected, Register new_val,
+               T1 load_insn,
+               void (MacroAssembler::*cmp_insn)(Register, Register),
+               T2 store_insn,
+               Register tmp = rscratch1) {
+    Label retry_load, done;
+    bind(retry_load);
+    (this->*load_insn)(tmp, addr);
+    (this->*cmp_insn)(tmp, expected);
+    br(Assembler::NE, done);
+    (this->*store_insn)(tmp, new_val, addr);
+    cbnzw(tmp, retry_load);
+    bind(done);
+  }
+
   // Calls
 
   address trampoline_call(Address entry, CodeBuffer *cbuf = NULL);
--- a/hotspot/src/cpu/x86/vm/assembler_x86.cpp	Sat Sep 26 09:22:24 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/assembler_x86.cpp	Wed Jul 05 20:51:27 2017 +0200
@@ -394,25 +394,25 @@
   int mod_idx = 0;
   // We will test if the displacement fits the compressed format and if so
   // apply the compression to the displacment iff the result is8bit.
-  if (VM_Version::supports_evex() && is_evex_instruction) {
-    switch (tuple_type) {
+  if (VM_Version::supports_evex() && _is_evex_instruction) {
+    switch (_tuple_type) {
     case EVEX_FV:
-      if ((evex_encoding & VEX_W) == VEX_W) {
-        mod_idx += 2 + ((evex_encoding & EVEX_Rb) == EVEX_Rb) ? 1 : 0;
+      if ((_evex_encoding & VEX_W) == VEX_W) {
+        mod_idx += 2 + ((_evex_encoding & EVEX_Rb) == EVEX_Rb) ? 1 : 0;
       } else {
-        mod_idx = ((evex_encoding & EVEX_Rb) == EVEX_Rb) ? 1 : 0;
+        mod_idx = ((_evex_encoding & EVEX_Rb) == EVEX_Rb) ? 1 : 0;
       }
       break;
 
     case EVEX_HV:
-      mod_idx = ((evex_encoding & EVEX_Rb) == EVEX_Rb) ? 1 : 0;
+      mod_idx = ((_evex_encoding & EVEX_Rb) == EVEX_Rb) ? 1 : 0;
       break;
 
     case EVEX_FVM:
       break;
 
     case EVEX_T1S:
-      switch (input_size_in_bits) {
+      switch (_input_size_in_bits) {
       case EVEX_8bit:
         break;
 
@@ -433,7 +433,7 @@
     case EVEX_T1F:
     case EVEX_T2:
     case EVEX_T4:
-      mod_idx = (input_size_in_bits == EVEX_64bit) ? 1 : 0;
+      mod_idx = (_input_size_in_bits == EVEX_64bit) ? 1 : 0;
       break;
 
     case EVEX_T8:
@@ -459,8 +459,8 @@
       break;
     }
 
-    if (avx_vector_len >= AVX_128bit && avx_vector_len <= AVX_512bit) {
-      int disp_factor = tuple_table[tuple_type + mod_idx][avx_vector_len];
+    if (_avx_vector_len >= AVX_128bit && _avx_vector_len <= AVX_512bit) {
+      int disp_factor = tuple_table[_tuple_type + mod_idx][_avx_vector_len];
       if ((disp % disp_factor) == 0) {
         int new_disp = disp / disp_factor;
         if (is8bit(new_disp)) {
@@ -591,7 +591,7 @@
       emit_data(disp, rspec, disp32_operand);
     }
   }
-  is_evex_instruction = false;
+  _is_evex_instruction = false;
 }
 
 void Assembler::emit_operand(XMMRegister reg, Register base, Register index,
@@ -1229,8 +1229,8 @@
 void Assembler::addsd(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_T1S;
-    input_size_in_bits = EVEX_64bit;
+    _tuple_type = EVEX_T1S;
+    _input_size_in_bits = EVEX_64bit;
     emit_simd_arith_q(0x58, dst, src, VEX_SIMD_F2);
   } else {
     emit_simd_arith(0x58, dst, src, VEX_SIMD_F2);
@@ -1245,8 +1245,8 @@
 void Assembler::addss(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_T1S;
-    input_size_in_bits = EVEX_32bit;
+    _tuple_type = EVEX_T1S;
+    _input_size_in_bits = EVEX_32bit;
   }
   emit_simd_arith(0x58, dst, src, VEX_SIMD_F3);
 }
@@ -1254,16 +1254,16 @@
 void Assembler::aesdec(XMMRegister dst, Address src) {
   assert(VM_Version::supports_aes(), "");
   InstructionMark im(this);
-  simd_prefix(dst, dst, src, VEX_SIMD_66, false,
-              VEX_OPCODE_0F_38, false, AVX_128bit, true);
+  simd_prefix(dst, dst, src, VEX_SIMD_66, /* no_mask_reg */ false,
+              VEX_OPCODE_0F_38, /* rex_w */ false, AVX_128bit, /* legacy_mode */ true);
   emit_int8((unsigned char)0xDE);
   emit_operand(dst, src);
 }
 
 void Assembler::aesdec(XMMRegister dst, XMMRegister src) {
   assert(VM_Version::supports_aes(), "");
-  int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, false,
-                                      VEX_OPCODE_0F_38, false, AVX_128bit, true);
+  int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, /* no_mask_reg */ false,
+                                      VEX_OPCODE_0F_38,  /* rex_w */ false, AVX_128bit, /* legacy_mode */ true);
   emit_int8((unsigned char)0xDE);
   emit_int8(0xC0 | encode);
 }
@@ -1271,16 +1271,16 @@
 void Assembler::aesdeclast(XMMRegister dst, Address src) {
   assert(VM_Version::supports_aes(), "");
   InstructionMark im(this);
-  simd_prefix(dst, dst, src, VEX_SIMD_66, false,
-              VEX_OPCODE_0F_38, false, AVX_128bit, true);
+  simd_prefix(dst, dst, src, VEX_SIMD_66, /* no_mask_reg */ false,
+              VEX_OPCODE_0F_38, /* rex_w */ false, AVX_128bit,  /* legacy_mode */ true);
   emit_int8((unsigned char)0xDF);
   emit_operand(dst, src);
 }
 
 void Assembler::aesdeclast(XMMRegister dst, XMMRegister src) {
   assert(VM_Version::supports_aes(), "");
-  int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, false,
-                                      VEX_OPCODE_0F_38, false, AVX_128bit, true);
+  int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, /* no_mask_reg */ false,
+                                      VEX_OPCODE_0F_38,  /* rex_w */ false, AVX_128bit, /* legacy_mode */ true);
   emit_int8((unsigned char)0xDF);
   emit_int8((unsigned char)(0xC0 | encode));
 }
@@ -1288,16 +1288,16 @@
 void Assembler::aesenc(XMMRegister dst, Address src) {
   assert(VM_Version::supports_aes(), "");
   InstructionMark im(this);
-  simd_prefix(dst, dst, src, VEX_SIMD_66, false,
-              VEX_OPCODE_0F_38, false, AVX_128bit, true);
+  simd_prefix(dst, dst, src, VEX_SIMD_66, /* no_mask_reg */ false,
+              VEX_OPCODE_0F_38, /* rex_w */ false, AVX_128bit, /* legacy_mode */ true);
   emit_int8((unsigned char)0xDC);
   emit_operand(dst, src);
 }
 
 void Assembler::aesenc(XMMRegister dst, XMMRegister src) {
   assert(VM_Version::supports_aes(), "");
-  int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, false,
-                                      VEX_OPCODE_0F_38, false, AVX_128bit, true);
+  int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, /* no_mask_reg */ false,
+                                      VEX_OPCODE_0F_38, /* rex_w */ false, AVX_128bit, /* legacy_mode */ true);
   emit_int8((unsigned char)0xDC);
   emit_int8(0xC0 | encode);
 }
@@ -1305,21 +1305,20 @@
 void Assembler::aesenclast(XMMRegister dst, Address src) {
   assert(VM_Version::supports_aes(), "");
   InstructionMark im(this);
-  simd_prefix(dst, dst, src, VEX_SIMD_66, false,
-              VEX_OPCODE_0F_38, false, AVX_128bit, true);
+  simd_prefix(dst, dst, src, VEX_SIMD_66, /* no_mask_reg */ false,
+              VEX_OPCODE_0F_38, /* rex_w */ false, AVX_128bit,  /* legacy_mode */ true);
   emit_int8((unsigned char)0xDD);
   emit_operand(dst, src);
 }
 
 void Assembler::aesenclast(XMMRegister dst, XMMRegister src) {
   assert(VM_Version::supports_aes(), "");
-  int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, false,
-                                      VEX_OPCODE_0F_38, false, AVX_128bit, true);
+  int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, /* no_mask_reg */ false,
+                                      VEX_OPCODE_0F_38, /* rex_w */ false, AVX_128bit, /* legacy_mode */ true);
   emit_int8((unsigned char)0xDD);
   emit_int8((unsigned char)(0xC0 | encode));
 }
 
-
 void Assembler::andl(Address dst, int32_t imm32) {
   InstructionMark im(this);
   prefix(dst);
@@ -1347,7 +1346,7 @@
 
 void Assembler::andnl(Register dst, Register src1, Register src2) {
   assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
-  int encode = vex_prefix_0F38_and_encode_legacy(dst, src1, src2, false);
+  int encode = vex_prefix_0F38_and_encode_legacy(dst, src1, src2);
   emit_int8((unsigned char)0xF2);
   emit_int8((unsigned char)(0xC0 | encode));
 }
@@ -1355,7 +1354,7 @@
 void Assembler::andnl(Register dst, Register src1, Address src2) {
   InstructionMark im(this);
   assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
-  vex_prefix_0F38_legacy(dst, src1, src2, false);
+  vex_prefix_0F38_legacy(dst, src1, src2);
   emit_int8((unsigned char)0xF2);
   emit_operand(dst, src2);
 }
@@ -1382,7 +1381,7 @@
 
 void Assembler::blsil(Register dst, Register src) {
   assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
-  int encode = vex_prefix_0F38_and_encode_legacy(rbx, dst, src, false);
+  int encode = vex_prefix_0F38_and_encode_legacy(rbx, dst, src);
   emit_int8((unsigned char)0xF3);
   emit_int8((unsigned char)(0xC0 | encode));
 }
@@ -1390,14 +1389,14 @@
 void Assembler::blsil(Register dst, Address src) {
   InstructionMark im(this);
   assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
-  vex_prefix_0F38_legacy(rbx, dst, src, false);
+  vex_prefix_0F38_legacy(rbx, dst, src);
   emit_int8((unsigned char)0xF3);
   emit_operand(rbx, src);
 }
 
 void Assembler::blsmskl(Register dst, Register src) {
   assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
-  int encode = vex_prefix_0F38_and_encode_legacy(rdx, dst, src, false);
+  int encode = vex_prefix_0F38_and_encode_legacy(rdx, dst, src);
   emit_int8((unsigned char)0xF3);
   emit_int8((unsigned char)(0xC0 | encode));
 }
@@ -1405,14 +1404,14 @@
 void Assembler::blsmskl(Register dst, Address src) {
   InstructionMark im(this);
   assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
-  vex_prefix_0F38(rdx, dst, src, false);
+  vex_prefix_0F38_legacy(rdx, dst, src);
   emit_int8((unsigned char)0xF3);
   emit_operand(rdx, src);
 }
 
 void Assembler::blsrl(Register dst, Register src) {
   assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
-  int encode = vex_prefix_0F38_and_encode_legacy(rcx, dst, src, false);
+  int encode = vex_prefix_0F38_and_encode_legacy(rcx, dst, src);
   emit_int8((unsigned char)0xF3);
   emit_int8((unsigned char)(0xC0 | encode));
 }
@@ -1420,7 +1419,7 @@
 void Assembler::blsrl(Register dst, Address src) {
   InstructionMark im(this);
   assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
-  vex_prefix_0F38_legacy(rcx, dst, src, false);
+  vex_prefix_0F38_legacy(rcx, dst, src);
   emit_int8((unsigned char)0xF3);
   emit_operand(rcx, src);
 }
@@ -1569,9 +1568,9 @@
   // 0x66 is there. Strangly ucomisd comes out correct
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_T1S;
-    input_size_in_bits = EVEX_64bit;
-    emit_simd_arith_nonds_q(0x2F, dst, src, VEX_SIMD_66, true);
+    _tuple_type = EVEX_T1S;
+    _input_size_in_bits = EVEX_64bit;
+    emit_simd_arith_nonds_q(0x2F, dst, src, VEX_SIMD_66, /* no_mask_reg */ true);
   } else {
     emit_simd_arith_nonds(0x2F, dst, src, VEX_SIMD_66);
   }
@@ -1580,7 +1579,7 @@
 void Assembler::comisd(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   if (VM_Version::supports_evex()) {
-    emit_simd_arith_nonds_q(0x2F, dst, src, VEX_SIMD_66, true);
+    emit_simd_arith_nonds_q(0x2F, dst, src, VEX_SIMD_66, /* no_mask_reg */ true);
   } else {
     emit_simd_arith_nonds(0x2F, dst, src, VEX_SIMD_66);
   }
@@ -1588,16 +1587,16 @@
 
 void Assembler::comiss(XMMRegister dst, Address src) {
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_T1S;
-    input_size_in_bits = EVEX_32bit;
+    _tuple_type = EVEX_T1S;
+    _input_size_in_bits = EVEX_32bit;
   }
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
-  emit_simd_arith_nonds(0x2F, dst, src, VEX_SIMD_NONE, true);
+  emit_simd_arith_nonds(0x2F, dst, src, VEX_SIMD_NONE, /* no_mask_reg */ true);
 }
 
 void Assembler::comiss(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
-  emit_simd_arith_nonds(0x2F, dst, src, VEX_SIMD_NONE, true);
+  emit_simd_arith_nonds(0x2F, dst, src, VEX_SIMD_NONE, /* no_mask_reg */ true);
 }
 
 void Assembler::cpuid() {
@@ -1607,12 +1606,12 @@
 
 void Assembler::cvtdq2pd(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  emit_simd_arith_nonds(0xE6, dst, src, VEX_SIMD_F3);
+  emit_simd_arith_nonds(0xE6, dst, src, VEX_SIMD_F3, /* no_mask_reg */ false, /* legacy_mode */ true);
 }
 
 void Assembler::cvtdq2ps(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  emit_simd_arith_nonds(0x5B, dst, src, VEX_SIMD_NONE);
+  emit_simd_arith_nonds(0x5B, dst, src, VEX_SIMD_NONE, /* no_mask_reg */ false, /* legacy_mode */ true);
 }
 
 void Assembler::cvtsd2ss(XMMRegister dst, XMMRegister src) {
@@ -1627,8 +1626,8 @@
 void Assembler::cvtsd2ss(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_T1F;
-    input_size_in_bits = EVEX_64bit;
+    _tuple_type = EVEX_T1F;
+    _input_size_in_bits = EVEX_64bit;
     emit_simd_arith_q(0x5A, dst, src, VEX_SIMD_F2);
   } else {
     emit_simd_arith(0x5A, dst, src, VEX_SIMD_F2);
@@ -1637,12 +1636,7 @@
 
 void Assembler::cvtsi2sdl(XMMRegister dst, Register src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  int encode = 0;
-  if (VM_Version::supports_evex()) {
-    encode = simd_prefix_and_encode_q(dst, dst, src, VEX_SIMD_F2, true);
-  } else {
-    encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F2, false);
-  }
+  int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F2, VM_Version::supports_evex());
   emit_int8(0x2A);
   emit_int8((unsigned char)(0xC0 | encode));
 }
@@ -1650,9 +1644,9 @@
 void Assembler::cvtsi2sdl(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_T1S;
-    input_size_in_bits = EVEX_32bit;
-    emit_simd_arith_q(0x2A, dst, src, VEX_SIMD_F2, true);
+    _tuple_type = EVEX_T1S;
+    _input_size_in_bits = EVEX_32bit;
+    emit_simd_arith(0x2A, dst, src, VEX_SIMD_F2, /* no_mask_reg */ true);
   } else {
     emit_simd_arith(0x2A, dst, src, VEX_SIMD_F2);
   }
@@ -1660,23 +1654,23 @@
 
 void Assembler::cvtsi2ssl(XMMRegister dst, Register src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
-  int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F3, true);
+  int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F3, /* no_mask_reg */ true);
   emit_int8(0x2A);
   emit_int8((unsigned char)(0xC0 | encode));
 }
 
 void Assembler::cvtsi2ssl(XMMRegister dst, Address src) {
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_T1S;
-    input_size_in_bits = EVEX_32bit;
+    _tuple_type = EVEX_T1S;
+    _input_size_in_bits = EVEX_32bit;
   }
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
-  emit_simd_arith(0x2A, dst, src, VEX_SIMD_F3, true);
+  emit_simd_arith(0x2A, dst, src, VEX_SIMD_F3, /* no_mask_reg */ true);
 }
 
 void Assembler::cvtsi2ssq(XMMRegister dst, Register src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
-  int encode = simd_prefix_and_encode_q(dst, dst, src, VEX_SIMD_F3, true);
+  int encode = simd_prefix_and_encode_q(dst, dst, src, VEX_SIMD_F3, /* no_mask_reg */ true);
   emit_int8(0x2A);
   emit_int8((unsigned char)(0xC0 | encode));
 }
@@ -1688,8 +1682,8 @@
 
 void Assembler::cvtss2sd(XMMRegister dst, Address src) {
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_T1S;
-    input_size_in_bits = EVEX_32bit;
+    _tuple_type = EVEX_T1S;
+    _input_size_in_bits = EVEX_32bit;
   }
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   emit_simd_arith(0x5A, dst, src, VEX_SIMD_F3);
@@ -1698,14 +1692,14 @@
 
 void Assembler::cvttsd2sil(Register dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  int encode = simd_prefix_and_encode(dst, src, VEX_SIMD_F2, VEX_OPCODE_0F, true);
+  int encode = simd_prefix_and_encode(dst, src, VEX_SIMD_F2, VEX_OPCODE_0F, /* no_mask_reg */ true);
   emit_int8(0x2C);
   emit_int8((unsigned char)(0xC0 | encode));
 }
 
 void Assembler::cvttss2sil(Register dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
-  int encode = simd_prefix_and_encode(dst, src, VEX_SIMD_F3, VEX_OPCODE_0F, true);
+  int encode = simd_prefix_and_encode(dst, src, VEX_SIMD_F3, VEX_OPCODE_0F, /* no_mask_reg */ true);
   emit_int8(0x2C);
   emit_int8((unsigned char)(0xC0 | encode));
 }
@@ -1721,8 +1715,8 @@
 void Assembler::divsd(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_T1S;
-    input_size_in_bits = EVEX_64bit;
+    _tuple_type = EVEX_T1S;
+    _input_size_in_bits = EVEX_64bit;
     emit_simd_arith_q(0x5E, dst, src, VEX_SIMD_F2);
   } else {
     emit_simd_arith(0x5E, dst, src, VEX_SIMD_F2);
@@ -1740,8 +1734,8 @@
 
 void Assembler::divss(XMMRegister dst, Address src) {
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_T1S;
-    input_size_in_bits = EVEX_32bit;
+    _tuple_type = EVEX_T1S;
+    _input_size_in_bits = EVEX_32bit;
   }
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
   emit_simd_arith(0x5E, dst, src, VEX_SIMD_F3);
@@ -1995,8 +1989,16 @@
 
 void Assembler::movapd(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  if (VM_Version::supports_evex()) {
-    emit_simd_arith_nonds_q(0x28, dst, src, VEX_SIMD_66, true);
+  if (VM_Version::supports_avx512novl()) {
+    int vector_len = AVX_512bit;
+    int dst_enc = dst->encoding();
+    int src_enc = src->encoding();
+    int encode = vex_prefix_and_encode(dst_enc, 0, src_enc, VEX_SIMD_66, VEX_OPCODE_0F,
+                                       /* vex_w */ true, vector_len, /* legacy_mode */ false, /* no_mask_reg */ false);
+    emit_int8(0x28);
+    emit_int8((unsigned char)(0xC0 | encode));
+  } else if (VM_Version::supports_evex()) {
+    emit_simd_arith_nonds_q(0x28, dst, src, VEX_SIMD_66);
   } else {
     emit_simd_arith_nonds(0x28, dst, src, VEX_SIMD_66);
   }
@@ -2004,13 +2006,19 @@
 
 void Assembler::movaps(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
-  emit_simd_arith_nonds(0x28, dst, src, VEX_SIMD_NONE);
+  if (VM_Version::supports_avx512novl()) {
+    int vector_len = AVX_512bit;
+    int encode = vex_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_NONE, vector_len);
+    emit_int8(0x28);
+    emit_int8((unsigned char)(0xC0 | encode));
+  } else {
+    emit_simd_arith_nonds(0x28, dst, src, VEX_SIMD_NONE);
+  }
 }
 
 void Assembler::movlhps(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
-  int encode = simd_prefix_and_encode(dst, src, src, VEX_SIMD_NONE, true, VEX_OPCODE_0F,
-                                      false, AVX_128bit);
+  int encode = simd_prefix_and_encode(dst, src, src, VEX_SIMD_NONE, /* no_mask_reg */ true);
   emit_int8(0x16);
   emit_int8((unsigned char)(0xC0 | encode));
 }
@@ -2023,48 +2031,54 @@
   emit_operand(dst, src);
 }
 
-void Assembler::kmovq(KRegister dst, KRegister src) {
+void Assembler::kmovql(KRegister dst, KRegister src) {
   NOT_LP64(assert(VM_Version::supports_evex(), ""));
   int encode = kreg_prefix_and_encode(dst, knoreg, src, VEX_SIMD_NONE,
-                                      true, VEX_OPCODE_0F, true);
+                                      /* no_mask_reg */ true, VEX_OPCODE_0F, /* rex_w */ true);
   emit_int8((unsigned char)0x90);
   emit_int8((unsigned char)(0xC0 | encode));
 }
 
-void Assembler::kmovq(KRegister dst, Address src) {
+void Assembler::kmovql(KRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_evex(), ""));
   int dst_enc = dst->encoding();
   int nds_enc = 0;
   vex_prefix(src, nds_enc, dst_enc, VEX_SIMD_NONE,
-             VEX_OPCODE_0F, true, AVX_128bit, true, true);
+             VEX_OPCODE_0F, /* vex_w */  true, AVX_128bit, /* legacy_mode */ true, /* no_reg_mask */ true);
   emit_int8((unsigned char)0x90);
   emit_operand((Register)dst, src);
 }
 
-void Assembler::kmovq(Address dst, KRegister src) {
+void Assembler::kmovql(Address dst, KRegister src) {
   NOT_LP64(assert(VM_Version::supports_evex(), ""));
   int src_enc = src->encoding();
   int nds_enc = 0;
   vex_prefix(dst, nds_enc, src_enc, VEX_SIMD_NONE,
-             VEX_OPCODE_0F, true, AVX_128bit, true, true);
+             VEX_OPCODE_0F, /* vex_w */ true, AVX_128bit, /* legacy_mode */ true, /* no_reg_mask */ true);
   emit_int8((unsigned char)0x90);
   emit_operand((Register)src, dst);
 }
 
 void Assembler::kmovql(KRegister dst, Register src) {
   NOT_LP64(assert(VM_Version::supports_evex(), ""));
-  bool supports_bw = VM_Version::supports_avx512bw();
-  VexSimdPrefix pre = supports_bw ? VEX_SIMD_F2 : VEX_SIMD_NONE;
-  int encode = kreg_prefix_and_encode(dst, knoreg, src, pre, true,
-                                      VEX_OPCODE_0F, supports_bw);
+  VexSimdPrefix pre = !_legacy_mode_bw ? VEX_SIMD_F2 : VEX_SIMD_NONE;
+  int encode = kreg_prefix_and_encode(dst, knoreg, src, pre, /* no_mask_reg */ true,
+                                      VEX_OPCODE_0F, /* legacy_mode */ !_legacy_mode_bw);
   emit_int8((unsigned char)0x92);
   emit_int8((unsigned char)(0xC0 | encode));
 }
 
 void Assembler::kmovdl(KRegister dst, Register src) {
   NOT_LP64(assert(VM_Version::supports_evex(), ""));
-  VexSimdPrefix pre = VM_Version::supports_avx512bw() ? VEX_SIMD_F2 : VEX_SIMD_NONE;
-  int encode = kreg_prefix_and_encode(dst, knoreg, src, pre, true, VEX_OPCODE_0F, false);
+  VexSimdPrefix pre = !_legacy_mode_bw ? VEX_SIMD_F2 : VEX_SIMD_NONE;
+  int encode = kreg_prefix_and_encode(dst, knoreg, src, pre, /* no_mask_reg */ true);
+  emit_int8((unsigned char)0x92);
+  emit_int8((unsigned char)(0xC0 | encode));
+}
+
+void Assembler::kmovwl(KRegister dst, Register src) {
+  NOT_LP64(assert(VM_Version::supports_evex(), ""));
+  int encode = kreg_prefix_and_encode(dst, knoreg, src, VEX_SIMD_NONE, /* no_mask_reg */ true);
   emit_int8((unsigned char)0x92);
   emit_int8((unsigned char)(0xC0 | encode));
 }
@@ -2088,7 +2102,7 @@
 
 void Assembler::movdl(XMMRegister dst, Register src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  int encode = simd_prefix_and_encode(dst, src, VEX_SIMD_66, true);
+  int encode = simd_prefix_and_encode(dst, src, VEX_SIMD_66, /* no_mask_reg */ true);
   emit_int8(0x6E);
   emit_int8((unsigned char)(0xC0 | encode));
 }
@@ -2096,7 +2110,7 @@
 void Assembler::movdl(Register dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   // swap src/dst to get correct prefix
-  int encode = simd_prefix_and_encode(src, dst, VEX_SIMD_66, true);
+  int encode = simd_prefix_and_encode(src, dst, VEX_SIMD_66, /* no_mask_reg */ true);
   emit_int8(0x7E);
   emit_int8((unsigned char)(0xC0 | encode));
 }
@@ -2104,11 +2118,11 @@
 void Assembler::movdl(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_T1S;
-    input_size_in_bits = EVEX_32bit;
-  }
-  InstructionMark im(this);
-  simd_prefix(dst, src, VEX_SIMD_66, true, VEX_OPCODE_0F);
+    _tuple_type = EVEX_T1S;
+    _input_size_in_bits = EVEX_32bit;
+  }
+  InstructionMark im(this);
+  simd_prefix(dst, src, VEX_SIMD_66, /* no_reg_mask */ true);
   emit_int8(0x6E);
   emit_operand(dst, src);
 }
@@ -2116,58 +2130,61 @@
 void Assembler::movdl(Address dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_T1S;
-    input_size_in_bits = EVEX_32bit;
-  }
-  InstructionMark im(this);
-  simd_prefix(dst, src, VEX_SIMD_66, true);
+    _tuple_type = EVEX_T1S;
+    _input_size_in_bits = EVEX_32bit;
+  }
+  InstructionMark im(this);
+  simd_prefix(dst, src, VEX_SIMD_66, /* no_reg_mask */ true);
   emit_int8(0x7E);
   emit_operand(src, dst);
 }
 
 void Assembler::movdqa(XMMRegister dst, XMMRegister src) {
+  _instruction_uses_vl = true;
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   emit_simd_arith_nonds(0x6F, dst, src, VEX_SIMD_66);
 }
 
 void Assembler::movdqa(XMMRegister dst, Address src) {
+  _instruction_uses_vl = true;
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_FVM;
+    _tuple_type = EVEX_FVM;
   }
   emit_simd_arith_nonds(0x6F, dst, src, VEX_SIMD_66);
 }
 
 void Assembler::movdqu(XMMRegister dst, Address src) {
+  _instruction_uses_vl = true;
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_FVM;
+    _tuple_type = EVEX_FVM;
   }
   emit_simd_arith_nonds(0x6F, dst, src, VEX_SIMD_F3);
 }
 
 void Assembler::movdqu(XMMRegister dst, XMMRegister src) {
+  _instruction_uses_vl = true;
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   emit_simd_arith_nonds(0x6F, dst, src, VEX_SIMD_F3);
 }
 
 void Assembler::movdqu(Address dst, XMMRegister src) {
+  _instruction_uses_vl = true;
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_FVM;
-  }
-  InstructionMark im(this);
-  simd_prefix(dst, src, VEX_SIMD_F3, false);
+    _tuple_type = EVEX_FVM;
+  }
+  InstructionMark im(this);
+  simd_prefix(dst, src, VEX_SIMD_F3, /* no_mask_reg */ false);
   emit_int8(0x7F);
   emit_operand(src, dst);
 }
 
 // Move Unaligned 256bit Vector
 void Assembler::vmovdqu(XMMRegister dst, XMMRegister src) {
+  _instruction_uses_vl = true;
   assert(UseAVX > 0, "");
-  if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_FVM;
-  }
   int vector_len = AVX_256bit;
   int encode = vex_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_F3, vector_len);
   emit_int8(0x6F);
@@ -2175,67 +2192,100 @@
 }
 
 void Assembler::vmovdqu(XMMRegister dst, Address src) {
+  _instruction_uses_vl = true;
   assert(UseAVX > 0, "");
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_FVM;
+    _tuple_type = EVEX_FVM;
   }
   InstructionMark im(this);
   int vector_len = AVX_256bit;
-  vex_prefix(dst, xnoreg, src, VEX_SIMD_F3, vector_len, false);
+  vex_prefix(dst, xnoreg, src, VEX_SIMD_F3, vector_len);
   emit_int8(0x6F);
   emit_operand(dst, src);
 }
 
 void Assembler::vmovdqu(Address dst, XMMRegister src) {
+  _instruction_uses_vl = true;
   assert(UseAVX > 0, "");
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_FVM;
+    _tuple_type = EVEX_FVM;
   }
   InstructionMark im(this);
   int vector_len = AVX_256bit;
   // swap src<->dst for encoding
   assert(src != xnoreg, "sanity");
-  vex_prefix(src, xnoreg, dst, VEX_SIMD_F3, vector_len, false);
+  vex_prefix(src, xnoreg, dst, VEX_SIMD_F3, vector_len);
   emit_int8(0x7F);
   emit_operand(src, dst);
 }
 
 // Move Unaligned EVEX enabled Vector (programmable : 8,16,32,64)
-void Assembler::evmovdqu(XMMRegister dst, XMMRegister src, int vector_len) {
+void Assembler::evmovdqul(XMMRegister dst, XMMRegister src, int vector_len) {
+  _instruction_uses_vl = true;
   assert(UseAVX > 0, "");
   int src_enc = src->encoding();
   int dst_enc = dst->encoding();
   int encode = vex_prefix_and_encode(dst_enc, 0, src_enc, VEX_SIMD_F3, VEX_OPCODE_0F,
-                                     true, vector_len, false, false);
+                                     /* vex_w */ false, vector_len, /* legacy_mode */ false, /* no_mask_reg */ false);
   emit_int8(0x6F);
   emit_int8((unsigned char)(0xC0 | encode));
 }
 
-void Assembler::evmovdqu(XMMRegister dst, Address src, int vector_len) {
+void Assembler::evmovdqul(XMMRegister dst, Address src, int vector_len) {
+  _instruction_uses_vl = true;
   assert(UseAVX > 0, "");
   InstructionMark im(this);
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_FVM;
-    vex_prefix_q(dst, xnoreg, src, VEX_SIMD_F3, vector_len, false);
-  } else {
-    vex_prefix(dst, xnoreg, src, VEX_SIMD_F3, vector_len, false);
-  }
+    _tuple_type = EVEX_FVM;
+  }
+  vex_prefix(dst, xnoreg, src, VEX_SIMD_F3, vector_len);
   emit_int8(0x6F);
   emit_operand(dst, src);
 }
 
-void Assembler::evmovdqu(Address dst, XMMRegister src, int vector_len) {
+void Assembler::evmovdqul(Address dst, XMMRegister src, int vector_len) {
+  _instruction_uses_vl = true;
   assert(UseAVX > 0, "");
   InstructionMark im(this);
   assert(src != xnoreg, "sanity");
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_FVM;
-    // swap src<->dst for encoding
-    vex_prefix_q(src, xnoreg, dst, VEX_SIMD_F3, vector_len, false);
-  } else {
-    // swap src<->dst for encoding
-    vex_prefix(src, xnoreg, dst, VEX_SIMD_F3, vector_len, false);
-  }
+    _tuple_type = EVEX_FVM;
+  }
+  // swap src<->dst for encoding
+  vex_prefix(src, xnoreg, dst, VEX_SIMD_F3, vector_len);
+  emit_int8(0x7F);
+  emit_operand(src, dst);
+}
+
+void Assembler::evmovdquq(XMMRegister dst, XMMRegister src, int vector_len) {
+  _instruction_uses_vl = true;
+  assert(UseAVX > 0, "");
+  int src_enc = src->encoding();
+  int dst_enc = dst->encoding();
+  int encode = vex_prefix_and_encode(dst_enc, 0, src_enc, VEX_SIMD_F3, VEX_OPCODE_0F,
+                                     /* vex_w */ true, vector_len, /* legacy_mode */ false, /* no_mask_reg */ false);
+  emit_int8(0x6F);
+  emit_int8((unsigned char)(0xC0 | encode));
+}
+
+void Assembler::evmovdquq(XMMRegister dst, Address src, int vector_len) {
+  _instruction_uses_vl = true;
+  assert(UseAVX > 2, "");
+  InstructionMark im(this);
+  _tuple_type = EVEX_FVM;
+  vex_prefix_q(dst, xnoreg, src, VEX_SIMD_F3, vector_len);
+  emit_int8(0x6F);
+  emit_operand(dst, src);
+}
+
+void Assembler::evmovdquq(Address dst, XMMRegister src, int vector_len) {
+  _instruction_uses_vl = true;
+  assert(UseAVX > 2, "");
+  InstructionMark im(this);
+  assert(src != xnoreg, "sanity");
+  _tuple_type = EVEX_FVM;
+  // swap src<->dst for encoding
+  vex_prefix_q(src, xnoreg, dst, VEX_SIMD_F3, vector_len);
   emit_int8(0x7F);
   emit_operand(src, dst);
 }
@@ -2282,10 +2332,12 @@
 void Assembler::movlpd(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_T1S;
-    input_size_in_bits = EVEX_32bit;
-  }
-  emit_simd_arith(0x12, dst, src, VEX_SIMD_66, true);
+    _tuple_type = EVEX_T1S;
+    _input_size_in_bits = EVEX_32bit;
+    emit_simd_arith_q(0x12, dst, src, VEX_SIMD_66, /* no_mask_reg */ true);
+  } else {
+    emit_simd_arith(0x12, dst, src, VEX_SIMD_66, /* no_mask_reg */ true);
+  }
 }
 
 void Assembler::movq( MMXRegister dst, Address src ) {
@@ -2312,11 +2364,11 @@
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   InstructionMark im(this);
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_T1S;
-    input_size_in_bits = EVEX_64bit;
-    simd_prefix_q(dst, xnoreg, src, VEX_SIMD_F3, true);
+    _tuple_type = EVEX_T1S;
+    _input_size_in_bits = EVEX_64bit;
+    simd_prefix_q(dst, xnoreg, src, VEX_SIMD_F3, /* no_mask_reg */ true);
   } else {
-    simd_prefix(dst, src, VEX_SIMD_F3, true, VEX_OPCODE_0F);
+    simd_prefix(dst, src, VEX_SIMD_F3, /* no_mask_reg */ true);
   }
   emit_int8(0x7E);
   emit_operand(dst, src);
@@ -2326,12 +2378,12 @@
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   InstructionMark im(this);
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_T1S;
-    input_size_in_bits = EVEX_64bit;
-    simd_prefix(src, xnoreg, dst, VEX_SIMD_66, true,
-                VEX_OPCODE_0F, true, AVX_128bit);
+    _tuple_type = EVEX_T1S;
+    _input_size_in_bits = EVEX_64bit;
+    simd_prefix(src, xnoreg, dst, VEX_SIMD_66, /* no_mask_reg */ true,
+                VEX_OPCODE_0F, /* rex_w */ true);
   } else {
-    simd_prefix(dst, src, VEX_SIMD_66, true);
+    simd_prefix(dst, src, VEX_SIMD_66, /* no_mask_reg */ true);
   }
   emit_int8((unsigned char)0xD6);
   emit_operand(src, dst);
@@ -2356,7 +2408,7 @@
 void Assembler::movsd(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   if (VM_Version::supports_evex()) {
-    emit_simd_arith_q(0x10, dst, src, VEX_SIMD_F2, true);
+    emit_simd_arith_q(0x10, dst, src, VEX_SIMD_F2, /* no_mask_reg */ true);
   } else {
     emit_simd_arith(0x10, dst, src, VEX_SIMD_F2);
   }
@@ -2365,9 +2417,9 @@
 void Assembler::movsd(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_T1S;
-    input_size_in_bits = EVEX_64bit;
-    emit_simd_arith_nonds_q(0x10, dst, src, VEX_SIMD_F2, true);
+    _tuple_type = EVEX_T1S;
+    _input_size_in_bits = EVEX_64bit;
+    emit_simd_arith_nonds_q(0x10, dst, src, VEX_SIMD_F2, /* no_mask_reg */ true);
   } else {
     emit_simd_arith_nonds(0x10, dst, src, VEX_SIMD_F2);
   }
@@ -2377,11 +2429,11 @@
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   InstructionMark im(this);
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_T1S;
-    input_size_in_bits = EVEX_64bit;
+    _tuple_type = EVEX_T1S;
+    _input_size_in_bits = EVEX_64bit;
     simd_prefix_q(src, xnoreg, dst, VEX_SIMD_F2);
   } else {
-    simd_prefix(src, xnoreg, dst, VEX_SIMD_F2, false);
+    simd_prefix(src, xnoreg, dst, VEX_SIMD_F2, /* no_mask_reg */ false);
   }
   emit_int8(0x11);
   emit_operand(src, dst);
@@ -2389,26 +2441,26 @@
 
 void Assembler::movss(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
-  emit_simd_arith(0x10, dst, src, VEX_SIMD_F3, true);
+  emit_simd_arith(0x10, dst, src, VEX_SIMD_F3, /* no_mask_reg */ true);
 }
 
 void Assembler::movss(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_T1S;
-    input_size_in_bits = EVEX_32bit;
-  }
-  emit_simd_arith_nonds(0x10, dst, src, VEX_SIMD_F3, true);
+    _tuple_type = EVEX_T1S;
+    _input_size_in_bits = EVEX_32bit;
+  }
+  emit_simd_arith_nonds(0x10, dst, src, VEX_SIMD_F3, /* no_mask_reg */ true);
 }
 
 void Assembler::movss(Address dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_T1S;
-    input_size_in_bits = EVEX_32bit;
-  }
-  InstructionMark im(this);
-  simd_prefix(dst, src, VEX_SIMD_F3, false);
+    _tuple_type = EVEX_T1S;
+    _input_size_in_bits = EVEX_32bit;
+  }
+  InstructionMark im(this);
+  simd_prefix(dst, src, VEX_SIMD_F3, /* no_mask_reg */ false);
   emit_int8(0x11);
   emit_operand(src, dst);
 }
@@ -2501,8 +2553,8 @@
 void Assembler::mulsd(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_T1S;
-    input_size_in_bits = EVEX_64bit;
+    _tuple_type = EVEX_T1S;
+    _input_size_in_bits = EVEX_64bit;
     emit_simd_arith_q(0x59, dst, src, VEX_SIMD_F2);
   } else {
     emit_simd_arith(0x59, dst, src, VEX_SIMD_F2);
@@ -2521,8 +2573,8 @@
 void Assembler::mulss(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_T1S;
-    input_size_in_bits = EVEX_32bit;
+    _tuple_type = EVEX_T1S;
+    _input_size_in_bits = EVEX_32bit;
   }
   emit_simd_arith(0x59, dst, src, VEX_SIMD_F3);
 }
@@ -2831,29 +2883,27 @@
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   assert((UseAVX > 0), "SSE mode requires address alignment 16 bytes");
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_FV;
-    input_size_in_bits = EVEX_32bit;
-  }
-  emit_simd_arith(0x67, dst, src, VEX_SIMD_66,
-                  false, (VM_Version::supports_avx512dq() == false));
+    _tuple_type = EVEX_FV;
+    _input_size_in_bits = EVEX_32bit;
+  }
+  emit_simd_arith(0x67, dst, src, VEX_SIMD_66, /* no_mask_reg */ false, /* legacy_mode */ _legacy_mode_bw);
 }
 
 void Assembler::packuswb(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  emit_simd_arith(0x67, dst, src, VEX_SIMD_66,
-                  false, (VM_Version::supports_avx512dq() == false));
+  emit_simd_arith(0x67, dst, src, VEX_SIMD_66, /* no_mask_reg */ false, /* legacy_mode */ _legacy_mode_bw);
 }
 
 void Assembler::vpackuswb(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
   assert(UseAVX > 0, "some form of AVX must be enabled");
-  emit_vex_arith(0x67, dst, nds, src, VEX_SIMD_66, vector_len,
-                 false, (VM_Version::supports_avx512dq() == false));
+  emit_vex_arith(0x67, dst, nds, src, VEX_SIMD_66, vector_len, /* no_mask_reg */ false, /* legacy_mode */ _legacy_mode_bw);
 }
 
 void Assembler::vpermq(XMMRegister dst, XMMRegister src, int imm8, int vector_len) {
+  _instruction_uses_vl = true;
   assert(VM_Version::supports_avx2(), "");
-  int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, false,
-                                      VEX_OPCODE_0F_3A, true, vector_len);
+  int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, /* no_mask_reg */ false,
+                                      VEX_OPCODE_0F_3A, /* rex_w */ true, vector_len);
   emit_int8(0x00);
   emit_int8(0xC0 | encode);
   emit_int8(imm8);
@@ -2867,8 +2917,8 @@
 void Assembler::pcmpestri(XMMRegister dst, Address src, int imm8) {
   assert(VM_Version::supports_sse4_2(), "");
   InstructionMark im(this);
-  simd_prefix(dst, xnoreg, src, VEX_SIMD_66, false, VEX_OPCODE_0F_3A,
-              false, AVX_128bit, true);
+  simd_prefix(dst, xnoreg, src, VEX_SIMD_66, /* no_mask_reg */ false, VEX_OPCODE_0F_3A,
+              /* rex_w */ false, AVX_128bit, /* legacy_mode */ true);
   emit_int8(0x61);
   emit_operand(dst, src);
   emit_int8(imm8);
@@ -2876,8 +2926,8 @@
 
 void Assembler::pcmpestri(XMMRegister dst, XMMRegister src, int imm8) {
   assert(VM_Version::supports_sse4_2(), "");
-  int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, false,
-                                      VEX_OPCODE_0F_3A, false, AVX_128bit, true);
+  int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, /* no_mask_reg */ false,
+                                      VEX_OPCODE_0F_3A, /* rex_w */ false, AVX_128bit, /* legacy_mode */ true);
   emit_int8(0x61);
   emit_int8((unsigned char)(0xC0 | encode));
   emit_int8(imm8);
@@ -2885,8 +2935,8 @@
 
 void Assembler::pextrd(Register dst, XMMRegister src, int imm8) {
   assert(VM_Version::supports_sse4_1(), "");
-  int encode = simd_prefix_and_encode(as_XMMRegister(dst->encoding()), xnoreg, src, VEX_SIMD_66, true, VEX_OPCODE_0F_3A,
-                                      false, AVX_128bit, (VM_Version::supports_avx512dq() == false));
+  int encode = simd_prefix_and_encode(as_XMMRegister(dst->encoding()), xnoreg, src, VEX_SIMD_66, /* no_mask_reg */ true,
+                                      VEX_OPCODE_0F_3A, /* rex_w */ false, AVX_128bit, /* legacy_mode */ _legacy_mode_dq);
   emit_int8(0x16);
   emit_int8((unsigned char)(0xC0 | encode));
   emit_int8(imm8);
@@ -2894,8 +2944,8 @@
 
 void Assembler::pextrq(Register dst, XMMRegister src, int imm8) {
   assert(VM_Version::supports_sse4_1(), "");
-  int encode = simd_prefix_and_encode(as_XMMRegister(dst->encoding()), xnoreg, src, VEX_SIMD_66, true, VEX_OPCODE_0F_3A,
-                                      false, AVX_128bit, (VM_Version::supports_avx512dq() == false));
+  int encode = simd_prefix_and_encode(as_XMMRegister(dst->encoding()), xnoreg, src, VEX_SIMD_66, /* no_mask_reg */  true,
+                                      VEX_OPCODE_0F_3A, /* rex_w */ true, AVX_128bit, /* legacy_mode */ _legacy_mode_dq);
   emit_int8(0x16);
   emit_int8((unsigned char)(0xC0 | encode));
   emit_int8(imm8);
@@ -2903,8 +2953,8 @@
 
 void Assembler::pinsrd(XMMRegister dst, Register src, int imm8) {
   assert(VM_Version::supports_sse4_1(), "");
-  int encode = simd_prefix_and_encode(dst, dst, as_XMMRegister(src->encoding()), VEX_SIMD_66, true, VEX_OPCODE_0F_3A,
-                                      false, AVX_128bit, (VM_Version::supports_avx512dq() == false));
+  int encode = simd_prefix_and_encode(dst, dst, as_XMMRegister(src->encoding()), VEX_SIMD_66, /* no_mask_reg */ true,
+                                      VEX_OPCODE_0F_3A, /* rex_w */ false, AVX_128bit, /* legacy_mode */ _legacy_mode_dq);
   emit_int8(0x22);
   emit_int8((unsigned char)(0xC0 | encode));
   emit_int8(imm8);
@@ -2912,8 +2962,8 @@
 
 void Assembler::pinsrq(XMMRegister dst, Register src, int imm8) {
   assert(VM_Version::supports_sse4_1(), "");
-  int encode = simd_prefix_and_encode(dst, dst, as_XMMRegister(src->encoding()), VEX_SIMD_66, true, VEX_OPCODE_0F_3A,
-                                      false, AVX_128bit, (VM_Version::supports_avx512dq() == false));
+  int encode = simd_prefix_and_encode(dst, dst, as_XMMRegister(src->encoding()), VEX_SIMD_66, /* no_mask_reg */ true,
+                                      VEX_OPCODE_0F_3A, /* rex_w */ true, AVX_128bit, /* legacy_mode */ _legacy_mode_dq);
   emit_int8(0x22);
   emit_int8((unsigned char)(0xC0 | encode));
   emit_int8(imm8);
@@ -2922,17 +2972,17 @@
 void Assembler::pmovzxbw(XMMRegister dst, Address src) {
   assert(VM_Version::supports_sse4_1(), "");
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_HVM;
-  }
-  InstructionMark im(this);
-  simd_prefix(dst, src, VEX_SIMD_66, false, VEX_OPCODE_0F_38);
+    _tuple_type = EVEX_HVM;
+  }
+  InstructionMark im(this);
+  simd_prefix(dst, src, VEX_SIMD_66, /* no_mask_reg */ false, VEX_OPCODE_0F_38);
   emit_int8(0x30);
   emit_operand(dst, src);
 }
 
 void Assembler::pmovzxbw(XMMRegister dst, XMMRegister src) {
   assert(VM_Version::supports_sse4_1(), "");
-  int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, false, VEX_OPCODE_0F_38);
+  int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, /* no_mask_reg */ false, VEX_OPCODE_0F_38);
   emit_int8(0x30);
   emit_int8((unsigned char)(0xC0 | encode));
 }
@@ -3035,8 +3085,8 @@
 
 void Assembler::pshufb(XMMRegister dst, XMMRegister src) {
   assert(VM_Version::supports_ssse3(), "");
-  int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, false, VEX_OPCODE_0F_38,
-                                      false, AVX_128bit, (VM_Version::supports_avx512bw() == false));
+  int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, /* no_mask_reg */ false,
+                                      VEX_OPCODE_0F_38, /* rex_w */ false, AVX_128bit, /* legacy_mode */ _legacy_mode_bw);
   emit_int8(0x00);
   emit_int8((unsigned char)(0xC0 | encode));
 }
@@ -3044,33 +3094,34 @@
 void Assembler::pshufb(XMMRegister dst, Address src) {
   assert(VM_Version::supports_ssse3(), "");
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_FVM;
-  }
-  InstructionMark im(this);
-  simd_prefix(dst, dst, src, VEX_SIMD_66, false, VEX_OPCODE_0F_38,
-              false, AVX_128bit, (VM_Version::supports_avx512bw() == false));
+    _tuple_type = EVEX_FVM;
+  }
+  InstructionMark im(this);
+  simd_prefix(dst, dst, src, VEX_SIMD_66, /* no_mask_reg */ false,
+              VEX_OPCODE_0F_38, /* rex_w */ false, AVX_128bit, /* legacy_mode */ _legacy_mode_bw);
   emit_int8(0x00);
   emit_operand(dst, src);
 }
 
 void Assembler::pshufd(XMMRegister dst, XMMRegister src, int mode) {
+  _instruction_uses_vl = true;
   assert(isByte(mode), "invalid value");
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   emit_simd_arith_nonds(0x70, dst, src, VEX_SIMD_66);
   emit_int8(mode & 0xFF);
-
 }
 
 void Assembler::pshufd(XMMRegister dst, Address src, int mode) {
+  _instruction_uses_vl = true;
   assert(isByte(mode), "invalid value");
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   assert((UseAVX > 0), "SSE mode requires address alignment 16 bytes");
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_FV;
-    input_size_in_bits = EVEX_32bit;
-  }
-  InstructionMark im(this);
-  simd_prefix(dst, src, VEX_SIMD_66, false);
+    _tuple_type = EVEX_FV;
+    _input_size_in_bits = EVEX_32bit;
+  }
+  InstructionMark im(this);
+  simd_prefix(dst, src, VEX_SIMD_66, /* no_mask_reg */ false);
   emit_int8(0x70);
   emit_operand(dst, src);
   emit_int8(mode & 0xFF);
@@ -3079,8 +3130,7 @@
 void Assembler::pshuflw(XMMRegister dst, XMMRegister src, int mode) {
   assert(isByte(mode), "invalid value");
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  emit_simd_arith_nonds(0x70, dst, src, VEX_SIMD_F2, false,
-                        (VM_Version::supports_avx512bw() == false));
+  emit_simd_arith_nonds(0x70, dst, src, VEX_SIMD_F2, /* no_mask_reg */ false, /* legacy_mode */ _legacy_mode_bw);
   emit_int8(mode & 0xFF);
 }
 
@@ -3089,29 +3139,33 @@
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   assert((UseAVX > 0), "SSE mode requires address alignment 16 bytes");
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_FVM;
-  }
-  InstructionMark im(this);
-  simd_prefix(dst, xnoreg, src, VEX_SIMD_F2, false, VEX_OPCODE_0F,
-              false, AVX_128bit, (VM_Version::supports_avx512bw() == false));
+    _tuple_type = EVEX_FVM;
+  }
+  InstructionMark im(this);
+  simd_prefix(dst, xnoreg, src, VEX_SIMD_F2, /* no_mask_reg */ false,
+              VEX_OPCODE_0F, /* rex_w */ false, AVX_128bit, /* legacy_mode */ _legacy_mode_bw);
   emit_int8(0x70);
   emit_operand(dst, src);
   emit_int8(mode & 0xFF);
 }
 
 void Assembler::psrldq(XMMRegister dst, int shift) {
-  // Shift 128 bit value in xmm register by number of bytes.
+  // Shift left 128 bit value in dst XMMRegister by shift number of bytes.
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  int encode = simd_prefix_and_encode(xmm3, dst, dst, VEX_SIMD_66, true, VEX_OPCODE_0F, false, AVX_128bit, (VM_Version::supports_avx512bw() == false));
+  // XMM3 is for /3 encoding: 66 0F 73 /3 ib
+  int encode = simd_prefix_and_encode(xmm3, dst, dst, VEX_SIMD_66, /* no_mask_reg */ true,
+                                      VEX_OPCODE_0F, /* rex_w */ false, AVX_128bit, /* legacy_mode */ _legacy_mode_bw);
   emit_int8(0x73);
   emit_int8((unsigned char)(0xC0 | encode));
   emit_int8(shift);
 }
 
 void Assembler::pslldq(XMMRegister dst, int shift) {
-  // Shift left 128 bit value in xmm register by number of bytes.
+  // Shift left 128 bit value in dst XMMRegister by shift number of bytes.
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  int encode = simd_prefix_and_encode(xmm7, dst, dst, VEX_SIMD_66, true, VEX_OPCODE_0F, false, AVX_128bit, (VM_Version::supports_avx512bw() == false));
+  // XMM7 is for /7 encoding: 66 0F 73 /7 ib
+  int encode = simd_prefix_and_encode(xmm7, dst, dst, VEX_SIMD_66, /* no_mask_reg */ true,
+                                      VEX_OPCODE_0F, /* rex_w */ false, AVX_128bit, /* legacy_mode */ _legacy_mode_bw);
   emit_int8(0x73);
   emit_int8((unsigned char)(0xC0 | encode));
   emit_int8(shift);
@@ -3121,16 +3175,16 @@
   assert(VM_Version::supports_sse4_1(), "");
   assert((UseAVX > 0), "SSE mode requires address alignment 16 bytes");
   InstructionMark im(this);
-  simd_prefix(dst, xnoreg, src, VEX_SIMD_66, false,
-              VEX_OPCODE_0F_38, false, AVX_128bit, true);
+  simd_prefix(dst, xnoreg, src, VEX_SIMD_66, /* no_mask_reg */ false,
+              VEX_OPCODE_0F_38, /* rex_w */ false, AVX_128bit, /* legacy_mode */ true);
   emit_int8(0x17);
   emit_operand(dst, src);
 }
 
 void Assembler::ptest(XMMRegister dst, XMMRegister src) {
   assert(VM_Version::supports_sse4_1(), "");
-  int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, false,
-                                      VEX_OPCODE_0F_38, false, AVX_128bit, true);
+  int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, /* no_mask_reg */ false,
+                                      VEX_OPCODE_0F_38, /* rex_w */ false, AVX_128bit, /* legacy_mode */ true);
   emit_int8(0x17);
   emit_int8((unsigned char)(0xC0 | encode));
 }
@@ -3142,7 +3196,8 @@
   assert(dst != xnoreg, "sanity");
   int dst_enc = dst->encoding();
   // swap src<->dst for encoding
-  vex_prefix(src, 0, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_38, false, vector_len, true, false);
+  vex_prefix(src, 0, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_38, /* rex_w */ false,
+             vector_len, /* legacy_mode  */ true, /* no_mask_reg */ false);
   emit_int8(0x17);
   emit_operand(dst, src);
 }
@@ -3150,8 +3205,7 @@
 void Assembler::vptest(XMMRegister dst, XMMRegister src) {
   assert(VM_Version::supports_avx(), "");
   int vector_len = AVX_256bit;
-  int encode = vex_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66,
-                                     vector_len, VEX_OPCODE_0F_38, true, false);
+  int encode = vex_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, vector_len, VEX_OPCODE_0F_38, /* legacy_mode */ true);
   emit_int8(0x17);
   emit_int8((unsigned char)(0xC0 | encode));
 }
@@ -3160,34 +3214,41 @@
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   assert((UseAVX > 0), "SSE mode requires address alignment 16 bytes");
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_FVM;
-  }
-  emit_simd_arith(0x60, dst, src, VEX_SIMD_66, false, (VM_Version::supports_avx512vlbw() == false));
+    _tuple_type = EVEX_FVM;
+  }
+  emit_simd_arith(0x60, dst, src, VEX_SIMD_66, /* no_mask_reg */ false, /* legacy_mode */ _legacy_mode_vlbw);
 }
 
 void Assembler::punpcklbw(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  emit_simd_arith(0x60, dst, src, VEX_SIMD_66, false, (VM_Version::supports_avx512vlbw() == false));
+  emit_simd_arith(0x60, dst, src, VEX_SIMD_66, /* no_mask_reg */ false, /* legacy_mode */ _legacy_mode_vlbw);
 }
 
 void Assembler::punpckldq(XMMRegister dst, Address src) {
+  _instruction_uses_vl = true;
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   assert((UseAVX > 0), "SSE mode requires address alignment 16 bytes");
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_FV;
-    input_size_in_bits = EVEX_32bit;
+    _tuple_type = EVEX_FV;
+    _input_size_in_bits = EVEX_32bit;
   }
   emit_simd_arith(0x62, dst, src, VEX_SIMD_66);
 }
 
 void Assembler::punpckldq(XMMRegister dst, XMMRegister src) {
+  _instruction_uses_vl = true;
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   emit_simd_arith(0x62, dst, src, VEX_SIMD_66);
 }
 
 void Assembler::punpcklqdq(XMMRegister dst, XMMRegister src) {
+  _instruction_uses_vl = true;
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  emit_simd_arith(0x6C, dst, src, VEX_SIMD_66);
+  if (VM_Version::supports_evex()) {
+    emit_simd_arith_q(0x6C, dst, src, VEX_SIMD_66);
+  } else {
+    emit_simd_arith(0x6C, dst, src, VEX_SIMD_66);
+  }
 }
 
 void Assembler::push(int32_t imm32) {
@@ -3396,8 +3457,8 @@
 void Assembler::sqrtsd(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_T1S;
-    input_size_in_bits = EVEX_64bit;
+    _tuple_type = EVEX_T1S;
+    _input_size_in_bits = EVEX_64bit;
     emit_simd_arith_q(0x51, dst, src, VEX_SIMD_F2);
   } else {
     emit_simd_arith(0x51, dst, src, VEX_SIMD_F2);
@@ -3416,8 +3477,8 @@
 void Assembler::sqrtss(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_T1S;
-    input_size_in_bits = EVEX_32bit;
+    _tuple_type = EVEX_T1S;
+    _input_size_in_bits = EVEX_32bit;
   }
   emit_simd_arith(0x51, dst, src, VEX_SIMD_F3);
 }
@@ -3479,10 +3540,14 @@
 void Assembler::subsd(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_T1S;
-    input_size_in_bits = EVEX_64bit;
-  }
-  emit_simd_arith_q(0x5C, dst, src, VEX_SIMD_F2);
+    _tuple_type = EVEX_T1S;
+    _input_size_in_bits = EVEX_64bit;
+  }
+  if (VM_Version::supports_evex()) {
+    emit_simd_arith_q(0x5C, dst, src, VEX_SIMD_F2);
+  } else {
+    emit_simd_arith(0x5C, dst, src, VEX_SIMD_F2);
+  }
 }
 
 void Assembler::subss(XMMRegister dst, XMMRegister src) {
@@ -3493,8 +3558,8 @@
 void Assembler::subss(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_T1S;
-    input_size_in_bits = EVEX_32bit;
+    _tuple_type = EVEX_T1S;
+    _input_size_in_bits = EVEX_32bit;
   }
   emit_simd_arith(0x5C, dst, src, VEX_SIMD_F3);
 }
@@ -3553,9 +3618,9 @@
 void Assembler::ucomisd(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_T1S;
-    input_size_in_bits = EVEX_64bit;
-    emit_simd_arith_nonds_q(0x2E, dst, src, VEX_SIMD_66, true);
+    _tuple_type = EVEX_T1S;
+    _input_size_in_bits = EVEX_64bit;
+    emit_simd_arith_nonds_q(0x2E, dst, src, VEX_SIMD_66, /* no_mask_reg */ true);
   } else {
     emit_simd_arith_nonds(0x2E, dst, src, VEX_SIMD_66);
   }
@@ -3564,7 +3629,7 @@
 void Assembler::ucomisd(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   if (VM_Version::supports_evex()) {
-    emit_simd_arith_nonds_q(0x2E, dst, src, VEX_SIMD_66, true);
+    emit_simd_arith_nonds_q(0x2E, dst, src, VEX_SIMD_66, /* no_mask_reg */ true);
   } else {
     emit_simd_arith_nonds(0x2E, dst, src, VEX_SIMD_66);
   }
@@ -3573,15 +3638,15 @@
 void Assembler::ucomiss(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_T1S;
-    input_size_in_bits = EVEX_32bit;
-  }
-  emit_simd_arith_nonds(0x2E, dst, src, VEX_SIMD_NONE, true);
+    _tuple_type = EVEX_T1S;
+    _input_size_in_bits = EVEX_32bit;
+  }
+  emit_simd_arith_nonds(0x2E, dst, src, VEX_SIMD_NONE, /* no_mask_reg */ true);
 }
 
 void Assembler::ucomiss(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
-  emit_simd_arith_nonds(0x2E, dst, src, VEX_SIMD_NONE, true);
+  emit_simd_arith_nonds(0x2E, dst, src, VEX_SIMD_NONE, /* no_mask_reg */ true);
 }
 
 void Assembler::xabort(int8_t imm8) {
@@ -3664,8 +3729,8 @@
 void Assembler::vaddsd(XMMRegister dst, XMMRegister nds, Address src) {
   assert(VM_Version::supports_avx(), "");
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_T1S;
-    input_size_in_bits = EVEX_64bit;
+    _tuple_type = EVEX_T1S;
+    _input_size_in_bits = EVEX_64bit;
     emit_vex_arith_q(0x58, dst, nds, src, VEX_SIMD_F2, AVX_128bit);
   } else {
     emit_vex_arith(0x58, dst, nds, src, VEX_SIMD_F2, AVX_128bit);
@@ -3684,8 +3749,8 @@
 void Assembler::vaddss(XMMRegister dst, XMMRegister nds, Address src) {
   assert(VM_Version::supports_avx(), "");
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_T1S;
-    input_size_in_bits = EVEX_32bit;
+    _tuple_type = EVEX_T1S;
+    _input_size_in_bits = EVEX_32bit;
   }
   emit_vex_arith(0x58, dst, nds, src, VEX_SIMD_F3, AVX_128bit);
 }
@@ -3698,8 +3763,8 @@
 void Assembler::vdivsd(XMMRegister dst, XMMRegister nds, Address src) {
   assert(VM_Version::supports_avx(), "");
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_T1S;
-    input_size_in_bits = EVEX_64bit;
+    _tuple_type = EVEX_T1S;
+    _input_size_in_bits = EVEX_64bit;
     emit_vex_arith_q(0x5E, dst, nds, src, VEX_SIMD_F2, AVX_128bit);
   } else {
     emit_vex_arith(0x5E, dst, nds, src, VEX_SIMD_F2, AVX_128bit);
@@ -3718,8 +3783,8 @@
 void Assembler::vdivss(XMMRegister dst, XMMRegister nds, Address src) {
   assert(VM_Version::supports_avx(), "");
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_T1S;
-    input_size_in_bits = EVEX_32bit;
+    _tuple_type = EVEX_T1S;
+    _input_size_in_bits = EVEX_32bit;
   }
   emit_vex_arith(0x5E, dst, nds, src, VEX_SIMD_F3, AVX_128bit);
 }
@@ -3732,8 +3797,8 @@
 void Assembler::vmulsd(XMMRegister dst, XMMRegister nds, Address src) {
   assert(VM_Version::supports_avx(), "");
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_T1S;
-    input_size_in_bits = EVEX_64bit;
+    _tuple_type = EVEX_T1S;
+    _input_size_in_bits = EVEX_64bit;
     emit_vex_arith_q(0x59, dst, nds, src, VEX_SIMD_F2, AVX_128bit);
   } else {
     emit_vex_arith(0x59, dst, nds, src, VEX_SIMD_F2, AVX_128bit);
@@ -3752,8 +3817,8 @@
 void Assembler::vmulss(XMMRegister dst, XMMRegister nds, Address src) {
   assert(VM_Version::supports_avx(), "");
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_T1S;
-    input_size_in_bits = EVEX_32bit;
+    _tuple_type = EVEX_T1S;
+    _input_size_in_bits = EVEX_32bit;
   }
   emit_vex_arith(0x59, dst, nds, src, VEX_SIMD_F3, AVX_128bit);
 }
@@ -3766,8 +3831,8 @@
 void Assembler::vsubsd(XMMRegister dst, XMMRegister nds, Address src) {
   assert(VM_Version::supports_avx(), "");
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_T1S;
-    input_size_in_bits = EVEX_64bit;
+    _tuple_type = EVEX_T1S;
+    _input_size_in_bits = EVEX_64bit;
     emit_vex_arith_q(0x5C, dst, nds, src, VEX_SIMD_F2, AVX_128bit);
   } else {
     emit_vex_arith(0x5C, dst, nds, src, VEX_SIMD_F2, AVX_128bit);
@@ -3786,8 +3851,8 @@
 void Assembler::vsubss(XMMRegister dst, XMMRegister nds, Address src) {
   assert(VM_Version::supports_avx(), "");
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_T1S;
-    input_size_in_bits = EVEX_32bit;
+    _tuple_type = EVEX_T1S;
+    _input_size_in_bits = EVEX_32bit;
   }
   emit_vex_arith(0x5C, dst, nds, src, VEX_SIMD_F3, AVX_128bit);
 }
@@ -3802,6 +3867,7 @@
 // Float-point vector arithmetic
 
 void Assembler::addpd(XMMRegister dst, XMMRegister src) {
+  _instruction_uses_vl = true;
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   if (VM_Version::supports_evex()) {
     emit_simd_arith_q(0x58, dst, src, VEX_SIMD_66);
@@ -3811,11 +3877,13 @@
 }
 
 void Assembler::addps(XMMRegister dst, XMMRegister src) {
+  _instruction_uses_vl = true;
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   emit_simd_arith(0x58, dst, src, VEX_SIMD_NONE);
 }
 
 void Assembler::vaddpd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
+  _instruction_uses_vl = true;
   assert(VM_Version::supports_avx(), "");
   if (VM_Version::supports_evex()) {
     emit_vex_arith_q(0x58, dst, nds, src, VEX_SIMD_66, vector_len);
@@ -3825,15 +3893,17 @@
 }
 
 void Assembler::vaddps(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
+  _instruction_uses_vl = true;
   assert(VM_Version::supports_avx(), "");
   emit_vex_arith(0x58, dst, nds, src, VEX_SIMD_NONE, vector_len);
 }
 
 void Assembler::vaddpd(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
+  _instruction_uses_vl = true;
   assert(VM_Version::supports_avx(), "");
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_FV;
-    input_size_in_bits = EVEX_64bit;
+    _tuple_type = EVEX_FV;
+    _input_size_in_bits = EVEX_64bit;
     emit_vex_arith_q(0x58, dst, nds, src, VEX_SIMD_66, vector_len);
   } else {
     emit_vex_arith(0x58, dst, nds, src, VEX_SIMD_66, vector_len);
@@ -3841,15 +3911,17 @@
 }
 
 void Assembler::vaddps(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
+  _instruction_uses_vl = true;
   assert(VM_Version::supports_avx(), "");
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_FV;
-    input_size_in_bits = EVEX_32bit;
+    _tuple_type = EVEX_FV;
+    _input_size_in_bits = EVEX_32bit;
   }
   emit_vex_arith(0x58, dst, nds, src, VEX_SIMD_NONE, vector_len);
 }
 
 void Assembler::subpd(XMMRegister dst, XMMRegister src) {
+  _instruction_uses_vl = true;
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   if (VM_Version::supports_evex()) {
     emit_simd_arith_q(0x5C, dst, src, VEX_SIMD_66);
@@ -3859,11 +3931,13 @@
 }
 
 void Assembler::subps(XMMRegister dst, XMMRegister src) {
+  _instruction_uses_vl = true;
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   emit_simd_arith(0x5C, dst, src, VEX_SIMD_NONE);
 }
 
 void Assembler::vsubpd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
+  _instruction_uses_vl = true;
   assert(VM_Version::supports_avx(), "");
   if (VM_Version::supports_evex()) {
     emit_vex_arith_q(0x5C, dst, nds, src, VEX_SIMD_66, vector_len);
@@ -3873,15 +3947,17 @@
 }
 
 void Assembler::vsubps(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
+  _instruction_uses_vl = true;
   assert(VM_Version::supports_avx(), "");
   emit_vex_arith(0x5C, dst, nds, src, VEX_SIMD_NONE, vector_len);
 }
 
 void Assembler::vsubpd(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
+  _instruction_uses_vl = true;
   assert(VM_Version::supports_avx(), "");
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_FV;
-    input_size_in_bits = EVEX_64bit;
+    _tuple_type = EVEX_FV;
+    _input_size_in_bits = EVEX_64bit;
     emit_vex_arith_q(0x5C, dst, nds, src, VEX_SIMD_66, vector_len);
   } else {
     emit_vex_arith(0x5C, dst, nds, src, VEX_SIMD_66, vector_len);
@@ -3889,15 +3965,17 @@
 }
 
 void Assembler::vsubps(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
+  _instruction_uses_vl = true;
   assert(VM_Version::supports_avx(), "");
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_FV;
-    input_size_in_bits = EVEX_32bit;
+    _tuple_type = EVEX_FV;
+    _input_size_in_bits = EVEX_32bit;
   }
   emit_vex_arith(0x5C, dst, nds, src, VEX_SIMD_NONE, vector_len);
 }
 
 void Assembler::mulpd(XMMRegister dst, XMMRegister src) {
+  _instruction_uses_vl = true;
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   if (VM_Version::supports_evex()) {
     emit_simd_arith_q(0x59, dst, src, VEX_SIMD_66);
@@ -3907,11 +3985,13 @@
 }
 
 void Assembler::mulps(XMMRegister dst, XMMRegister src) {
+  _instruction_uses_vl = true;
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   emit_simd_arith(0x59, dst, src, VEX_SIMD_NONE);
 }
 
 void Assembler::vmulpd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
+  _instruction_uses_vl = true;
   assert(VM_Version::supports_avx(), "");
   if (VM_Version::supports_evex()) {
     emit_vex_arith_q(0x59, dst, nds, src, VEX_SIMD_66, vector_len);
@@ -3921,15 +4001,17 @@
 }
 
 void Assembler::vmulps(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
+  _instruction_uses_vl = true;
   assert(VM_Version::supports_avx(), "");
   emit_vex_arith(0x59, dst, nds, src, VEX_SIMD_NONE, vector_len);
 }
 
 void Assembler::vmulpd(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
+  _instruction_uses_vl = true;
   assert(VM_Version::supports_avx(), "");
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_FV;
-    input_size_in_bits = EVEX_64bit;
+    _tuple_type = EVEX_FV;
+    _input_size_in_bits = EVEX_64bit;
     emit_vex_arith_q(0x59, dst, nds, src, VEX_SIMD_66, vector_len);
   } else {
     emit_vex_arith(0x59, dst, nds, src, VEX_SIMD_66, vector_len);
@@ -3937,15 +4019,17 @@
 }
 
 void Assembler::vmulps(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
+  _instruction_uses_vl = true;
   assert(VM_Version::supports_avx(), "");
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_FV;
-    input_size_in_bits = EVEX_32bit;
+    _tuple_type = EVEX_FV;
+    _input_size_in_bits = EVEX_32bit;
   }
   emit_vex_arith(0x59, dst, nds, src, VEX_SIMD_NONE, vector_len);
 }
 
 void Assembler::divpd(XMMRegister dst, XMMRegister src) {
+  _instruction_uses_vl = true;
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   if (VM_Version::supports_evex()) {
     emit_simd_arith_q(0x5E, dst, src, VEX_SIMD_66);
@@ -3955,11 +4039,13 @@
 }
 
 void Assembler::divps(XMMRegister dst, XMMRegister src) {
+  _instruction_uses_vl = true;
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   emit_simd_arith(0x5E, dst, src, VEX_SIMD_NONE);
 }
 
 void Assembler::vdivpd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
+  _instruction_uses_vl = true;
   assert(VM_Version::supports_avx(), "");
   if (VM_Version::supports_evex()) {
     emit_vex_arith_q(0x5E, dst, nds, src, VEX_SIMD_66, vector_len);
@@ -3969,15 +4055,17 @@
 }
 
 void Assembler::vdivps(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
+  _instruction_uses_vl = true;
   assert(VM_Version::supports_avx(), "");
   emit_vex_arith(0x5E, dst, nds, src, VEX_SIMD_NONE, vector_len);
 }
 
 void Assembler::vdivpd(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
+  _instruction_uses_vl = true;
   assert(VM_Version::supports_avx(), "");
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_FV;
-    input_size_in_bits = EVEX_64bit;
+    _tuple_type = EVEX_FV;
+    _input_size_in_bits = EVEX_64bit;
     emit_vex_arith_q(0x5E, dst, nds, src, VEX_SIMD_66, vector_len);
   } else {
     emit_vex_arith(0x5E, dst, nds, src, VEX_SIMD_66, vector_len);
@@ -3985,164 +4073,178 @@
 }
 
 void Assembler::vdivps(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
+  _instruction_uses_vl = true;
+  assert(VM_Version::supports_avx(), "");
+  if (VM_Version::supports_evex()) {
+    _tuple_type = EVEX_FV;
+    _input_size_in_bits = EVEX_32bit;
+  }
+  emit_vex_arith(0x5E, dst, nds, src, VEX_SIMD_NONE, vector_len);
+}
+
+void Assembler::vsqrtpd(XMMRegister dst, XMMRegister src, int vector_len) {
+  _instruction_uses_vl = true;
   assert(VM_Version::supports_avx(), "");
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_FV;
-    input_size_in_bits = EVEX_32bit;
-  }
-  emit_vex_arith(0x5E, dst, nds, src, VEX_SIMD_NONE, vector_len);
+    emit_vex_arith_q(0x51, dst, xnoreg, src, VEX_SIMD_66, vector_len);
+  } else {
+    emit_vex_arith(0x51, dst, xnoreg, src, VEX_SIMD_66, vector_len);
+  }
+}
+
+void Assembler::vsqrtpd(XMMRegister dst, Address src, int vector_len) {
+  _instruction_uses_vl = true;
+  assert(VM_Version::supports_avx(), "");
+  if (VM_Version::supports_evex()) {
+    _tuple_type = EVEX_FV;
+    _input_size_in_bits = EVEX_64bit;
+    emit_vex_arith_q(0x51, dst, xnoreg, src, VEX_SIMD_66, vector_len);
+  } else {
+    emit_vex_arith(0x51, dst, xnoreg, src, VEX_SIMD_66, vector_len);
+  }
 }
 
 void Assembler::andpd(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  if (VM_Version::supports_evex() && VM_Version::supports_avx512dq()) {
+  if (VM_Version::supports_avx512dq()) {
     emit_simd_arith_q(0x54, dst, src, VEX_SIMD_66);
   } else {
-    emit_simd_arith(0x54, dst, src, VEX_SIMD_66, false, true);
+    emit_simd_arith(0x54, dst, src, VEX_SIMD_66, /* no_mask_reg */ false, /* legacy_mode */ true);
   }
 }
 
 void Assembler::andps(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
-  emit_simd_arith(0x54, dst, src, VEX_SIMD_NONE, false,
-                  (VM_Version::supports_avx512dq() == false));
+  emit_simd_arith(0x54, dst, src, VEX_SIMD_NONE, /* no_mask_reg */ false, /* legacy_mode */ _legacy_mode_dq);
 }
 
 void Assembler::andps(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_FV;
-    input_size_in_bits = EVEX_32bit;
-  }
-  emit_simd_arith(0x54, dst, src, VEX_SIMD_NONE,
-                  false, (VM_Version::supports_avx512dq() == false));
+    _tuple_type = EVEX_FV;
+    _input_size_in_bits = EVEX_32bit;
+  }
+  emit_simd_arith(0x54, dst, src, VEX_SIMD_NONE, /* no_mask_reg */ false, /* legacy_mode */ _legacy_mode_dq);
 }
 
 void Assembler::andpd(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  if (VM_Version::supports_evex() && VM_Version::supports_avx512dq()) {
-    tuple_type = EVEX_FV;
-    input_size_in_bits = EVEX_64bit;
+  if (VM_Version::supports_avx512dq()) {
+    _tuple_type = EVEX_FV;
+    _input_size_in_bits = EVEX_64bit;
     emit_simd_arith_q(0x54, dst, src, VEX_SIMD_66);
   } else {
-    emit_simd_arith(0x54, dst, src, VEX_SIMD_66, false, true);
+    emit_simd_arith(0x54, dst, src, VEX_SIMD_66, /* no_mask_reg */ false, /* legacy_mode */ true);
   }
 }
 
 void Assembler::vandpd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
   assert(VM_Version::supports_avx(), "");
-  if (VM_Version::supports_evex() && VM_Version::supports_avx512dq()) {
+  if (VM_Version::supports_avx512dq()) {
     emit_vex_arith_q(0x54, dst, nds, src, VEX_SIMD_66, vector_len);
   } else {
-    emit_vex_arith(0x54, dst, nds, src, VEX_SIMD_66, vector_len, true);
+    emit_vex_arith(0x54, dst, nds, src, VEX_SIMD_66, vector_len, /* no_mask_reg */ false, /* legacy_mode */ true);
   }
 }
 
 void Assembler::vandps(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
   assert(VM_Version::supports_avx(), "");
-  bool legacy_mode = (VM_Version::supports_avx512dq() == false);
-  emit_vex_arith(0x54, dst, nds, src, VEX_SIMD_NONE, vector_len, legacy_mode);
+  emit_vex_arith(0x54, dst, nds, src, VEX_SIMD_NONE, vector_len, /* no_mask_reg */ false,  /* legacy_mode */ _legacy_mode_dq);
 }
 
 void Assembler::vandpd(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
   assert(VM_Version::supports_avx(), "");
-  if (VM_Version::supports_evex() && VM_Version::supports_avx512dq()) {
-    tuple_type = EVEX_FV;
-    input_size_in_bits = EVEX_64bit;
+  if (VM_Version::supports_avx512dq()) {
+    _tuple_type = EVEX_FV;
+    _input_size_in_bits = EVEX_64bit;
     emit_vex_arith_q(0x54, dst, nds, src, VEX_SIMD_66, vector_len);
   } else {
-    emit_vex_arith(0x54, dst, nds, src, VEX_SIMD_66, vector_len, true);
+    emit_vex_arith(0x54, dst, nds, src, VEX_SIMD_66, vector_len, /* no_mask_reg */ false, /* legacy_mode */ true);
   }
 }
 
 void Assembler::vandps(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
   assert(VM_Version::supports_avx(), "");
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_FV;
-    input_size_in_bits = EVEX_32bit;
-  }
-  emit_vex_arith(0x54, dst, nds, src, VEX_SIMD_NONE, vector_len,
-                 (VM_Version::supports_avx512dq() == false));
+    _tuple_type = EVEX_FV;
+    _input_size_in_bits = EVEX_32bit;
+  }
+  emit_vex_arith(0x54, dst, nds, src, VEX_SIMD_NONE, vector_len, /* no_mask_reg */ false, /* legacy_mode */ _legacy_mode_dq);
 }
 
 void Assembler::xorpd(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  if (VM_Version::supports_evex() && VM_Version::supports_avx512dq()) {
+  if (VM_Version::supports_avx512dq()) {
     emit_simd_arith_q(0x57, dst, src, VEX_SIMD_66);
   } else {
-    emit_simd_arith(0x57, dst, src, VEX_SIMD_66, false, true);
+    emit_simd_arith(0x57, dst, src, VEX_SIMD_66, /* no_mask_reg */ false, /* legacy_mode */ true);
   }
 }
 
 void Assembler::xorps(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
-  emit_simd_arith(0x57, dst, src, VEX_SIMD_NONE,
-                  false, (VM_Version::supports_avx512dq() == false));
+  emit_simd_arith(0x57, dst, src, VEX_SIMD_NONE, /* no_mask_reg */ false, /* legacy_mode */ _legacy_mode_dq);
 }
 
 void Assembler::xorpd(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  if (VM_Version::supports_evex() && VM_Version::supports_avx512dq()) {
-    tuple_type = EVEX_FV;
-    input_size_in_bits = EVEX_64bit;
+  if (VM_Version::supports_avx512dq()) {
+    _tuple_type = EVEX_FV;
+    _input_size_in_bits = EVEX_64bit;
     emit_simd_arith_q(0x57, dst, src, VEX_SIMD_66);
   } else {
-    emit_simd_arith(0x57, dst, src, VEX_SIMD_66, false, true);
+    emit_simd_arith(0x57, dst, src, VEX_SIMD_66, /* no_mask_reg */ false, /* legacy_mode */ true);
   }
 }
 
 void Assembler::xorps(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_FV;
-    input_size_in_bits = EVEX_32bit;
-  }
-  emit_simd_arith(0x57, dst, src, VEX_SIMD_NONE, false,
-                  (VM_Version::supports_avx512dq() == false));
+    _tuple_type = EVEX_FV;
+    _input_size_in_bits = EVEX_32bit;
+  }
+  emit_simd_arith(0x57, dst, src, VEX_SIMD_NONE, /* no_mask_reg */ false, /* legacy_mode */ _legacy_mode_dq);
 }
 
 void Assembler::vxorpd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
   assert(VM_Version::supports_avx(), "");
-  if (VM_Version::supports_evex() && VM_Version::supports_avx512dq()) {
+  if (VM_Version::supports_avx512dq()) {
     emit_vex_arith_q(0x57, dst, nds, src, VEX_SIMD_66, vector_len);
   } else {
-    emit_vex_arith(0x57, dst, nds, src, VEX_SIMD_66, vector_len, true);
+    emit_vex_arith(0x57, dst, nds, src, VEX_SIMD_66, vector_len, /* no_mask_reg */ false, /* legacy_mode */ true);
   }
 }
 
 void Assembler::vxorps(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
   assert(VM_Version::supports_avx(), "");
-  emit_vex_arith(0x57, dst, nds, src, VEX_SIMD_NONE, vector_len,
-                 (VM_Version::supports_avx512dq() == false));
+  emit_vex_arith(0x57, dst, nds, src, VEX_SIMD_NONE, vector_len, /* no_mask_reg */ false, /* legacy_mode */ _legacy_mode_dq);
 }
 
 void Assembler::vxorpd(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
   assert(VM_Version::supports_avx(), "");
-  if (VM_Version::supports_evex() && VM_Version::supports_avx512dq()) {
-    tuple_type = EVEX_FV;
-    input_size_in_bits = EVEX_64bit;
+  if (VM_Version::supports_avx512dq()) {
+    _tuple_type = EVEX_FV;
+    _input_size_in_bits = EVEX_64bit;
     emit_vex_arith_q(0x57, dst, nds, src, VEX_SIMD_66, vector_len);
   } else {
-    emit_vex_arith(0x57, dst, nds, src, VEX_SIMD_66, vector_len, true);
+    emit_vex_arith(0x57, dst, nds, src, VEX_SIMD_66, vector_len, /* no_mask_reg */ false, /* legacy_mode */ true);
   }
 }
 
 void Assembler::vxorps(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
   assert(VM_Version::supports_avx(), "");
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_FV;
-    input_size_in_bits = EVEX_32bit;
-  }
-  emit_vex_arith(0x57, dst, nds, src, VEX_SIMD_NONE, vector_len,
-                 (VM_Version::supports_avx512dq() == false));
+    _tuple_type = EVEX_FV;
+    _input_size_in_bits = EVEX_32bit;
+  }
+  emit_vex_arith(0x57, dst, nds, src, VEX_SIMD_NONE, vector_len, /* no_mask_reg */ false, /* legacy_mode */ _legacy_mode_dq);
 }
 
 // Integer vector arithmetic
 void Assembler::vphaddw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
   assert(VM_Version::supports_avx() && (vector_len == 0) ||
          VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
-  int encode = vex_prefix_and_encode(dst, nds, src, VEX_SIMD_66, vector_len,
-                                     VEX_OPCODE_0F_38, true, false);
+  int encode = vex_prefix_and_encode(dst, nds, src, VEX_SIMD_66, vector_len, VEX_OPCODE_0F_38, /* legacy_mode */ true);
   emit_int8(0x01);
   emit_int8((unsigned char)(0xC0 | encode));
 }
@@ -4150,28 +4252,29 @@
 void Assembler::vphaddd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
   assert(VM_Version::supports_avx() && (vector_len == 0) ||
          VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
-  int encode = vex_prefix_and_encode(dst, nds, src, VEX_SIMD_66, vector_len,
-                                     VEX_OPCODE_0F_38, true, false);
+  int encode = vex_prefix_and_encode(dst, nds, src, VEX_SIMD_66, vector_len, VEX_OPCODE_0F_38, /* legacy_mode */ true);
   emit_int8(0x02);
   emit_int8((unsigned char)(0xC0 | encode));
 }
 
 void Assembler::paddb(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  emit_simd_arith(0xFC, dst, src, VEX_SIMD_66);
+  emit_simd_arith(0xFC, dst, src, VEX_SIMD_66, /* no_mask_reg */ false, /* legacy_mode */ _legacy_mode_bw);
 }
 
 void Assembler::paddw(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  emit_simd_arith(0xFD, dst, src, VEX_SIMD_66);
+  emit_simd_arith(0xFD, dst, src, VEX_SIMD_66, /* no_mask_reg */ false, /* legacy_mode */ _legacy_mode_bw);
 }
 
 void Assembler::paddd(XMMRegister dst, XMMRegister src) {
+  _instruction_uses_vl = true;
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   emit_simd_arith(0xFE, dst, src, VEX_SIMD_66);
 }
 
 void Assembler::paddq(XMMRegister dst, XMMRegister src) {
+  _instruction_uses_vl = true;
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   if (VM_Version::supports_evex()) {
     emit_simd_arith_q(0xD4, dst, src, VEX_SIMD_66);
@@ -4182,38 +4285,38 @@
 
 void Assembler::phaddw(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse3(), ""));
-  int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, false,
-                                      VEX_OPCODE_0F_38, false, AVX_128bit, true);
+  int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, /* no_mask_reg */ false,
+                                      VEX_OPCODE_0F_38, /* rex_w */ false, AVX_128bit, /* legacy_mode */ true);
   emit_int8(0x01);
   emit_int8((unsigned char)(0xC0 | encode));
 }
 
 void Assembler::phaddd(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse3(), ""));
-  int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, false,
-                                      VEX_OPCODE_0F_38, false, AVX_128bit, true);
+  int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, /* no_mask_reg */ false,
+                                      VEX_OPCODE_0F_38, /* rex_w */ false, AVX_128bit, /* legacy_mode */ true);
   emit_int8(0x02);
   emit_int8((unsigned char)(0xC0 | encode));
 }
 
 void Assembler::vpaddb(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
   assert(UseAVX > 0, "requires some form of AVX");
-  emit_vex_arith(0xFC, dst, nds, src, VEX_SIMD_66, vector_len,
-                 (VM_Version::supports_avx512bw() == false));
+  emit_vex_arith(0xFC, dst, nds, src, VEX_SIMD_66, vector_len, /* no_mask_reg */ false, /* legacy_mode */ _legacy_mode_bw);
 }
 
 void Assembler::vpaddw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
   assert(UseAVX > 0, "requires some form of AVX");
-  emit_vex_arith(0xFD, dst, nds, src, VEX_SIMD_66, vector_len,
-                 (VM_Version::supports_avx512bw() == false));
+  emit_vex_arith(0xFD, dst, nds, src, VEX_SIMD_66, vector_len, /* no_mask_reg */ false, /* legacy_mode */ _legacy_mode_bw);
 }
 
 void Assembler::vpaddd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
+  _instruction_uses_vl = true;
   assert(UseAVX > 0, "requires some form of AVX");
   emit_vex_arith(0xFE, dst, nds, src, VEX_SIMD_66, vector_len);
 }
 
 void Assembler::vpaddq(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
+  _instruction_uses_vl = true;
   assert(UseAVX > 0, "requires some form of AVX");
   if (VM_Version::supports_evex()) {
     emit_vex_arith_q(0xD4, dst, nds, src, VEX_SIMD_66, vector_len);
@@ -4225,33 +4328,35 @@
 void Assembler::vpaddb(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
   assert(UseAVX > 0, "requires some form of AVX");
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_FVM;
-  }
-  emit_vex_arith(0xFC, dst, nds, src, VEX_SIMD_66, vector_len);
+    _tuple_type = EVEX_FVM;
+  }
+  emit_vex_arith(0xFC, dst, nds, src, VEX_SIMD_66, vector_len, /* no_mask_reg */ false, /* legacy_mode */ _legacy_mode_bw);
 }
 
 void Assembler::vpaddw(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
   assert(UseAVX > 0, "requires some form of AVX");
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_FVM;
-  }
-  emit_vex_arith(0xFD, dst, nds, src, VEX_SIMD_66, vector_len);
+    _tuple_type = EVEX_FVM;
+  }
+  emit_vex_arith(0xFD, dst, nds, src, VEX_SIMD_66, vector_len, /* no_mask_reg */ false, /* legacy_mode */ _legacy_mode_bw);
 }
 
 void Assembler::vpaddd(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
+  _instruction_uses_vl = true;
   assert(UseAVX > 0, "requires some form of AVX");
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_FV;
-    input_size_in_bits = EVEX_32bit;
+    _tuple_type = EVEX_FV;
+    _input_size_in_bits = EVEX_32bit;
   }
   emit_vex_arith(0xFE, dst, nds, src, VEX_SIMD_66, vector_len);
 }
 
 void Assembler::vpaddq(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
+  _instruction_uses_vl = true;
   assert(UseAVX > 0, "requires some form of AVX");
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_FV;
-    input_size_in_bits = EVEX_64bit;
+    _tuple_type = EVEX_FV;
+    _input_size_in_bits = EVEX_64bit;
     emit_vex_arith_q(0xD4, dst, nds, src, VEX_SIMD_66, vector_len);
   } else {
     emit_vex_arith(0xD4, dst, nds, src, VEX_SIMD_66, vector_len);
@@ -4260,20 +4365,22 @@
 
 void Assembler::psubb(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  emit_simd_arith(0xF8, dst, src, VEX_SIMD_66);
+  emit_simd_arith(0xF8, dst, src, VEX_SIMD_66, /* no_mask_reg */ false, /* legacy_mode */ _legacy_mode_bw);
 }
 
 void Assembler::psubw(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  emit_simd_arith(0xF9, dst, src, VEX_SIMD_66);
+  emit_simd_arith(0xF9, dst, src, VEX_SIMD_66, /* no_mask_reg */ false, /* legacy_mode */ _legacy_mode_bw);
 }
 
 void Assembler::psubd(XMMRegister dst, XMMRegister src) {
+  _instruction_uses_vl = true;
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   emit_simd_arith(0xFA, dst, src, VEX_SIMD_66);
 }
 
 void Assembler::psubq(XMMRegister dst, XMMRegister src) {
+  _instruction_uses_vl = true;
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   if (VM_Version::supports_evex()) {
     emit_simd_arith_q(0xFB, dst, src, VEX_SIMD_66);
@@ -4284,22 +4391,22 @@
 
 void Assembler::vpsubb(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
   assert(UseAVX > 0, "requires some form of AVX");
-  emit_vex_arith(0xF8, dst, nds, src, VEX_SIMD_66, vector_len,
-                 (VM_Version::supports_avx512bw() == false));
+  emit_vex_arith(0xF8, dst, nds, src, VEX_SIMD_66, vector_len, /* no_mask_reg */ false, /* legacy_mode */ _legacy_mode_bw);
 }
 
 void Assembler::vpsubw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
   assert(UseAVX > 0, "requires some form of AVX");
-  emit_vex_arith(0xF9, dst, nds, src, VEX_SIMD_66, vector_len,
-                 (VM_Version::supports_avx512bw() == false));
+  emit_vex_arith(0xF9, dst, nds, src, VEX_SIMD_66, vector_len, /* no_mask_reg */ false, /* legacy_mode */ _legacy_mode_bw);
 }
 
 void Assembler::vpsubd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
+  _instruction_uses_vl = true;
   assert(UseAVX > 0, "requires some form of AVX");
   emit_vex_arith(0xFA, dst, nds, src, VEX_SIMD_66, vector_len);
 }
 
 void Assembler::vpsubq(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
+  _instruction_uses_vl = true;
   assert(UseAVX > 0, "requires some form of AVX");
   if (VM_Version::supports_evex()) {
     emit_vex_arith_q(0xFB, dst, nds, src, VEX_SIMD_66, vector_len);
@@ -4311,35 +4418,35 @@
 void Assembler::vpsubb(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
   assert(UseAVX > 0, "requires some form of AVX");
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_FVM;
-  }
-  emit_vex_arith(0xF8, dst, nds, src, VEX_SIMD_66, vector_len,
-                 (VM_Version::supports_avx512bw() == false));
+    _tuple_type = EVEX_FVM;
+  }
+  emit_vex_arith(0xF8, dst, nds, src, VEX_SIMD_66, vector_len, /* no_mask_reg */ false, /* legacy_mode */ _legacy_mode_bw);
 }
 
 void Assembler::vpsubw(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
   assert(UseAVX > 0, "requires some form of AVX");
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_FVM;
-  }
-  emit_vex_arith(0xF9, dst, nds, src, VEX_SIMD_66, vector_len,
-                 (VM_Version::supports_avx512bw() == false));
+    _tuple_type = EVEX_FVM;
+  }
+  emit_vex_arith(0xF9, dst, nds, src, VEX_SIMD_66, vector_len, /* no_mask_reg */ false, /* legacy_mode */ _legacy_mode_bw);
 }
 
 void Assembler::vpsubd(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
+  _instruction_uses_vl = true;
   assert(UseAVX > 0, "requires some form of AVX");
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_FV;
-    input_size_in_bits = EVEX_32bit;
+    _tuple_type = EVEX_FV;
+    _input_size_in_bits = EVEX_32bit;
   }
   emit_vex_arith(0xFA, dst, nds, src, VEX_SIMD_66, vector_len);
 }
 
 void Assembler::vpsubq(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
+  _instruction_uses_vl = true;
   assert(UseAVX > 0, "requires some form of AVX");
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_FV;
-    input_size_in_bits = EVEX_64bit;
+    _tuple_type = EVEX_FV;
+    _input_size_in_bits = EVEX_64bit;
     emit_vex_arith_q(0xFB, dst, nds, src, VEX_SIMD_66, vector_len);
   } else {
     emit_vex_arith(0xFB, dst, nds, src, VEX_SIMD_66, vector_len);
@@ -4348,28 +4455,27 @@
 
 void Assembler::pmullw(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  emit_simd_arith(0xD5, dst, src, VEX_SIMD_66,
-                  (VM_Version::supports_avx512bw() == false));
+  emit_simd_arith(0xD5, dst, src, VEX_SIMD_66, /* no_mask_reg */ false, /* legacy_mode */ _legacy_mode_bw);
 }
 
 void Assembler::pmulld(XMMRegister dst, XMMRegister src) {
+  _instruction_uses_vl = true;
   assert(VM_Version::supports_sse4_1(), "");
   int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66,
-                                      false, VEX_OPCODE_0F_38);
+                                      /* no_mask_reg */ false, VEX_OPCODE_0F_38);
   emit_int8(0x40);
   emit_int8((unsigned char)(0xC0 | encode));
 }
 
 void Assembler::vpmullw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
   assert(UseAVX > 0, "requires some form of AVX");
-  emit_vex_arith(0xD5, dst, nds, src, VEX_SIMD_66, vector_len,
-                 (VM_Version::supports_avx512bw() == false));
+  emit_vex_arith(0xD5, dst, nds, src, VEX_SIMD_66, vector_len, /* no_mask_reg */ false, /* legacy_mode */ _legacy_mode_bw);
 }
 
 void Assembler::vpmulld(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
+  _instruction_uses_vl = true;
   assert(UseAVX > 0, "requires some form of AVX");
-  int encode = vex_prefix_and_encode(dst, nds, src, VEX_SIMD_66,
-                                     vector_len, VEX_OPCODE_0F_38);
+  int encode = vex_prefix_and_encode(dst, nds, src, VEX_SIMD_66, vector_len, VEX_OPCODE_0F_38);
   emit_int8(0x40);
   emit_int8((unsigned char)(0xC0 | encode));
 }
@@ -4379,8 +4485,8 @@
   int src_enc = src->encoding();
   int dst_enc = dst->encoding();
   int nds_enc = nds->is_valid() ? nds->encoding() : 0;
-  int encode = vex_prefix_and_encode(dst_enc, nds_enc, src_enc, VEX_SIMD_66,
-                                     VEX_OPCODE_0F_38, true, vector_len, false, false);
+  int encode = vex_prefix_and_encode(dst_enc, nds_enc, src_enc, VEX_SIMD_66, VEX_OPCODE_0F_38,
+                                     /* vex_w */ true, vector_len, /* legacy_mode */ _legacy_mode_dq, /* no_mask_reg */ false);
   emit_int8(0x40);
   emit_int8((unsigned char)(0xC0 | encode));
 }
@@ -4388,22 +4494,23 @@
 void Assembler::vpmullw(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
   assert(UseAVX > 0, "requires some form of AVX");
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_FVM;
-  }
-  emit_vex_arith(0xD5, dst, nds, src, VEX_SIMD_66, vector_len);
+    _tuple_type = EVEX_FVM;
+  }
+  emit_vex_arith(0xD5, dst, nds, src, VEX_SIMD_66, vector_len, /* no_mask_reg */ false, /* legacy_mode */ _legacy_mode_bw);
 }
 
 void Assembler::vpmulld(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
+  _instruction_uses_vl = true;
   assert(UseAVX > 0, "requires some form of AVX");
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_FV;
-    input_size_in_bits = EVEX_32bit;
+    _tuple_type = EVEX_FV;
+    _input_size_in_bits = EVEX_32bit;
   }
   InstructionMark im(this);
   int dst_enc = dst->encoding();
   int nds_enc = nds->is_valid() ? nds->encoding() : 0;
   vex_prefix(src, nds_enc, dst_enc, VEX_SIMD_66,
-             VEX_OPCODE_0F_38, false, vector_len);
+             VEX_OPCODE_0F_38, /* vex_w */ false, vector_len);
   emit_int8(0x40);
   emit_operand(dst, src);
 }
@@ -4411,13 +4518,14 @@
 void Assembler::vpmullq(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
   assert(UseAVX > 0, "requires some form of AVX");
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_FV;
-    input_size_in_bits = EVEX_64bit;
+    _tuple_type = EVEX_FV;
+    _input_size_in_bits = EVEX_64bit;
   }
   InstructionMark im(this);
   int dst_enc = dst->encoding();
   int nds_enc = nds->is_valid() ? nds->encoding() : 0;
-  vex_prefix(src, nds_enc, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_38, true, vector_len);
+  vex_prefix(src, nds_enc, dst_enc, VEX_SIMD_66,
+             VEX_OPCODE_0F_38, /* vex_w */ true, vector_len, /* legacy_mode */ _legacy_mode_dq);
   emit_int8(0x40);
   emit_operand(dst, src);
 }
@@ -4426,26 +4534,28 @@
 void Assembler::psllw(XMMRegister dst, int shift) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   // XMM6 is for /6 encoding: 66 0F 71 /6 ib
-  int encode = simd_prefix_and_encode(xmm6, dst, dst, VEX_SIMD_66, false, VEX_OPCODE_0F,
-                                      false, AVX_128bit, (VM_Version::supports_avx512bw() == false));
+  int encode = simd_prefix_and_encode(xmm6, dst, dst, VEX_SIMD_66, /* no_mask_reg */ false, VEX_OPCODE_0F,
+                                      /* rex_w */ false, AVX_128bit, /* legacy_mode */ _legacy_mode_bw);
   emit_int8(0x71);
   emit_int8((unsigned char)(0xC0 | encode));
   emit_int8(shift & 0xFF);
 }
 
 void Assembler::pslld(XMMRegister dst, int shift) {
+  _instruction_uses_vl = true;
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   // XMM6 is for /6 encoding: 66 0F 72 /6 ib
-  int encode = simd_prefix_and_encode(xmm6, dst, dst, VEX_SIMD_66, false);
+  int encode = simd_prefix_and_encode(xmm6, dst, dst, VEX_SIMD_66, /* no_mask_reg */ false);
   emit_int8(0x72);
   emit_int8((unsigned char)(0xC0 | encode));
   emit_int8(shift & 0xFF);
 }
 
 void Assembler::psllq(XMMRegister dst, int shift) {
+  _instruction_uses_vl = true;
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   // XMM6 is for /6 encoding: 66 0F 73 /6 ib
-  int encode = simd_prefix_and_encode(xmm6, dst, dst, VEX_SIMD_66, false, VEX_OPCODE_0F, true);
+  int encode = simd_prefix_and_encode(xmm6, dst, dst, VEX_SIMD_66, /* no_mask_reg */ false, VEX_OPCODE_0F, /* rex_w */ true);
   emit_int8(0x73);
   emit_int8((unsigned char)(0xC0 | encode));
   emit_int8(shift & 0xFF);
@@ -4453,16 +4563,17 @@
 
 void Assembler::psllw(XMMRegister dst, XMMRegister shift) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  emit_simd_arith(0xF1, dst, shift, VEX_SIMD_66, false,
-                  (VM_Version::supports_avx512bw() == false));
+  emit_simd_arith(0xF1, dst, shift, VEX_SIMD_66, /* no_mask_reg */ false, /* legacy_mode */ _legacy_mode_bw);
 }
 
 void Assembler::pslld(XMMRegister dst, XMMRegister shift) {
+  _instruction_uses_vl = true;
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   emit_simd_arith(0xF2, dst, shift, VEX_SIMD_66);
 }
 
 void Assembler::psllq(XMMRegister dst, XMMRegister shift) {
+  _instruction_uses_vl = true;
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   if (VM_Version::supports_evex()) {
     emit_simd_arith_q(0xF3, dst, shift, VEX_SIMD_66);
@@ -4474,12 +4585,12 @@
 void Assembler::vpsllw(XMMRegister dst, XMMRegister src, int shift, int vector_len) {
   assert(UseAVX > 0, "requires some form of AVX");
   // XMM6 is for /6 encoding: 66 0F 71 /6 ib
-  emit_vex_arith(0x71, xmm6, dst, src, VEX_SIMD_66, vector_len,
-                 (VM_Version::supports_avx512bw() == false));
+  emit_vex_arith(0x71, xmm6, dst, src, VEX_SIMD_66, vector_len, /* no_mask_reg */ false, /* legacy_mode */ _legacy_mode_bw);
   emit_int8(shift & 0xFF);
 }
 
 void Assembler::vpslld(XMMRegister dst, XMMRegister src, int shift, int vector_len) {
+  _instruction_uses_vl = true;
   assert(UseAVX > 0, "requires some form of AVX");
   // XMM6 is for /6 encoding: 66 0F 72 /6 ib
   emit_vex_arith(0x72, xmm6, dst, src, VEX_SIMD_66, vector_len);
@@ -4487,6 +4598,7 @@
 }
 
 void Assembler::vpsllq(XMMRegister dst, XMMRegister src, int shift, int vector_len) {
+  _instruction_uses_vl = true;
   assert(UseAVX > 0, "requires some form of AVX");
   // XMM6 is for /6 encoding: 66 0F 73 /6 ib
   if (VM_Version::supports_evex()) {
@@ -4499,16 +4611,17 @@
 
 void Assembler::vpsllw(XMMRegister dst, XMMRegister src, XMMRegister shift, int vector_len) {
   assert(UseAVX > 0, "requires some form of AVX");
-  emit_vex_arith(0xF1, dst, src, shift, VEX_SIMD_66, vector_len,
-                 (VM_Version::supports_avx512bw() == false));
+  emit_vex_arith(0xF1, dst, src, shift, VEX_SIMD_66, vector_len, /* no_mask_reg */ false, /* legacy_mode */ _legacy_mode_bw);
 }
 
 void Assembler::vpslld(XMMRegister dst, XMMRegister src, XMMRegister shift, int vector_len) {
+  _instruction_uses_vl = true;
   assert(UseAVX > 0, "requires some form of AVX");
   emit_vex_arith(0xF2, dst, src, shift, VEX_SIMD_66, vector_len);
 }
 
 void Assembler::vpsllq(XMMRegister dst, XMMRegister src, XMMRegister shift, int vector_len) {
+  _instruction_uses_vl = true;
   assert(UseAVX > 0, "requires some form of AVX");
   if (VM_Version::supports_evex()) {
     emit_vex_arith_q(0xF3, dst, src, shift, VEX_SIMD_66, vector_len);
@@ -4521,33 +4634,31 @@
 void Assembler::psrlw(XMMRegister dst, int shift) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   // XMM2 is for /2 encoding: 66 0F 71 /2 ib
-  int encode = simd_prefix_and_encode(xmm2, dst, dst, VEX_SIMD_66, false, VEX_OPCODE_0F,
-                                      (VM_Version::supports_avx512bw() == false));
+  int encode = simd_prefix_and_encode(xmm2, dst, dst, VEX_SIMD_66, /* no_mask_reg */ false,
+                                      VEX_OPCODE_0F, /* rex_w */ false, AVX_128bit, /* legacy_mode */ _legacy_mode_bw);
   emit_int8(0x71);
   emit_int8((unsigned char)(0xC0 | encode));
   emit_int8(shift & 0xFF);
 }
 
 void Assembler::psrld(XMMRegister dst, int shift) {
+  _instruction_uses_vl = true;
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   // XMM2 is for /2 encoding: 66 0F 72 /2 ib
-  int encode = simd_prefix_and_encode(xmm2, dst, dst, VEX_SIMD_66, false);
+  int encode = simd_prefix_and_encode(xmm2, dst, dst, VEX_SIMD_66, /* no_mask_reg */ false);
   emit_int8(0x72);
   emit_int8((unsigned char)(0xC0 | encode));
   emit_int8(shift & 0xFF);
 }
 
 void Assembler::psrlq(XMMRegister dst, int shift) {
+  _instruction_uses_vl = true;
   // Do not confuse it with psrldq SSE2 instruction which
   // shifts 128 bit value in xmm register by number of bytes.
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   // XMM2 is for /2 encoding: 66 0F 73 /2 ib
-  int encode = 0;
-  if (VM_Version::supports_evex() && VM_Version::supports_avx512bw()) {
-    encode = simd_prefix_and_encode(xmm2, dst, dst, VEX_SIMD_66, true, VEX_OPCODE_0F, false);
-  } else {
-    encode = simd_prefix_and_encode(xmm2, dst, dst, VEX_SIMD_66, false, VEX_OPCODE_0F, true);
-  }
+  int encode = simd_prefix_and_encode(xmm2, dst, dst, VEX_SIMD_66, /* no_mask_reg */ false,
+                                      VEX_OPCODE_0F, /* rex_w */ VM_Version::supports_evex());
   emit_int8(0x73);
   emit_int8((unsigned char)(0xC0 | encode));
   emit_int8(shift & 0xFF);
@@ -4555,16 +4666,17 @@
 
 void Assembler::psrlw(XMMRegister dst, XMMRegister shift) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  emit_simd_arith(0xD1, dst, shift, VEX_SIMD_66, false,
-                  (VM_Version::supports_avx512bw() == false));
+  emit_simd_arith(0xD1, dst, shift, VEX_SIMD_66, /* no_mask_reg */ false, /* legacy_mode */ _legacy_mode_bw);
 }
 
 void Assembler::psrld(XMMRegister dst, XMMRegister shift) {
+  _instruction_uses_vl = true;
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   emit_simd_arith(0xD2, dst, shift, VEX_SIMD_66);
 }
 
 void Assembler::psrlq(XMMRegister dst, XMMRegister shift) {
+  _instruction_uses_vl = true;
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   if (VM_Version::supports_evex()) {
     emit_simd_arith_q(0xD3, dst, shift, VEX_SIMD_66);
@@ -4575,20 +4687,21 @@
 
 void Assembler::vpsrlw(XMMRegister dst, XMMRegister src, int shift, int vector_len) {
   assert(UseAVX > 0, "requires some form of AVX");
-  // XMM2 is for /2 encoding: 66 0F 73 /2 ib
-  emit_vex_arith(0x71, xmm2, dst, src, VEX_SIMD_66, vector_len,
-                 (VM_Version::supports_avx512bw() == false));
+  // XMM2 is for /2 encoding: 66 0F 71 /2 ib
+  emit_vex_arith(0x71, xmm2, dst, src, VEX_SIMD_66, vector_len, /* no_mask_reg */ false, /* legacy_mode */ _legacy_mode_bw);
   emit_int8(shift & 0xFF);
 }
 
 void Assembler::vpsrld(XMMRegister dst, XMMRegister src, int shift, int vector_len) {
+  _instruction_uses_vl = true;
   assert(UseAVX > 0, "requires some form of AVX");
-  // XMM2 is for /2 encoding: 66 0F 73 /2 ib
+  // XMM2 is for /2 encoding: 66 0F 72 /2 ib
   emit_vex_arith(0x72, xmm2, dst, src, VEX_SIMD_66, vector_len);
   emit_int8(shift & 0xFF);
 }
 
 void Assembler::vpsrlq(XMMRegister dst, XMMRegister src, int shift, int vector_len) {
+  _instruction_uses_vl = true;
   assert(UseAVX > 0, "requires some form of AVX");
   // XMM2 is for /2 encoding: 66 0F 73 /2 ib
   if (VM_Version::supports_evex()) {
@@ -4601,16 +4714,17 @@
 
 void Assembler::vpsrlw(XMMRegister dst, XMMRegister src, XMMRegister shift, int vector_len) {
   assert(UseAVX > 0, "requires some form of AVX");
-  emit_vex_arith(0xD1, dst, src, shift, VEX_SIMD_66, vector_len,
-                 (VM_Version::supports_avx512bw() == false));
+  emit_vex_arith(0xD1, dst, src, shift, VEX_SIMD_66, vector_len, /* no_mask_reg */ false, /* legacy_mode */ _legacy_mode_bw);
 }
 
 void Assembler::vpsrld(XMMRegister dst, XMMRegister src, XMMRegister shift, int vector_len) {
+  _instruction_uses_vl = true;
   assert(UseAVX > 0, "requires some form of AVX");
   emit_vex_arith(0xD2, dst, src, shift, VEX_SIMD_66, vector_len);
 }
 
 void Assembler::vpsrlq(XMMRegister dst, XMMRegister src, XMMRegister shift, int vector_len) {
+  _instruction_uses_vl = true;
   assert(UseAVX > 0, "requires some form of AVX");
   if (VM_Version::supports_evex()) {
     emit_vex_arith_q(0xD3, dst, src, shift, VEX_SIMD_66, vector_len);
@@ -4623,17 +4737,18 @@
 void Assembler::psraw(XMMRegister dst, int shift) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   // XMM4 is for /4 encoding: 66 0F 71 /4 ib
-  int encode = simd_prefix_and_encode(xmm4, dst, dst, VEX_SIMD_66, false, VEX_OPCODE_0F,
-                                      (VM_Version::supports_avx512bw() == false));
+  int encode = simd_prefix_and_encode(xmm4, dst, dst, VEX_SIMD_66, /* no_mask_reg */ false,
+                                      VEX_OPCODE_0F, /* rex_w */ false, AVX_128bit, /* legacy_mode */ _legacy_mode_bw);
   emit_int8(0x71);
   emit_int8((unsigned char)(0xC0 | encode));
   emit_int8(shift & 0xFF);
 }
 
 void Assembler::psrad(XMMRegister dst, int shift) {
+  _instruction_uses_vl = true;
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   // XMM4 is for /4 encoding: 66 0F 72 /4 ib
-  int encode = simd_prefix_and_encode(xmm4, dst, dst, VEX_SIMD_66, false);
+  int encode = simd_prefix_and_encode(xmm4, dst, dst, VEX_SIMD_66, /* no_mask_reg */ false);
   emit_int8(0x72);
   emit_int8((unsigned char)(0xC0 | encode));
   emit_int8(shift & 0xFF);
@@ -4641,11 +4756,11 @@
 
 void Assembler::psraw(XMMRegister dst, XMMRegister shift) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  emit_simd_arith(0xE1, dst, shift, VEX_SIMD_66,
-                  (VM_Version::supports_avx512bw() == false));
+  emit_simd_arith(0xE1, dst, shift, VEX_SIMD_66, /* no_mask_reg */ false, /* legacy_mode */ _legacy_mode_bw);
 }
 
 void Assembler::psrad(XMMRegister dst, XMMRegister shift) {
+  _instruction_uses_vl = true;
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   emit_simd_arith(0xE2, dst, shift, VEX_SIMD_66);
 }
@@ -4653,12 +4768,12 @@
 void Assembler::vpsraw(XMMRegister dst, XMMRegister src, int shift, int vector_len) {
   assert(UseAVX > 0, "requires some form of AVX");
   // XMM4 is for /4 encoding: 66 0F 71 /4 ib
-  emit_vex_arith(0x71, xmm4, dst, src, VEX_SIMD_66, vector_len,
-                 (VM_Version::supports_avx512bw() == false));
+  emit_vex_arith(0x71, xmm4, dst, src, VEX_SIMD_66, vector_len, /* no_mask_reg */ false, /* legacy_mode */ _legacy_mode_bw);
   emit_int8(shift & 0xFF);
 }
 
 void Assembler::vpsrad(XMMRegister dst, XMMRegister src, int shift, int vector_len) {
+  _instruction_uses_vl = true;
   assert(UseAVX > 0, "requires some form of AVX");
   // XMM4 is for /4 encoding: 66 0F 71 /4 ib
   emit_vex_arith(0x72, xmm4, dst, src, VEX_SIMD_66, vector_len);
@@ -4667,11 +4782,11 @@
 
 void Assembler::vpsraw(XMMRegister dst, XMMRegister src, XMMRegister shift, int vector_len) {
   assert(UseAVX > 0, "requires some form of AVX");
-  emit_vex_arith(0xE1, dst, src, shift, VEX_SIMD_66, vector_len,
-                 (VM_Version::supports_avx512bw() == false));
+  emit_vex_arith(0xE1, dst, src, shift, VEX_SIMD_66, vector_len, /* no_mask_reg */ false, /* legacy_mode */ _legacy_mode_bw);
 }
 
 void Assembler::vpsrad(XMMRegister dst, XMMRegister src, XMMRegister shift, int vector_len) {
+  _instruction_uses_vl = true;
   assert(UseAVX > 0, "requires some form of AVX");
   emit_vex_arith(0xE2, dst, src, shift, VEX_SIMD_66, vector_len);
 }
@@ -4684,53 +4799,61 @@
 }
 
 void Assembler::vpand(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
+  _instruction_uses_vl = true;
   assert(UseAVX > 0, "requires some form of AVX");
   emit_vex_arith(0xDB, dst, nds, src, VEX_SIMD_66, vector_len);
 }
 
 void Assembler::vpand(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
+  _instruction_uses_vl = true;
   assert(UseAVX > 0, "requires some form of AVX");
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_FV;
-    input_size_in_bits = EVEX_32bit;
+    _tuple_type = EVEX_FV;
+    _input_size_in_bits = EVEX_32bit;
   }
   emit_vex_arith(0xDB, dst, nds, src, VEX_SIMD_66, vector_len);
 }
 
 void Assembler::por(XMMRegister dst, XMMRegister src) {
+  _instruction_uses_vl = true;
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   emit_simd_arith(0xEB, dst, src, VEX_SIMD_66);
 }
 
 void Assembler::vpor(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
+  _instruction_uses_vl = true;
   assert(UseAVX > 0, "requires some form of AVX");
   emit_vex_arith(0xEB, dst, nds, src, VEX_SIMD_66, vector_len);
 }
 
 void Assembler::vpor(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
+  _instruction_uses_vl = true;
   assert(UseAVX > 0, "requires some form of AVX");
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_FV;
-    input_size_in_bits = EVEX_32bit;
+    _tuple_type = EVEX_FV;
+    _input_size_in_bits = EVEX_32bit;
   }
   emit_vex_arith(0xEB, dst, nds, src, VEX_SIMD_66, vector_len);
 }
 
 void Assembler::pxor(XMMRegister dst, XMMRegister src) {
+  _instruction_uses_vl = true;
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   emit_simd_arith(0xEF, dst, src, VEX_SIMD_66);
 }
 
 void Assembler::vpxor(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
+  _instruction_uses_vl = true;
   assert(UseAVX > 0, "requires some form of AVX");
   emit_vex_arith(0xEF, dst, nds, src, VEX_SIMD_66, vector_len);
 }
 
 void Assembler::vpxor(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
+  _instruction_uses_vl = true;
   assert(UseAVX > 0, "requires some form of AVX");
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_FV;
-    input_size_in_bits = EVEX_32bit;
+    _tuple_type = EVEX_FV;
+    _input_size_in_bits = EVEX_32bit;
   }
   emit_vex_arith(0xEF, dst, nds, src, VEX_SIMD_66, vector_len);
 }
@@ -4739,6 +4862,9 @@
 void Assembler::vinsertf128h(XMMRegister dst, XMMRegister nds, XMMRegister src) {
   assert(VM_Version::supports_avx(), "");
   int vector_len = AVX_256bit;
+  if (VM_Version::supports_evex()) {
+    vector_len = AVX_512bit;
+  }
   int encode = vex_prefix_and_encode(dst, nds, src, VEX_SIMD_66, vector_len, VEX_OPCODE_0F_3A);
   emit_int8(0x18);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -4753,8 +4879,8 @@
   int src_enc = src->encoding();
   int dst_enc = dst->encoding();
   int nds_enc = nds->is_valid() ? nds->encoding() : 0;
-  int encode = vex_prefix_and_encode(dst_enc, nds_enc, src_enc, VEX_SIMD_66,
-                                     VEX_OPCODE_0F_3A, true, vector_len, false, false);
+  int encode = vex_prefix_and_encode(dst_enc, nds_enc, src_enc, VEX_SIMD_66, VEX_OPCODE_0F_3A,
+                                     /* vex_w */ true, vector_len, /* legacy_mode */ false, /* no_mask_reg */ false);
   emit_int8(0x1A);
   emit_int8((unsigned char)(0xC0 | encode));
   // 0x00 - insert into lower 256 bits
@@ -4763,35 +4889,70 @@
 }
 
 void Assembler::vinsertf64x4h(XMMRegister dst, Address src) {
-  assert(VM_Version::supports_avx(), "");
-  if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_T4;
-    input_size_in_bits = EVEX_64bit;
-  }
+  assert(VM_Version::supports_evex(), "");
+  _tuple_type = EVEX_T4;
+  _input_size_in_bits = EVEX_64bit;
   InstructionMark im(this);
   int vector_len = AVX_512bit;
   assert(dst != xnoreg, "sanity");
   int dst_enc = dst->encoding();
   // swap src<->dst for encoding
-  vex_prefix(src, dst_enc, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_3A, true, vector_len);
+  vex_prefix(src, dst_enc, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_3A, /* vex_w */ true, vector_len);
   emit_int8(0x1A);
   emit_operand(dst, src);
   // 0x01 - insert into upper 128 bits
   emit_int8(0x01);
 }
 
+void Assembler::vinsertf32x4h(XMMRegister dst, XMMRegister nds, XMMRegister src, int value) {
+  assert(VM_Version::supports_evex(), "");
+  int vector_len = AVX_512bit;
+  int src_enc = src->encoding();
+  int dst_enc = dst->encoding();
+  int nds_enc = nds->is_valid() ? nds->encoding() : 0;
+  int encode = vex_prefix_and_encode(dst_enc, nds_enc, src_enc, VEX_SIMD_66, VEX_OPCODE_0F_3A,
+                                     /* vex_w */ false, vector_len, /* legacy_mode */ false, /* no_mask_reg */ false);
+  emit_int8(0x18);
+  emit_int8((unsigned char)(0xC0 | encode));
+  // 0x00 - insert into q0 128 bits (0..127)
+  // 0x01 - insert into q1 128 bits (128..255)
+  // 0x02 - insert into q2 128 bits (256..383)
+  // 0x03 - insert into q3 128 bits (384..511)
+  emit_int8(value & 0x3);
+}
+
+void Assembler::vinsertf32x4h(XMMRegister dst, Address src, int value) {
+  assert(VM_Version::supports_evex(), "");
+  _tuple_type = EVEX_T4;
+  _input_size_in_bits = EVEX_32bit;
+  InstructionMark im(this);
+  int vector_len = AVX_512bit;
+  assert(dst != xnoreg, "sanity");
+  int dst_enc = dst->encoding();
+  // swap src<->dst for encoding
+  vex_prefix(src, dst_enc, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_3A, /* vex_w */ false, vector_len);
+  emit_int8(0x18);
+  emit_operand(dst, src);
+  // 0x00 - insert into q0 128 bits (0..127)
+  // 0x01 - insert into q1 128 bits (128..255)
+  // 0x02 - insert into q2 128 bits (256..383)
+  // 0x03 - insert into q3 128 bits (384..511)
+  emit_int8(value & 0x3);
+}
+
 void Assembler::vinsertf128h(XMMRegister dst, Address src) {
   assert(VM_Version::supports_avx(), "");
+  int vector_len = AVX_256bit;
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_T4;
-    input_size_in_bits = EVEX_32bit;
-  }
-  InstructionMark im(this);
-  int vector_len = AVX_256bit;
+    _tuple_type = EVEX_T4;
+    _input_size_in_bits = EVEX_32bit;
+    vector_len = AVX_512bit;
+  }
+  InstructionMark im(this);
   assert(dst != xnoreg, "sanity");
   int dst_enc = dst->encoding();
   // swap src<->dst for encoding
-  vex_prefix(src, dst_enc, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_3A, false, vector_len);
+  vex_prefix(src, dst_enc, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_3A, /* vex_w */ false, vector_len);
   emit_int8(0x18);
   emit_operand(dst, src);
   // 0x01 - insert into upper 128 bits
@@ -4801,6 +4962,9 @@
 void Assembler::vextractf128h(XMMRegister dst, XMMRegister src) {
   assert(VM_Version::supports_avx(), "");
   int vector_len = AVX_256bit;
+  if (VM_Version::supports_evex()) {
+    vector_len = AVX_512bit;
+  }
   int encode = vex_prefix_and_encode(src, xnoreg, dst, VEX_SIMD_66, vector_len, VEX_OPCODE_0F_3A);
   emit_int8(0x19);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -4811,15 +4975,16 @@
 
 void Assembler::vextractf128h(Address dst, XMMRegister src) {
   assert(VM_Version::supports_avx(), "");
+  int vector_len = AVX_256bit;
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_T4;
-    input_size_in_bits = EVEX_32bit;
-  }
-  InstructionMark im(this);
-  int vector_len = AVX_256bit;
+    _tuple_type = EVEX_T4;
+    _input_size_in_bits = EVEX_32bit;
+    vector_len = AVX_512bit;
+  }
+  InstructionMark im(this);
   assert(src != xnoreg, "sanity");
   int src_enc = src->encoding();
-  vex_prefix(dst, 0, src_enc, VEX_SIMD_66, VEX_OPCODE_0F_3A, false, vector_len);
+  vex_prefix(dst, 0, src_enc, VEX_SIMD_66, VEX_OPCODE_0F_3A, /* vex_w */ false, vector_len);
   emit_int8(0x19);
   emit_operand(src, dst);
   // 0x01 - extract from upper 128 bits
@@ -4829,6 +4994,9 @@
 void Assembler::vinserti128h(XMMRegister dst, XMMRegister nds, XMMRegister src) {
   assert(VM_Version::supports_avx2(), "");
   int vector_len = AVX_256bit;
+  if (VM_Version::supports_evex()) {
+    vector_len = AVX_512bit;
+  }
   int encode = vex_prefix_and_encode(dst, nds, src, VEX_SIMD_66, vector_len, VEX_OPCODE_0F_3A);
   emit_int8(0x38);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -4844,7 +5012,7 @@
   int dst_enc = dst->encoding();
   int nds_enc = nds->is_valid() ? nds->encoding() : 0;
   int encode = vex_prefix_and_encode(dst_enc, nds_enc, src_enc, VEX_SIMD_66, VEX_OPCODE_0F_3A,
-                                     VM_Version::supports_avx512dq(), vector_len, false, false);
+                                     /* vex_w */ true, vector_len, /* legacy_mode */ false, /* no_reg_mask */ false);
   emit_int8(0x38);
   emit_int8((unsigned char)(0xC0 | encode));
   // 0x00 - insert into lower 256 bits
@@ -4854,16 +5022,17 @@
 
 void Assembler::vinserti128h(XMMRegister dst, Address src) {
   assert(VM_Version::supports_avx2(), "");
+  int vector_len = AVX_256bit;
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_T4;
-    input_size_in_bits = EVEX_32bit;
-  }
-  InstructionMark im(this);
-  int vector_len = AVX_256bit;
+    _tuple_type = EVEX_T4;
+    _input_size_in_bits = EVEX_32bit;
+    vector_len = AVX_512bit;
+  }
+  InstructionMark im(this);
   assert(dst != xnoreg, "sanity");
   int dst_enc = dst->encoding();
   // swap src<->dst for encoding
-  vex_prefix(src, dst_enc, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_3A, false, vector_len);
+  vex_prefix(src, dst_enc, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_3A, /* vex_w */ false, vector_len);
   emit_int8(0x38);
   emit_operand(dst, src);
   // 0x01 - insert into upper 128 bits
@@ -4873,6 +5042,9 @@
 void Assembler::vextracti128h(XMMRegister dst, XMMRegister src) {
   assert(VM_Version::supports_avx(), "");
   int vector_len = AVX_256bit;
+  if (VM_Version::supports_evex()) {
+    vector_len = AVX_512bit;
+  }
   int encode = vex_prefix_and_encode(src, xnoreg, dst, VEX_SIMD_66, vector_len, VEX_OPCODE_0F_3A);
   emit_int8(0x39);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -4883,15 +5055,16 @@
 
 void Assembler::vextracti128h(Address dst, XMMRegister src) {
   assert(VM_Version::supports_avx2(), "");
+  int vector_len = AVX_256bit;
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_T4;
-    input_size_in_bits = EVEX_32bit;
-  }
-  InstructionMark im(this);
-  int vector_len = AVX_256bit;
+    _tuple_type = EVEX_T4;
+    _input_size_in_bits = EVEX_32bit;
+    vector_len = AVX_512bit;
+  }
+  InstructionMark im(this);
   assert(src != xnoreg, "sanity");
   int src_enc = src->encoding();
-  vex_prefix(dst, 0, src_enc, VEX_SIMD_66, VEX_OPCODE_0F_3A, false, vector_len);
+  vex_prefix(dst, 0, src_enc, VEX_SIMD_66, VEX_OPCODE_0F_3A, /* vex_w */ false, vector_len);
   emit_int8(0x39);
   emit_operand(src, dst);
   // 0x01 - extract from upper 128 bits
@@ -4904,7 +5077,7 @@
   int src_enc = src->encoding();
   int dst_enc = dst->encoding();
   int encode = vex_prefix_and_encode(src_enc, 0, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_3A,
-                                     true, vector_len, false, false);
+                                     /* vex_w */ true, vector_len, /* legacy_mode */ false, /* no_mask_reg */ false);
   emit_int8(0x3B);
   emit_int8((unsigned char)(0xC0 | encode));
   // 0x01 - extract from upper 256 bits
@@ -4916,8 +5089,14 @@
   int vector_len = AVX_512bit;
   int src_enc = src->encoding();
   int dst_enc = dst->encoding();
-  int encode = vex_prefix_and_encode(src_enc, 0, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_3A,
-                                     VM_Version::supports_avx512dq(), vector_len, false, false);
+  int encode;
+  if (VM_Version::supports_avx512dq()) {
+    encode = vex_prefix_and_encode(src_enc, 0, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_3A,
+                                   /* vex_w */ true, vector_len, /* legacy_mode */ false, /* no_mask_reg */ false);
+  } else {
+    encode = vex_prefix_and_encode(src_enc, 0, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_3A,
+                                   /* vex_w */ false, vector_len, /* legacy_mode */ true, /* no_mask_reg */ false);
+  }
   emit_int8(0x39);
   emit_int8((unsigned char)(0xC0 | encode));
   // 0x01 - extract from bits 255:128
@@ -4932,7 +5111,7 @@
   int src_enc = src->encoding();
   int dst_enc = dst->encoding();
   int encode = vex_prefix_and_encode(src_enc, 0, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_3A,
-                                     VM_Version::supports_avx512dq(), vector_len, false, false);
+                                     /* vex_w */ true, vector_len, /* legacy_mode */ false, /* no_mask_reg */ false);
   emit_int8(0x1B);
   emit_int8((unsigned char)(0xC0 | encode));
   // 0x01 - extract from upper 256 bits
@@ -4940,18 +5119,18 @@
 }
 
 void Assembler::vextractf64x4h(Address dst, XMMRegister src) {
-  assert(VM_Version::supports_avx2(), "");
-  tuple_type = EVEX_T4;
-  input_size_in_bits = EVEX_64bit;
+  assert(VM_Version::supports_evex(), "");
+  _tuple_type = EVEX_T4;
+  _input_size_in_bits = EVEX_64bit;
   InstructionMark im(this);
   int vector_len = AVX_512bit;
   assert(src != xnoreg, "sanity");
   int src_enc = src->encoding();
   vex_prefix(dst, 0, src_enc, VEX_SIMD_66, VEX_OPCODE_0F_3A,
-             VM_Version::supports_avx512dq(), vector_len);
+             /* vex_w */ true, vector_len);
   emit_int8(0x1B);
   emit_operand(src, dst);
-  // 0x01 - extract from upper 128 bits
+  // 0x01 - extract from upper 256 bits
   emit_int8(0x01);
 }
 
@@ -4960,10 +5139,29 @@
   int vector_len = AVX_512bit;
   int src_enc = src->encoding();
   int dst_enc = dst->encoding();
-  int encode = vex_prefix_and_encode(src_enc, 0, dst_enc, VEX_SIMD_66,
-                                     VEX_OPCODE_0F_3A, false, vector_len, false, false);
+  int encode = vex_prefix_and_encode(src_enc, 0, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_3A,
+                                     /* vex_w */ false, vector_len, /* legacy_mode */ false, /* no_mask_reg */ false);
   emit_int8(0x19);
   emit_int8((unsigned char)(0xC0 | encode));
+  // 0x00 - extract from bits 127:0
+  // 0x01 - extract from bits 255:128
+  // 0x02 - extract from bits 383:256
+  // 0x03 - extract from bits 511:384
+  emit_int8(value & 0x3);
+}
+
+void Assembler::vextractf32x4h(Address dst, XMMRegister src, int value) {
+  assert(VM_Version::supports_evex(), "");
+  _tuple_type = EVEX_T4;
+  _input_size_in_bits = EVEX_32bit;
+  InstructionMark im(this);
+  int vector_len = AVX_512bit;
+  assert(src != xnoreg, "sanity");
+  int src_enc = src->encoding();
+  vex_prefix(dst, 0, src_enc, VEX_SIMD_66, VEX_OPCODE_0F_3A, /* vex_w */ false, vector_len);
+  emit_int8(0x19);
+  emit_operand(src, dst);
+  // 0x00 - extract from bits 127:0
   // 0x01 - extract from bits 255:128
   // 0x02 - extract from bits 383:256
   // 0x03 - extract from bits 511:384
@@ -4976,7 +5174,7 @@
   int src_enc = src->encoding();
   int dst_enc = dst->encoding();
   int encode = vex_prefix_and_encode(src_enc, 0, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_3A,
-                                     VM_Version::supports_avx512dq(), vector_len, false, false);
+                                     /* vex_w */ !_legacy_mode_dq, vector_len, /* legacy_mode */ false, /* no_mask_reg */ false);
   emit_int8(0x19);
   emit_int8((unsigned char)(0xC0 | encode));
   // 0x01 - extract from bits 255:128
@@ -4987,178 +5185,190 @@
 
 // duplicate 4-bytes integer data from src into 8 locations in dest
 void Assembler::vpbroadcastd(XMMRegister dst, XMMRegister src) {
-  assert(VM_Version::supports_avx2(), "");
+  _instruction_uses_vl = true;
+  assert(UseAVX > 1, "");
   int vector_len = AVX_256bit;
-  int encode = vex_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66,
-                                     vector_len, VEX_OPCODE_0F_38, false);
+  int encode = vex_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, vector_len, VEX_OPCODE_0F_38);
   emit_int8(0x58);
   emit_int8((unsigned char)(0xC0 | encode));
 }
 
 // duplicate 1-byte integer data from src into 16||32|64 locations in dest : requires AVX512BW and AVX512VL
 void Assembler::evpbroadcastb(XMMRegister dst, XMMRegister src, int vector_len) {
-  assert(VM_Version::supports_evex(), "");
-  int encode = vex_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66,
-                                     vector_len, VEX_OPCODE_0F_38, false);
+  _instruction_uses_vl = true;
+  assert(UseAVX > 1, "");
+  int encode = vex_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, vector_len, VEX_OPCODE_0F_38);
   emit_int8(0x78);
   emit_int8((unsigned char)(0xC0 | encode));
 }
 
 void Assembler::evpbroadcastb(XMMRegister dst, Address src, int vector_len) {
-  assert(VM_Version::supports_evex(), "");
-  tuple_type = EVEX_T1S;
-  input_size_in_bits = EVEX_8bit;
+  _instruction_uses_vl = true;
+  assert(UseAVX > 1, "");
+  _tuple_type = EVEX_T1S;
+  _input_size_in_bits = EVEX_8bit;
   InstructionMark im(this);
   assert(dst != xnoreg, "sanity");
   int dst_enc = dst->encoding();
   // swap src<->dst for encoding
-  vex_prefix(src, dst_enc, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_38, false, vector_len);
+  vex_prefix(src, dst_enc, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_38, /* vex_w */ false, vector_len);
   emit_int8(0x78);
   emit_operand(dst, src);
 }
 
 // duplicate 2-byte integer data from src into 8|16||32 locations in dest : requires AVX512BW and AVX512VL
 void Assembler::evpbroadcastw(XMMRegister dst, XMMRegister src, int vector_len) {
-  assert(VM_Version::supports_evex(), "");
-  int encode = vex_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66,
-                                     vector_len, VEX_OPCODE_0F_38, false);
+  _instruction_uses_vl = true;
+  assert(UseAVX > 1, "");
+  int encode = vex_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, vector_len, VEX_OPCODE_0F_38);
   emit_int8(0x79);
   emit_int8((unsigned char)(0xC0 | encode));
 }
 
 void Assembler::evpbroadcastw(XMMRegister dst, Address src, int vector_len) {
-  assert(VM_Version::supports_evex(), "");
-  tuple_type = EVEX_T1S;
-  input_size_in_bits = EVEX_16bit;
+  _instruction_uses_vl = true;
+  assert(UseAVX > 1, "");
+  _tuple_type = EVEX_T1S;
+  _input_size_in_bits = EVEX_16bit;
   InstructionMark im(this);
   assert(dst != xnoreg, "sanity");
   int dst_enc = dst->encoding();
   // swap src<->dst for encoding
-  vex_prefix(src, dst_enc, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_38, false, vector_len);
+  vex_prefix(src, dst_enc, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_38, /* vex_w */ false, vector_len);
   emit_int8(0x79);
   emit_operand(dst, src);
 }
 
 // duplicate 4-byte integer data from src into 4|8|16 locations in dest : requires AVX512VL
 void Assembler::evpbroadcastd(XMMRegister dst, XMMRegister src, int vector_len) {
-  assert(VM_Version::supports_evex(), "");
-  int encode = vex_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66,
-                                     vector_len, VEX_OPCODE_0F_38, false);
+  _instruction_uses_vl = true;
+  assert(UseAVX > 1, "");
+  int encode = vex_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, vector_len, VEX_OPCODE_0F_38);
   emit_int8(0x58);
   emit_int8((unsigned char)(0xC0 | encode));
 }
 
 void Assembler::evpbroadcastd(XMMRegister dst, Address src, int vector_len) {
-  assert(VM_Version::supports_evex(), "");
-  tuple_type = EVEX_T1S;
-  input_size_in_bits = EVEX_32bit;
+  _instruction_uses_vl = true;
+  assert(UseAVX > 1, "");
+  _tuple_type = EVEX_T1S;
+  _input_size_in_bits = EVEX_32bit;
   InstructionMark im(this);
   assert(dst != xnoreg, "sanity");
   int dst_enc = dst->encoding();
   // swap src<->dst for encoding
-  vex_prefix(src, dst_enc, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_38, false, vector_len);
+  vex_prefix(src, dst_enc, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_38, /* vex_w */ false, vector_len);
   emit_int8(0x58);
   emit_operand(dst, src);
 }
 
 // duplicate 8-byte integer data from src into 4|8|16 locations in dest : requires AVX512VL
 void Assembler::evpbroadcastq(XMMRegister dst, XMMRegister src, int vector_len) {
-  assert(VM_Version::supports_evex(), "");
-  int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66,
-                                     VEX_OPCODE_0F_38, true, vector_len, false, false);
+  _instruction_uses_vl = true;
+  assert(UseAVX > 1, "");
+  int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38,
+                                     /* vex_w */ true, vector_len, /* legacy_mode */ false, /* no_mask_reg */ false);
   emit_int8(0x59);
   emit_int8((unsigned char)(0xC0 | encode));
 }
 
 void Assembler::evpbroadcastq(XMMRegister dst, Address src, int vector_len) {
-  assert(VM_Version::supports_evex(), "");
-  tuple_type = EVEX_T1S;
-  input_size_in_bits = EVEX_64bit;
+  _instruction_uses_vl = true;
+  assert(UseAVX > 1, "");
+  _tuple_type = EVEX_T1S;
+  _input_size_in_bits = EVEX_64bit;
   InstructionMark im(this);
   assert(dst != xnoreg, "sanity");
   int dst_enc = dst->encoding();
   // swap src<->dst for encoding
-  vex_prefix(src, dst_enc, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_38, true, vector_len);
+  vex_prefix(src, dst_enc, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_38, /* vex_w */ true, vector_len);
   emit_int8(0x59);
   emit_operand(dst, src);
 }
 
 // duplicate single precision fp from src into 4|8|16 locations in dest : requires AVX512VL
 void Assembler::evpbroadcastss(XMMRegister dst, XMMRegister src, int vector_len) {
-  assert(VM_Version::supports_evex(), "");
-  int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66,
-                                     VEX_OPCODE_0F_38, false, vector_len, false, false);
+  _instruction_uses_vl = true;
+  assert(UseAVX > 1, "");
+  int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38,
+                                     /* vex_w */ false, vector_len, /* legacy_mode */ false, /*no_mask_reg */ false);
   emit_int8(0x18);
   emit_int8((unsigned char)(0xC0 | encode));
 }
 
 void Assembler::evpbroadcastss(XMMRegister dst, Address src, int vector_len) {
-  assert(VM_Version::supports_evex(), "");
-  tuple_type = EVEX_T1S;
-  input_size_in_bits = EVEX_32bit;
+  assert(UseAVX > 1, "");
+  _tuple_type = EVEX_T1S;
+  _input_size_in_bits = EVEX_32bit;
   InstructionMark im(this);
   assert(dst != xnoreg, "sanity");
   int dst_enc = dst->encoding();
   // swap src<->dst for encoding
-  vex_prefix(src, 0, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_38, false, vector_len);
+  vex_prefix(src, 0, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_38, /* vex_w */ false, vector_len);
   emit_int8(0x18);
   emit_operand(dst, src);
 }
 
 // duplicate double precision fp from src into 2|4|8 locations in dest : requires AVX512VL
 void Assembler::evpbroadcastsd(XMMRegister dst, XMMRegister src, int vector_len) {
-  assert(VM_Version::supports_evex(), "");
-  int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66,
-                                     VEX_OPCODE_0F_38, true, vector_len, false, false);
+  _instruction_uses_vl = true;
+  assert(UseAVX > 1, "");
+  int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38,
+                                     /*vex_w */ true, vector_len, /* legacy_mode */ false, /*no_mask_reg */ false);
   emit_int8(0x19);
   emit_int8((unsigned char)(0xC0 | encode));
 }
 
 void Assembler::evpbroadcastsd(XMMRegister dst, Address src, int vector_len) {
-  assert(VM_Version::supports_evex(), "");
-  tuple_type = EVEX_T1S;
-  input_size_in_bits = EVEX_64bit;
+  _instruction_uses_vl = true;
+  assert(UseAVX > 1, "");
+  _tuple_type = EVEX_T1S;
+  _input_size_in_bits = EVEX_64bit;
   InstructionMark im(this);
   assert(dst != xnoreg, "sanity");
   int dst_enc = dst->encoding();
   // swap src<->dst for encoding
-  vex_prefix(src, 0, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_38, true, vector_len);
+  vex_prefix(src, 0, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_38, /* vex_w */ true, vector_len);
   emit_int8(0x19);
   emit_operand(dst, src);
 }
 
 // duplicate 1-byte integer data from src into 16||32|64 locations in dest : requires AVX512BW and AVX512VL
 void Assembler::evpbroadcastb(XMMRegister dst, Register src, int vector_len) {
+  _instruction_uses_vl = true;
   assert(VM_Version::supports_evex(), "");
-  int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66,
-                                     VEX_OPCODE_0F_38, false, vector_len, false, false);
+  int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38,
+                                     /*vex_w */ false, vector_len, /* legacy_mode */ false, /*no_mask_reg */ false);
   emit_int8(0x7A);
   emit_int8((unsigned char)(0xC0 | encode));
 }
 
 // duplicate 2-byte integer data from src into 8|16||32 locations in dest : requires AVX512BW and AVX512VL
 void Assembler::evpbroadcastw(XMMRegister dst, Register src, int vector_len) {
+  _instruction_uses_vl = true;
   assert(VM_Version::supports_evex(), "");
-  int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66,
-                                     VEX_OPCODE_0F_38, false, vector_len, false, false);
+  int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38,
+                                     /* vex_w */ false, vector_len, /* legacy_mode */ false, /*no_mask_reg */ false);
   emit_int8(0x7B);
   emit_int8((unsigned char)(0xC0 | encode));
 }
 
 // duplicate 4-byte integer data from src into 4|8|16 locations in dest : requires AVX512VL
 void Assembler::evpbroadcastd(XMMRegister dst, Register src, int vector_len) {
+  _instruction_uses_vl = true;
   assert(VM_Version::supports_evex(), "");
-  int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66,
-                                     VEX_OPCODE_0F_38, false, vector_len, false, false);
+  int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38,
+                                     /* vex_w */ false, vector_len, /* legacy_mode */ false, /*no_mask_reg */ false);
   emit_int8(0x7C);
   emit_int8((unsigned char)(0xC0 | encode));
 }
 
 // duplicate 8-byte integer data from src into 4|8|16 locations in dest : requires AVX512VL
 void Assembler::evpbroadcastq(XMMRegister dst, Register src, int vector_len) {
+  _instruction_uses_vl = true;
   assert(VM_Version::supports_evex(), "");
-  int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66,
-                                     VEX_OPCODE_0F_38, true, vector_len, false, false);
+  int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38,
+                                     /* vex_w */ true, vector_len, /* legacy_mode */ false, /*no_mask_reg */ false);
   emit_int8(0x7C);
   emit_int8((unsigned char)(0xC0 | encode));
 }
@@ -5166,8 +5376,8 @@
 // Carry-Less Multiplication Quadword
 void Assembler::pclmulqdq(XMMRegister dst, XMMRegister src, int mask) {
   assert(VM_Version::supports_clmul(), "");
-  int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, false,
-                                      VEX_OPCODE_0F_3A, false, AVX_128bit, true);
+  int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, /* no_mask_reg */ false,
+                                      VEX_OPCODE_0F_3A, /* rex_w */ false, AVX_128bit, /* legacy_mode */ true);
   emit_int8(0x44);
   emit_int8((unsigned char)(0xC0 | encode));
   emit_int8((unsigned char)mask);
@@ -5177,8 +5387,7 @@
 void Assembler::vpclmulqdq(XMMRegister dst, XMMRegister nds, XMMRegister src, int mask) {
   assert(VM_Version::supports_avx() && VM_Version::supports_clmul(), "");
   int vector_len = AVX_128bit;
-  int encode = vex_prefix_and_encode(dst, nds, src, VEX_SIMD_66,
-                                     vector_len, VEX_OPCODE_0F_3A, true);
+  int encode = vex_prefix_and_encode(dst, nds, src, VEX_SIMD_66, vector_len, VEX_OPCODE_0F_3A, /* legacy_mode */ true);
   emit_int8(0x44);
   emit_int8((unsigned char)(0xC0 | encode));
   emit_int8((unsigned char)mask);
@@ -5737,7 +5946,7 @@
                             int vector_len, bool no_mask_reg ){
   // EVEX 0x62 prefix
   prefix(EVEX_4bytes);
-  evex_encoding = (vex_w ? VEX_W : 0) | (evex_r ? EVEX_Rb : 0);
+  _evex_encoding = (vex_w ? VEX_W : 0) | (evex_r ? EVEX_Rb : 0);
 
   // P0: byte 2, initialized to RXBR`00mm
   // instead of not'd
@@ -5776,10 +5985,10 @@
   bool vex_r = ((xreg_enc & 8) == 8) ? 1 : 0;
   bool vex_b = adr.base_needs_rex();
   bool vex_x = adr.index_needs_rex();
-  avx_vector_len = vector_len;
-
-  // if vector length is turned off, revert to AVX for vectors smaller than AVX_512bit
-  if (VM_Version::supports_avx512vl() == false) {
+  _avx_vector_len = vector_len;
+
+  // if vector length is turned off, revert to AVX for vectors smaller than 512-bit
+  if (_legacy_mode_vl && _instruction_uses_vl) {
     switch (vector_len) {
     case AVX_128bit:
     case AVX_256bit:
@@ -5792,11 +6001,12 @@
   {
     bool evex_r = (xreg_enc >= 16);
     bool evex_v = (nds_enc >= 16);
-    is_evex_instruction = true;
+    _is_evex_instruction = true;
     evex_prefix(vex_r, vex_b, vex_x, vex_w, evex_r, evex_v, nds_enc, pre, opc, false, false, vector_len, no_mask_reg);
   } else {
     vex_prefix(vex_r, vex_b, vex_x, vex_w, nds_enc, pre, opc, vector_len);
   }
+  _instruction_uses_vl = false;
 }
 
 int Assembler::vex_prefix_and_encode(int dst_enc, int nds_enc, int src_enc, VexSimdPrefix pre, VexOpcode opc,
@@ -5804,10 +6014,10 @@
   bool vex_r = ((dst_enc & 8) == 8) ? 1 : 0;
   bool vex_b = ((src_enc & 8) == 8) ? 1 : 0;
   bool vex_x = false;
-  avx_vector_len = vector_len;
-
-  // if vector length is turned off, revert to AVX for vectors smaller than AVX_512bit
-  if (VM_Version::supports_avx512vl() == false) {
+  _avx_vector_len = vector_len;
+
+  // if vector length is turned off, revert to AVX for vectors smaller than 512-bit
+  if (_legacy_mode_vl && _instruction_uses_vl) {
     switch (vector_len) {
     case AVX_128bit:
     case AVX_256bit:
@@ -5827,6 +6037,8 @@
     vex_prefix(vex_r, vex_b, vex_x, vex_w, nds_enc, pre, opc, vector_len);
   }
 
+  _instruction_uses_vl = false;
+
   // return modrm byte components for operands
   return (((dst_enc & 7) << 3) | (src_enc & 7));
 }
@@ -5915,13 +6127,13 @@
 }
 
 void Assembler::emit_simd_arith_nonds(int opcode, XMMRegister dst, XMMRegister src, VexSimdPrefix pre, bool no_mask_reg, bool legacy_mode) {
-  int encode = simd_prefix_and_encode(dst, xnoreg, src, pre, no_mask_reg, VEX_OPCODE_0F, legacy_mode, AVX_128bit);
+  int encode = simd_prefix_and_encode(dst, xnoreg, src, pre, no_mask_reg, VEX_OPCODE_0F, false, AVX_128bit, legacy_mode);
   emit_int8(opcode);
   emit_int8((unsigned char)(0xC0 | encode));
 }
 
 void Assembler::emit_simd_arith_nonds_q(int opcode, XMMRegister dst, XMMRegister src, VexSimdPrefix pre, bool no_mask_reg) {
-  int encode = simd_prefix_and_encode(dst, xnoreg, src, pre, no_mask_reg, VEX_OPCODE_0F, true, AVX_128bit);
+  int encode = simd_prefix_and_encode(dst, xnoreg, src, pre, no_mask_reg, VEX_OPCODE_0F, true);
   emit_int8(opcode);
   emit_int8((unsigned char)(0xC0 | encode));
 }
@@ -5945,7 +6157,7 @@
 
 void Assembler::emit_vex_arith(int opcode, XMMRegister dst, XMMRegister nds, XMMRegister src,
                                VexSimdPrefix pre, int vector_len, bool no_mask_reg, bool legacy_mode) {
-  int encode = vex_prefix_and_encode(dst, nds, src, pre, vector_len, VEX_OPCODE_0F, false, no_mask_reg);
+  int encode = vex_prefix_and_encode(dst, nds, src, pre, vector_len, VEX_OPCODE_0F, legacy_mode, no_mask_reg);
   emit_int8(opcode);
   emit_int8((unsigned char)(0xC0 | encode));
 }
@@ -6594,7 +6806,7 @@
 
 void Assembler::cvtsi2sdq(XMMRegister dst, Register src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  int encode = simd_prefix_and_encode_q(dst, dst, src, VEX_SIMD_F2, true);
+  int encode = simd_prefix_and_encode_q(dst, dst, src, VEX_SIMD_F2, /* no_mask_reg */ true);
   emit_int8(0x2A);
   emit_int8((unsigned char)(0xC0 | encode));
 }
@@ -6602,11 +6814,11 @@
 void Assembler::cvtsi2sdq(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_T1S;
-    input_size_in_bits = EVEX_32bit;
-  }
-  InstructionMark im(this);
-  simd_prefix_q(dst, dst, src, VEX_SIMD_F2, true);
+    _tuple_type = EVEX_T1S;
+    _input_size_in_bits = EVEX_32bit;
+  }
+  InstructionMark im(this);
+  simd_prefix_q(dst, dst, src, VEX_SIMD_F2, /* no_mask_reg */ true);
   emit_int8(0x2A);
   emit_operand(dst, src);
 }
@@ -6614,25 +6826,25 @@
 void Assembler::cvtsi2ssq(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
   if (VM_Version::supports_evex()) {
-    tuple_type = EVEX_T1S;
-    input_size_in_bits = EVEX_32bit;
-  }
-  InstructionMark im(this);
-  simd_prefix_q(dst, dst, src, VEX_SIMD_F3, true);
+    _tuple_type = EVEX_T1S;
+    _input_size_in_bits = EVEX_32bit;
+  }
+  InstructionMark im(this);
+  simd_prefix_q(dst, dst, src, VEX_SIMD_F3, /* no_mask_reg */ true);
   emit_int8(0x2A);
   emit_operand(dst, src);
 }
 
 void Assembler::cvttsd2siq(Register dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  int encode = simd_prefix_and_encode_q(dst, src, VEX_SIMD_F2, VEX_OPCODE_0F, true);
+  int encode = simd_prefix_and_encode_q(dst, src, VEX_SIMD_F2, VEX_OPCODE_0F, /* no_mask_reg */ true);
   emit_int8(0x2C);
   emit_int8((unsigned char)(0xC0 | encode));
 }
 
 void Assembler::cvttss2siq(Register dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
-  int encode = simd_prefix_and_encode_q(dst, src, VEX_SIMD_F3, VEX_OPCODE_0F, true);
+  int encode = simd_prefix_and_encode_q(dst, src, VEX_SIMD_F3, VEX_OPCODE_0F, /* no_mask_reg */ true);
   emit_int8(0x2C);
   emit_int8((unsigned char)(0xC0 | encode));
 }
@@ -6668,6 +6880,13 @@
   emit_operand(as_Register(1), src);
 }
 
+void Assembler::xrstor(Address src) {
+  prefixq(src);
+  emit_int8(0x0F);
+  emit_int8((unsigned char)0xAE);
+  emit_operand(as_Register(5), src);
+}
+
 void Assembler::fxsave(Address dst) {
   prefixq(dst);
   emit_int8(0x0F);
@@ -6675,6 +6894,13 @@
   emit_operand(as_Register(0), dst);
 }
 
+void Assembler::xsave(Address dst) {
+  prefixq(dst);
+  emit_int8(0x0F);
+  emit_int8((unsigned char)0xAE);
+  emit_operand(as_Register(4), dst);
+}
+
 void Assembler::idivq(Register src) {
   int encode = prefixq_and_encode(src->encoding());
   emit_int8((unsigned char)0xF7);
@@ -6801,7 +7027,7 @@
 void Assembler::movdq(XMMRegister dst, Register src) {
   // table D-1 says MMX/SSE2
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  int encode = simd_prefix_and_encode_q(dst, src, VEX_SIMD_66, true);
+  int encode = simd_prefix_and_encode_q(dst, src, VEX_SIMD_66, /* no_mask_reg */ true);
   emit_int8(0x6E);
   emit_int8((unsigned char)(0xC0 | encode));
 }
@@ -6810,7 +7036,7 @@
   // table D-1 says MMX/SSE2
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   // swap src/dst to get correct prefix
-  int encode = simd_prefix_and_encode_q(src, dst, VEX_SIMD_66, true);
+  int encode = simd_prefix_and_encode_q(src, dst, VEX_SIMD_66, /* no_mask_reg */ true);
   emit_int8(0x7E);
   emit_int8((unsigned char)(0xC0 | encode));
 }
@@ -6943,8 +7169,8 @@
 
 void Assembler::mulxq(Register dst1, Register dst2, Register src) {
   assert(VM_Version::supports_bmi2(), "bit manipulation instructions not supported");
-  int encode = vex_prefix_and_encode(dst1->encoding(), dst2->encoding(), src->encoding(),
-                                     VEX_SIMD_F2, VEX_OPCODE_0F_38, true, AVX_128bit, true, false);
+  int encode = vex_prefix_and_encode(dst1->encoding(), dst2->encoding(), src->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F_38,
+                                    /* vex_w */ true, AVX_128bit, /* legacy_mode */ true, /* no_mask_reg */ false);
   emit_int8((unsigned char)0xF6);
   emit_int8((unsigned char)(0xC0 | encode));
 }
@@ -7106,8 +7332,8 @@
 
 void Assembler::rorxq(Register dst, Register src, int imm8) {
   assert(VM_Version::supports_bmi2(), "bit manipulation instructions not supported");
-  int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_F2,
-                                     VEX_OPCODE_0F_3A, true, AVX_128bit, true, false);
+  int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F_3A,
+                                     /* vex_w */ true, AVX_128bit, /* legacy_mode */ true, /* no_mask_reg */ false);
   emit_int8((unsigned char)0xF0);
   emit_int8((unsigned char)(0xC0 | encode));
   emit_int8(imm8);
--- a/hotspot/src/cpu/x86/vm/assembler_x86.hpp	Sat Sep 26 09:22:24 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/assembler_x86.hpp	Wed Jul 05 20:51:27 2017 +0200
@@ -438,7 +438,9 @@
 
 };
 
-const int FPUStateSizeInWords = NOT_LP64(27) LP64_ONLY( 512*2 / wordSize);
+// 64-bit refect the fxsave size which is 512 bytes and the new xsave area on EVEX which is another 2176 bytes
+// See fxsave and xsave(EVEX enabled) documentation for layout
+const int FPUStateSizeInWords = NOT_LP64(27) LP64_ONLY(2688 / wordSize);
 
 // The Intel x86/Amd64 Assembler: Pure assembler doing NO optimizations on the instruction
 // level (e.g. mov rax, 0 is not translated into xor rax, rax!); i.e., what you write
@@ -594,11 +596,16 @@
 
 private:
 
-  int evex_encoding;
-  int input_size_in_bits;
-  int avx_vector_len;
-  int tuple_type;
-  bool is_evex_instruction;
+  int _evex_encoding;
+  int _input_size_in_bits;
+  int _avx_vector_len;
+  int _tuple_type;
+  bool _is_evex_instruction;
+  bool _legacy_mode_bw;
+  bool _legacy_mode_dq;
+  bool _legacy_mode_vl;
+  bool _legacy_mode_vlbw;
+  bool _instruction_uses_vl;
 
   // 64bit prefixes
   int prefix_and_encode(int reg_enc, bool byteinst = false);
@@ -972,11 +979,16 @@
   // belong in macro assembler but there is no need for both varieties to exist
 
   void init_attributes(void) {
-    evex_encoding = 0;
-    input_size_in_bits = 0;
-    avx_vector_len = AVX_NoVec;
-    tuple_type = EVEX_ETUP;
-    is_evex_instruction = false;
+    _evex_encoding = 0;
+    _input_size_in_bits = 0;
+    _avx_vector_len = AVX_NoVec;
+    _tuple_type = EVEX_ETUP;
+    _is_evex_instruction = false;
+    _legacy_mode_bw = (VM_Version::supports_avx512bw() == false);
+    _legacy_mode_dq = (VM_Version::supports_avx512dq() == false);
+    _legacy_mode_vl = (VM_Version::supports_avx512vl() == false);
+    _legacy_mode_vlbw = (VM_Version::supports_avx512vlbw() == false);
+    _instruction_uses_vl = false;
   }
 
   void lea(Register dst, Address src);
@@ -1344,8 +1356,10 @@
   void fxch(int i = 1);
 
   void fxrstor(Address src);
+  void xrstor(Address src);
 
   void fxsave(Address dst);
+  void xsave(Address dst);
 
   void fyl2x();
   void frndint();
@@ -1479,11 +1493,12 @@
   void movb(Address dst, int imm8);
   void movb(Register dst, Address src);
 
-  void kmovq(KRegister dst, KRegister src);
+  void kmovql(KRegister dst, KRegister src);
   void kmovql(KRegister dst, Register src);
   void kmovdl(KRegister dst, Register src);
-  void kmovq(Address dst, KRegister src);
-  void kmovq(KRegister dst, Address src);
+  void kmovwl(KRegister dst, Register src);
+  void kmovql(Address dst, KRegister src);
+  void kmovql(KRegister dst, Address src);
 
   void movdl(XMMRegister dst, Register src);
   void movdl(Register dst, XMMRegister src);
@@ -1509,9 +1524,12 @@
   void vmovdqu(XMMRegister dst, XMMRegister src);
 
    // Move Unaligned 512bit Vector
-  void evmovdqu(Address dst, XMMRegister src, int vector_len);
-  void evmovdqu(XMMRegister dst, Address src, int vector_len);
-  void evmovdqu(XMMRegister dst, XMMRegister src, int vector_len);
+  void evmovdqul(Address dst, XMMRegister src, int vector_len);
+  void evmovdqul(XMMRegister dst, Address src, int vector_len);
+  void evmovdqul(XMMRegister dst, XMMRegister src, int vector_len);
+  void evmovdquq(Address dst, XMMRegister src, int vector_len);
+  void evmovdquq(XMMRegister dst, Address src, int vector_len);
+  void evmovdquq(XMMRegister dst, XMMRegister src, int vector_len);
 
   // Move lower 64bit to high 64bit in 128bit register
   void movlhps(XMMRegister dst, XMMRegister src);
@@ -1643,6 +1661,7 @@
 
   // Pemutation of 64bit words
   void vpermq(XMMRegister dst, XMMRegister src, int imm8, int vector_len);
+  void vpermq(XMMRegister dst, XMMRegister src, int imm8);
 
   void pause();
 
@@ -1920,6 +1939,10 @@
   void vdivpd(XMMRegister dst, XMMRegister nds, Address src, int vector_len);
   void vdivps(XMMRegister dst, XMMRegister nds, Address src, int vector_len);
 
+  // Sqrt Packed Floating-Point Values - Double precision only
+  void vsqrtpd(XMMRegister dst, XMMRegister src, int vector_len);
+  void vsqrtpd(XMMRegister dst, Address src, int vector_len);
+
   // Bitwise Logical AND of Packed Floating-Point Values
   void andpd(XMMRegister dst, XMMRegister src);
   void andps(XMMRegister dst, XMMRegister src);
@@ -2057,6 +2080,9 @@
   void vextracti64x2h(XMMRegister dst, XMMRegister src, int value);
   void vextractf64x2h(XMMRegister dst, XMMRegister src, int value);
   void vextractf32x4h(XMMRegister dst, XMMRegister src, int value);
+  void vextractf32x4h(Address dst, XMMRegister src, int value);
+  void vinsertf32x4h(XMMRegister dst, XMMRegister nds, XMMRegister src, int value);
+  void vinsertf32x4h(XMMRegister dst, Address src, int value);
 
   // duplicate 4-bytes integer data from src into 8 locations in dest
   void vpbroadcastd(XMMRegister dst, XMMRegister src);
--- a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Sat Sep 26 09:22:24 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Wed Jul 05 20:51:27 2017 +0200
@@ -3798,16 +3798,24 @@
     if (left->as_xmm_float_reg() != dest->as_xmm_float_reg()) {
       __ movflt(dest->as_xmm_float_reg(), left->as_xmm_float_reg());
     }
-    __ xorps(dest->as_xmm_float_reg(),
-             ExternalAddress((address)float_signflip_pool));
-
+    if (UseAVX > 1) {
+      __ vnegatess(dest->as_xmm_float_reg(), dest->as_xmm_float_reg(),
+                   ExternalAddress((address)float_signflip_pool));
+    } else {
+      __ xorps(dest->as_xmm_float_reg(),
+               ExternalAddress((address)float_signflip_pool));
+    }
   } else if (dest->is_double_xmm()) {
     if (left->as_xmm_double_reg() != dest->as_xmm_double_reg()) {
       __ movdbl(dest->as_xmm_double_reg(), left->as_xmm_double_reg());
     }
-    __ xorpd(dest->as_xmm_double_reg(),
-             ExternalAddress((address)double_signflip_pool));
-
+    if (UseAVX > 1) {
+      __ vnegatesd(dest->as_xmm_double_reg(), dest->as_xmm_double_reg(),
+                   ExternalAddress((address)double_signflip_pool));
+    } else {
+      __ xorpd(dest->as_xmm_double_reg(),
+               ExternalAddress((address)double_signflip_pool));
+    }
   } else if (left->is_single_fpu() || left->is_double_fpu()) {
     assert(left->fpu() == 0, "arg must be on TOS");
     assert(dest->fpu() == 0, "dest must be TOS");
--- a/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp	Sat Sep 26 09:22:24 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp	Wed Jul 05 20:51:27 2017 +0200
@@ -401,11 +401,9 @@
 
     } else if (UseSSE == 1) {
       int xmm_off = xmm_regs_as_doubles_off;
-      for (int n = 0; n < FrameMap::nof_xmm_regs; n++) {
-        if (n < xmm_bypass_limit) {
-          VMReg xmm_name_0 = as_XMMRegister(n)->as_VMReg();
-          map->set_callee_saved(VMRegImpl::stack2reg(xmm_off + num_rt_args), xmm_name_0);
-        }
+      for (int n = 0; n < FrameMap::nof_fpu_regs; n++) {
+        VMReg xmm_name_0 = as_XMMRegister(n)->as_VMReg();
+        map->set_callee_saved(VMRegImpl::stack2reg(xmm_off + num_rt_args), xmm_name_0);
         xmm_off += 2;
       }
       assert(xmm_off == float_regs_as_doubles_off, "incorrect number of xmm registers");
@@ -452,14 +450,11 @@
       __ frstor(Address(rsp, fpu_state_off * VMRegImpl::stack_slot_size));
 
       // Save the FPU registers in de-opt-able form
-      __ fstp_d(Address(rsp, float_regs_as_doubles_off * VMRegImpl::stack_slot_size +  0));
-      __ fstp_d(Address(rsp, float_regs_as_doubles_off * VMRegImpl::stack_slot_size +  8));
-      __ fstp_d(Address(rsp, float_regs_as_doubles_off * VMRegImpl::stack_slot_size + 16));
-      __ fstp_d(Address(rsp, float_regs_as_doubles_off * VMRegImpl::stack_slot_size + 24));
-      __ fstp_d(Address(rsp, float_regs_as_doubles_off * VMRegImpl::stack_slot_size + 32));
-      __ fstp_d(Address(rsp, float_regs_as_doubles_off * VMRegImpl::stack_slot_size + 40));
-      __ fstp_d(Address(rsp, float_regs_as_doubles_off * VMRegImpl::stack_slot_size + 48));
-      __ fstp_d(Address(rsp, float_regs_as_doubles_off * VMRegImpl::stack_slot_size + 56));
+      int offset = 0;
+      for (int n = 0; n < FrameMap::nof_fpu_regs; n++) {
+        __ fstp_d(Address(rsp, float_regs_as_doubles_off * VMRegImpl::stack_slot_size + offset));
+        offset += 8;
+      }
     }
 
     if (UseSSE >= 2) {
@@ -468,52 +463,26 @@
       // so always save them as doubles.
       // note that float values are _not_ converted automatically, so for float values
       // the second word contains only garbage data.
-      __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size +  0), xmm0);
-      __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size +  8), xmm1);
-      __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 16), xmm2);
-      __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 24), xmm3);
-      __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 32), xmm4);
-      __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 40), xmm5);
-      __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 48), xmm6);
-      __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 56), xmm7);
+      int xmm_bypass_limit = FrameMap::nof_xmm_regs;
+      int offset = 0;
 #ifdef _LP64
-      __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 64), xmm8);
-      __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 72), xmm9);
-      __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 80), xmm10);
-      __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 88), xmm11);
-      __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 96), xmm12);
-      __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 104), xmm13);
-      __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 112), xmm14);
-      __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 120), xmm15);
-      if (UseAVX > 2) {
-        __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 128), xmm16);
-        __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 136), xmm17);
-        __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 144), xmm18);
-        __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 152), xmm19);
-        __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 160), xmm20);
-        __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 168), xmm21);
-        __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 176), xmm22);
-        __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 184), xmm23);
-        __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 192), xmm24);
-        __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 200), xmm25);
-        __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 208), xmm26);
-        __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 216), xmm27);
-        __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 224), xmm28);
-        __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 232), xmm29);
-        __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 240), xmm30);
-        __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 248), xmm31);
+      if (UseAVX < 3) {
+        xmm_bypass_limit = xmm_bypass_limit / 2;
+      }
+#endif
+      for (int n = 0; n < xmm_bypass_limit; n++) {
+        XMMRegister xmm_name = as_XMMRegister(n);
+        __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + offset), xmm_name);
+        offset += 8;
       }
-#endif // _LP64
     } else if (UseSSE == 1) {
-      // save XMM registers as float because double not supported without SSE2
-      __ movflt(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size +  0), xmm0);
-      __ movflt(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size +  8), xmm1);
-      __ movflt(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 16), xmm2);
-      __ movflt(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 24), xmm3);
-      __ movflt(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 32), xmm4);
-      __ movflt(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 40), xmm5);
-      __ movflt(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 48), xmm6);
-      __ movflt(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 56), xmm7);
+      // save XMM registers as float because double not supported without SSE2(num MMX == num fpu)
+      int offset = 0;
+      for (int n = 0; n < FrameMap::nof_fpu_regs; n++) {
+        XMMRegister xmm_name = as_XMMRegister(n);
+        __ movflt(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + offset), xmm_name);
+        offset += 8;
+      }
     }
   }
 
@@ -528,52 +497,26 @@
   if (restore_fpu_registers) {
     if (UseSSE >= 2) {
       // restore XMM registers
-      __ movdbl(xmm0, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size +  0));
-      __ movdbl(xmm1, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size +  8));
-      __ movdbl(xmm2, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 16));
-      __ movdbl(xmm3, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 24));
-      __ movdbl(xmm4, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 32));
-      __ movdbl(xmm5, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 40));
-      __ movdbl(xmm6, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 48));
-      __ movdbl(xmm7, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 56));
+      int xmm_bypass_limit = FrameMap::nof_xmm_regs;
 #ifdef _LP64
-      __ movdbl(xmm8, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 64));
-      __ movdbl(xmm9, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 72));
-      __ movdbl(xmm10, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 80));
-      __ movdbl(xmm11, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 88));
-      __ movdbl(xmm12, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 96));
-      __ movdbl(xmm13, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 104));
-      __ movdbl(xmm14, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 112));
-      __ movdbl(xmm15, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 120));
-      if (UseAVX > 2) {
-        __ movdbl(xmm16, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 128));
-        __ movdbl(xmm17, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 136));
-        __ movdbl(xmm18, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 144));
-        __ movdbl(xmm19, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 152));
-        __ movdbl(xmm20, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 160));
-        __ movdbl(xmm21, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 168));
-        __ movdbl(xmm22, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 176));
-        __ movdbl(xmm23, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 184));
-        __ movdbl(xmm24, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 192));
-        __ movdbl(xmm25, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 200));
-        __ movdbl(xmm26, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 208));
-        __ movdbl(xmm27, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 216));
-        __ movdbl(xmm28, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 224));
-        __ movdbl(xmm29, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 232));
-        __ movdbl(xmm30, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 240));
-        __ movdbl(xmm31, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 248));
+      if (UseAVX < 3) {
+        xmm_bypass_limit = xmm_bypass_limit / 2;
       }
-#endif // _LP64
+#endif
+      int offset = 0;
+      for (int n = 0; n < xmm_bypass_limit; n++) {
+        XMMRegister xmm_name = as_XMMRegister(n);
+        __ movdbl(xmm_name, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + offset));
+        offset += 8;
+      }
     } else if (UseSSE == 1) {
-      // restore XMM registers
-      __ movflt(xmm0, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size +  0));
-      __ movflt(xmm1, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size +  8));
-      __ movflt(xmm2, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 16));
-      __ movflt(xmm3, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 24));
-      __ movflt(xmm4, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 32));
-      __ movflt(xmm5, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 40));
-      __ movflt(xmm6, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 48));
-      __ movflt(xmm7, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 56));
+      // restore XMM registers(num MMX == num fpu)
+      int offset = 0;
+      for (int n = 0; n < FrameMap::nof_fpu_regs; n++) {
+        XMMRegister xmm_name = as_XMMRegister(n);
+        __ movflt(xmm_name, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + offset));
+        offset += 8;
+      }
     }
 
     if (UseSSE < 2) {
--- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp	Sat Sep 26 09:22:24 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp	Wed Jul 05 20:51:27 2017 +0200
@@ -3751,8 +3751,31 @@
 }
 
 void MacroAssembler::pop_FPU_state() {
-  NOT_LP64(frstor(Address(rsp, 0));)
-  LP64_ONLY(fxrstor(Address(rsp, 0));)
+#ifndef _LP64
+  frstor(Address(rsp, 0));
+#else
+  // AVX will continue to use the fxsave area.
+  // EVEX needs to utilize the xsave area, which is under different
+  // management.
+  if(VM_Version::supports_evex()) {
+    // EDX:EAX describe the XSAVE header and
+    // are obtained while fetching info for XCR0 via cpuid.
+    // These two registers make up 64-bits in the header for which bits
+    // 62:10 are currently reserved for future implementations and unused.  Bit 63
+    // is unused for our implementation as we do not utilize
+    // compressed XSAVE areas.  Bits 9..8 are currently ignored as we do not use
+    // the functionality for PKRU state and MSR tracing.
+    // Ergo we are primarily concerned with bits 7..0, which define
+    // which ISA extensions and features are enabled for a given machine and are
+    // defined in XemXcr0Eax and is used to map the XSAVE area
+    // for restoring registers as described via XCR0.
+    movl(rdx,VM_Version::get_xsave_header_upper_segment());
+    movl(rax,VM_Version::get_xsave_header_lower_segment());
+    xrstor(Address(rsp, 0));
+  } else {
+    fxrstor(Address(rsp, 0));
+  }
+#endif
   addptr(rsp, FPUStateSizeInWords * wordSize);
 }
 
@@ -3769,13 +3792,49 @@
   push_FPU_state();
 }
 
+#ifdef _LP64
+#define XSTATE_BV 0x200
+#endif
+
 void MacroAssembler::push_FPU_state() {
   subptr(rsp, FPUStateSizeInWords * wordSize);
 #ifndef _LP64
   fnsave(Address(rsp, 0));
   fwait();
 #else
-  fxsave(Address(rsp, 0));
+  // AVX will continue to use the fxsave area.
+  // EVEX needs to utilize the xsave area, which is under different
+  // management.
+  if(VM_Version::supports_evex()) {
+    // Save a copy of EAX and EDX
+    push(rax);
+    push(rdx);
+    // EDX:EAX describe the XSAVE header and
+    // are obtained while fetching info for XCR0 via cpuid.
+    // These two registers make up 64-bits in the header for which bits
+    // 62:10 are currently reserved for future implementations and unused.  Bit 63
+    // is unused for our implementation as we do not utilize
+    // compressed XSAVE areas.  Bits 9..8 are currently ignored as we do not use
+    // the functionality for PKRU state and MSR tracing.
+    // Ergo we are primarily concerned with bits 7..0, which define
+    // which ISA extensions and features are enabled for a given machine and are
+    // defined in XemXcr0Eax and is used to program XSAVE area
+    // for saving the required registers as defined in XCR0.
+    int xcr0_edx = VM_Version::get_xsave_header_upper_segment();
+    int xcr0_eax = VM_Version::get_xsave_header_lower_segment();
+    movl(rdx,xcr0_edx);
+    movl(rax,xcr0_eax);
+    xsave(Address(rsp, wordSize*2));
+    // now Apply control bits and clear bytes 8..23 in the header
+    pop(rdx);
+    pop(rax);
+    movl(Address(rsp, XSTATE_BV), xcr0_eax);
+    movl(Address(rsp, XSTATE_BV+4), xcr0_edx);
+    andq(Address(rsp, XSTATE_BV+8), 0);
+    andq(Address(rsp, XSTATE_BV+16), 0);
+  } else {
+    fxsave(Address(rsp, 0));
+  }
 #endif // LP64
 }
 
@@ -4082,6 +4141,84 @@
   }
 }
 
+void MacroAssembler::vnegatess(XMMRegister dst, XMMRegister nds, AddressLiteral src) {
+  int nds_enc = nds->encoding();
+  int dst_enc = dst->encoding();
+  bool dst_upper_bank = (dst_enc > 15);
+  bool nds_upper_bank = (nds_enc > 15);
+  if (VM_Version::supports_avx512novl() &&
+      (nds_upper_bank || dst_upper_bank)) {
+    if (dst_upper_bank) {
+      subptr(rsp, 64);
+      evmovdqul(Address(rsp, 0), xmm0, Assembler::AVX_512bit);
+      movflt(xmm0, nds);
+      if (reachable(src)) {
+        vxorps(xmm0, xmm0, as_Address(src), Assembler::AVX_128bit);
+      } else {
+        lea(rscratch1, src);
+        vxorps(xmm0, xmm0, Address(rscratch1, 0), Assembler::AVX_128bit);
+      }
+      movflt(dst, xmm0);
+      evmovdqul(xmm0, Address(rsp, 0), Assembler::AVX_512bit);
+      addptr(rsp, 64);
+    } else {
+      movflt(dst, nds);
+      if (reachable(src)) {
+        vxorps(dst, dst, as_Address(src), Assembler::AVX_128bit);
+      } else {
+        lea(rscratch1, src);
+        vxorps(dst, dst, Address(rscratch1, 0), Assembler::AVX_128bit);
+      }
+    }
+  } else {
+    if (reachable(src)) {
+      vxorps(dst, nds, as_Address(src), Assembler::AVX_128bit);
+    } else {
+      lea(rscratch1, src);
+      vxorps(dst, nds, Address(rscratch1, 0), Assembler::AVX_128bit);
+    }
+  }
+}
+
+void MacroAssembler::vnegatesd(XMMRegister dst, XMMRegister nds, AddressLiteral src) {
+  int nds_enc = nds->encoding();
+  int dst_enc = dst->encoding();
+  bool dst_upper_bank = (dst_enc > 15);
+  bool nds_upper_bank = (nds_enc > 15);
+  if (VM_Version::supports_avx512novl() &&
+      (nds_upper_bank || dst_upper_bank)) {
+    if (dst_upper_bank) {
+      subptr(rsp, 64);
+      evmovdqul(Address(rsp, 0), xmm0, Assembler::AVX_512bit);
+      movdbl(xmm0, nds);
+      if (reachable(src)) {
+        vxorps(xmm0, xmm0, as_Address(src), Assembler::AVX_128bit);
+      } else {
+        lea(rscratch1, src);
+        vxorps(xmm0, xmm0, Address(rscratch1, 0), Assembler::AVX_128bit);
+      }
+      movdbl(dst, xmm0);
+      evmovdqul(xmm0, Address(rsp, 0), Assembler::AVX_512bit);
+      addptr(rsp, 64);
+    } else {
+      movdbl(dst, nds);
+      if (reachable(src)) {
+        vxorps(dst, dst, as_Address(src), Assembler::AVX_128bit);
+      } else {
+        lea(rscratch1, src);
+        vxorps(dst, dst, Address(rscratch1, 0), Assembler::AVX_128bit);
+      }
+    }
+  } else {
+    if (reachable(src)) {
+      vxorpd(dst, nds, as_Address(src), Assembler::AVX_128bit);
+    } else {
+      lea(rscratch1, src);
+      vxorpd(dst, nds, Address(rscratch1, 0), Assembler::AVX_128bit);
+    }
+  }
+}
+
 void MacroAssembler::vxorpd(XMMRegister dst, XMMRegister nds, AddressLiteral src, int vector_len) {
   if (reachable(src)) {
     vxorpd(dst, nds, as_Address(src), vector_len);
@@ -4318,7 +4455,6 @@
 void MacroAssembler::store_check(Register obj) {
   // Does a store check for the oop in register obj. The content of
   // register obj is destroyed afterwards.
-
   BarrierSet* bs = Universe::heap()->barrier_set();
   assert(bs->kind() == BarrierSet::CardTableForRS ||
          bs->kind() == BarrierSet::CardTableExtension,
@@ -4572,69 +4708,58 @@
 
   // if we are coming from c1, xmm registers may be live
   int off = 0;
+  int num_xmm_regs = LP64_ONLY(16) NOT_LP64(8);
+  if (UseAVX > 2) {
+    num_xmm_regs = LP64_ONLY(32) NOT_LP64(8);
+  }
+
   if (UseSSE == 1)  {
     subptr(rsp, sizeof(jdouble)*8);
-    movflt(Address(rsp,off++*sizeof(jdouble)),xmm0);
-    movflt(Address(rsp,off++*sizeof(jdouble)),xmm1);
-    movflt(Address(rsp,off++*sizeof(jdouble)),xmm2);
-    movflt(Address(rsp,off++*sizeof(jdouble)),xmm3);
-    movflt(Address(rsp,off++*sizeof(jdouble)),xmm4);
-    movflt(Address(rsp,off++*sizeof(jdouble)),xmm5);
-    movflt(Address(rsp,off++*sizeof(jdouble)),xmm6);
-    movflt(Address(rsp,off++*sizeof(jdouble)),xmm7);
+    for (int n = 0; n < 8; n++) {
+      movflt(Address(rsp, off++*sizeof(jdouble)), as_XMMRegister(n));
+    }
   } else if (UseSSE >= 2)  {
     if (UseAVX > 2) {
+      push(rbx);
       movl(rbx, 0xffff);
-#ifdef _LP64
-      kmovql(k1, rbx);
-#else
-      kmovdl(k1, rbx);
-#endif
+      kmovwl(k1, rbx);
+      pop(rbx);
     }
 #ifdef COMPILER2
     if (MaxVectorSize > 16) {
-      assert(UseAVX > 0, "256bit vectors are supported only with AVX");
+      if(UseAVX > 2) {
+        // Save upper half of ZMM registes
+        subptr(rsp, 32*num_xmm_regs);
+        for (int n = 0; n < num_xmm_regs; n++) {
+          vextractf64x4h(Address(rsp, off++*32), as_XMMRegister(n));
+        }
+        off = 0;
+      }
+      assert(UseAVX > 0, "256 bit vectors are supported only with AVX");
       // Save upper half of YMM registes
-      subptr(rsp, 16 * LP64_ONLY(16) NOT_LP64(8));
-      vextractf128h(Address(rsp,  0),xmm0);
-      vextractf128h(Address(rsp, 16),xmm1);
-      vextractf128h(Address(rsp, 32),xmm2);
-      vextractf128h(Address(rsp, 48),xmm3);
-      vextractf128h(Address(rsp, 64),xmm4);
-      vextractf128h(Address(rsp, 80),xmm5);
-      vextractf128h(Address(rsp, 96),xmm6);
-      vextractf128h(Address(rsp,112),xmm7);
-#ifdef _LP64
-      vextractf128h(Address(rsp,128),xmm8);
-      vextractf128h(Address(rsp,144),xmm9);
-      vextractf128h(Address(rsp,160),xmm10);
-      vextractf128h(Address(rsp,176),xmm11);
-      vextractf128h(Address(rsp,192),xmm12);
-      vextractf128h(Address(rsp,208),xmm13);
-      vextractf128h(Address(rsp,224),xmm14);
-      vextractf128h(Address(rsp,240),xmm15);
-#endif
+      subptr(rsp, 16*num_xmm_regs);
+      for (int n = 0; n < num_xmm_regs; n++) {
+        vextractf128h(Address(rsp, off++*16), as_XMMRegister(n));
+      }
     }
 #endif
-    // Save whole 128bit (16 bytes) XMM regiters
-    subptr(rsp, 16 * LP64_ONLY(16) NOT_LP64(8));
-    movdqu(Address(rsp,off++*16),xmm0);
-    movdqu(Address(rsp,off++*16),xmm1);
-    movdqu(Address(rsp,off++*16),xmm2);
-    movdqu(Address(rsp,off++*16),xmm3);
-    movdqu(Address(rsp,off++*16),xmm4);
-    movdqu(Address(rsp,off++*16),xmm5);
-    movdqu(Address(rsp,off++*16),xmm6);
-    movdqu(Address(rsp,off++*16),xmm7);
+    // Save whole 128bit (16 bytes) XMM registers
+    subptr(rsp, 16*num_xmm_regs);
+    off = 0;
 #ifdef _LP64
-    movdqu(Address(rsp,off++*16),xmm8);
-    movdqu(Address(rsp,off++*16),xmm9);
-    movdqu(Address(rsp,off++*16),xmm10);
-    movdqu(Address(rsp,off++*16),xmm11);
-    movdqu(Address(rsp,off++*16),xmm12);
-    movdqu(Address(rsp,off++*16),xmm13);
-    movdqu(Address(rsp,off++*16),xmm14);
-    movdqu(Address(rsp,off++*16),xmm15);
+    if (VM_Version::supports_avx512novl()) {
+      for (int n = 0; n < num_xmm_regs; n++) {
+        vextractf32x4h(Address(rsp, off++*16), as_XMMRegister(n), 0);
+      }
+    } else {
+      for (int n = 0; n < num_xmm_regs; n++) {
+        movdqu(Address(rsp, off++*16), as_XMMRegister(n));
+      }
+    }
+#else
+    for (int n = 0; n < num_xmm_regs; n++) {
+      movdqu(Address(rsp, off++*16), as_XMMRegister(n));
+    }
 #endif
   }
 
@@ -4689,7 +4814,7 @@
   movsd(Address(rsp, 0), xmm0);
   fld_d(Address(rsp, 0));
 #endif // _LP64
-  addptr(rsp, sizeof(jdouble) * nb_args);
+  addptr(rsp, sizeof(jdouble)*nb_args);
   if (num_fpu_regs_in_use > 1) {
     // Must save return value to stack and then restore entire FPU
     // stack except incoming arguments
@@ -4699,63 +4824,50 @@
       addptr(rsp, sizeof(jdouble));
     }
     fld_d(Address(rsp, (nb_args-1)*sizeof(jdouble)));
-    addptr(rsp, sizeof(jdouble) * nb_args);
+    addptr(rsp, sizeof(jdouble)*nb_args);
   }
 
   off = 0;
   if (UseSSE == 1)  {
-    movflt(xmm0, Address(rsp,off++*sizeof(jdouble)));
-    movflt(xmm1, Address(rsp,off++*sizeof(jdouble)));
-    movflt(xmm2, Address(rsp,off++*sizeof(jdouble)));
-    movflt(xmm3, Address(rsp,off++*sizeof(jdouble)));
-    movflt(xmm4, Address(rsp,off++*sizeof(jdouble)));
-    movflt(xmm5, Address(rsp,off++*sizeof(jdouble)));
-    movflt(xmm6, Address(rsp,off++*sizeof(jdouble)));
-    movflt(xmm7, Address(rsp,off++*sizeof(jdouble)));
+    for (int n = 0; n < 8; n++) {
+      movflt(as_XMMRegister(n), Address(rsp, off++*sizeof(jdouble)));
+    }
     addptr(rsp, sizeof(jdouble)*8);
   } else if (UseSSE >= 2)  {
     // Restore whole 128bit (16 bytes) XMM regiters
-    movdqu(xmm0, Address(rsp,off++*16));
-    movdqu(xmm1, Address(rsp,off++*16));
-    movdqu(xmm2, Address(rsp,off++*16));
-    movdqu(xmm3, Address(rsp,off++*16));
-    movdqu(xmm4, Address(rsp,off++*16));
-    movdqu(xmm5, Address(rsp,off++*16));
-    movdqu(xmm6, Address(rsp,off++*16));
-    movdqu(xmm7, Address(rsp,off++*16));
 #ifdef _LP64
-    movdqu(xmm8, Address(rsp,off++*16));
-    movdqu(xmm9, Address(rsp,off++*16));
-    movdqu(xmm10, Address(rsp,off++*16));
-    movdqu(xmm11, Address(rsp,off++*16));
-    movdqu(xmm12, Address(rsp,off++*16));
-    movdqu(xmm13, Address(rsp,off++*16));
-    movdqu(xmm14, Address(rsp,off++*16));
-    movdqu(xmm15, Address(rsp,off++*16));
+    if (VM_Version::supports_avx512novl()) {
+      for (int n = 0; n < num_xmm_regs; n++) {
+        vinsertf32x4h(as_XMMRegister(n), Address(rsp, off++*16), 0);
+      }
+    }
+    else {
+      for (int n = 0; n < num_xmm_regs; n++) {
+        movdqu(as_XMMRegister(n), Address(rsp, off++*16));
+      }
+    }
+#else
+    for (int n = 0; n < num_xmm_regs; n++) {
+      movdqu(as_XMMRegister(n), Address(rsp, off++ * 16));
+    }
 #endif
-    addptr(rsp, 16 * LP64_ONLY(16) NOT_LP64(8));
+    addptr(rsp, 16*num_xmm_regs);
+
 #ifdef COMPILER2
     if (MaxVectorSize > 16) {
       // Restore upper half of YMM registes.
-      vinsertf128h(xmm0, Address(rsp,  0));
-      vinsertf128h(xmm1, Address(rsp, 16));
-      vinsertf128h(xmm2, Address(rsp, 32));
-      vinsertf128h(xmm3, Address(rsp, 48));
-      vinsertf128h(xmm4, Address(rsp, 64));
-      vinsertf128h(xmm5, Address(rsp, 80));
-      vinsertf128h(xmm6, Address(rsp, 96));
-      vinsertf128h(xmm7, Address(rsp,112));
-#ifdef _LP64
-      vinsertf128h(xmm8, Address(rsp,128));
-      vinsertf128h(xmm9, Address(rsp,144));
-      vinsertf128h(xmm10, Address(rsp,160));
-      vinsertf128h(xmm11, Address(rsp,176));
-      vinsertf128h(xmm12, Address(rsp,192));
-      vinsertf128h(xmm13, Address(rsp,208));
-      vinsertf128h(xmm14, Address(rsp,224));
-      vinsertf128h(xmm15, Address(rsp,240));
-#endif
-      addptr(rsp, 16 * LP64_ONLY(16) NOT_LP64(8));
+      off = 0;
+      for (int n = 0; n < num_xmm_regs; n++) {
+        vinsertf128h(as_XMMRegister(n), Address(rsp, off++*16));
+      }
+      addptr(rsp, 16*num_xmm_regs);
+      if(UseAVX > 2) {
+        off = 0;
+        for (int n = 0; n < num_xmm_regs; n++) {
+          vinsertf64x4h(as_XMMRegister(n), Address(rsp, off++*32));
+        }
+        addptr(rsp, 32*num_xmm_regs);
+      }
     }
 #endif
   }
@@ -7095,11 +7207,7 @@
       Label L_fill_32_bytes_loop, L_check_fill_8_bytes, L_fill_8_bytes_loop, L_fill_8_bytes;
       if (UseAVX > 2) {
         movl(rtmp, 0xffff);
-#ifdef _LP64
-        kmovql(k1, rtmp);
-#else
-        kmovdl(k1, rtmp);
-#endif
+        kmovwl(k1, rtmp);
       }
       movdl(xtmp, value);
       if (UseAVX > 2 && UseUnalignedLoadStores) {
@@ -7112,7 +7220,7 @@
         align(16);
 
         BIND(L_fill_64_bytes_loop);
-        evmovdqu(Address(to, 0), xtmp, Assembler::AVX_512bit);
+        evmovdqul(Address(to, 0), xtmp, Assembler::AVX_512bit);
         addptr(to, 64);
         subl(count, 16 << shift);
         jcc(Assembler::greaterEqual, L_fill_64_bytes_loop);
@@ -7120,7 +7228,7 @@
         BIND(L_check_fill_32_bytes);
         addl(count, 8 << shift);
         jccb(Assembler::less, L_check_fill_8_bytes);
-        evmovdqu(Address(to, 0), xtmp, Assembler::AVX_256bit);
+        evmovdqul(Address(to, 0), xtmp, Assembler::AVX_256bit);
         addptr(to, 32);
         subl(count, 8 << shift);
 
@@ -8399,6 +8507,14 @@
   Label L_tail, L_tail_restore, L_tail_loop, L_exit, L_align_loop, L_aligned;
   Label L_fold_tail, L_fold_128b, L_fold_512b, L_fold_512b_loop, L_fold_tail_loop;
 
+  // For EVEX with VL and BW, provide a standard mask, VL = 128 will guide the merge
+  // context for the registers used, where all instructions below are using 128-bit mode
+  // On EVEX without VL and BW, these instructions will all be AVX.
+  if (VM_Version::supports_avx512vlbw()) {
+    movl(tmp, 0xffff);
+    kmovwl(k1, tmp);
+  }
+
   lea(table, ExternalAddress(StubRoutines::crc_table_addr()));
   notl(crc); // ~crc
   cmpl(len, 16);
--- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp	Sat Sep 26 09:22:24 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp	Wed Jul 05 20:51:27 2017 +0200
@@ -1069,6 +1069,9 @@
   void vsubss(XMMRegister dst, XMMRegister nds, Address src)     { Assembler::vsubss(dst, nds, src); }
   void vsubss(XMMRegister dst, XMMRegister nds, AddressLiteral src);
 
+  void vnegatess(XMMRegister dst, XMMRegister nds, AddressLiteral src);
+  void vnegatesd(XMMRegister dst, XMMRegister nds, AddressLiteral src);
+
   // AVX Vector instructions
 
   void vxorpd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) { Assembler::vxorpd(dst, nds, src, vector_len); }
--- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp	Sat Sep 26 09:22:24 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp	Wed Jul 05 20:51:27 2017 +0200
@@ -115,6 +115,7 @@
 OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_frame_words,
                                            int* total_frame_words, bool verify_fpu, bool save_vectors) {
   int vect_words = 0;
+  int num_xmm_regs = XMMRegisterImpl::number_of_registers;
 #ifdef COMPILER2
   if (save_vectors) {
     assert(UseAVX > 0, "512bit vectors are supported only with EVEX");
@@ -173,59 +174,50 @@
     __ fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_std()));
   }
 
+  int off = st0_off;
+  int delta = st1_off - off;
+
   // Save the FPU registers in de-opt-able form
-
-  __ fstp_d(Address(rsp, st0_off*wordSize)); // st(0)
-  __ fstp_d(Address(rsp, st1_off*wordSize)); // st(1)
-  __ fstp_d(Address(rsp, st2_off*wordSize)); // st(2)
-  __ fstp_d(Address(rsp, st3_off*wordSize)); // st(3)
-  __ fstp_d(Address(rsp, st4_off*wordSize)); // st(4)
-  __ fstp_d(Address(rsp, st5_off*wordSize)); // st(5)
-  __ fstp_d(Address(rsp, st6_off*wordSize)); // st(6)
-  __ fstp_d(Address(rsp, st7_off*wordSize)); // st(7)
-
-  if( UseSSE == 1 ) {           // Save the XMM state
-    __ movflt(Address(rsp,xmm0_off*wordSize),xmm0);
-    __ movflt(Address(rsp,xmm1_off*wordSize),xmm1);
-    __ movflt(Address(rsp,xmm2_off*wordSize),xmm2);
-    __ movflt(Address(rsp,xmm3_off*wordSize),xmm3);
-    __ movflt(Address(rsp,xmm4_off*wordSize),xmm4);
-    __ movflt(Address(rsp,xmm5_off*wordSize),xmm5);
-    __ movflt(Address(rsp,xmm6_off*wordSize),xmm6);
-    __ movflt(Address(rsp,xmm7_off*wordSize),xmm7);
-  } else if( UseSSE >= 2 ) {
+  for (int n = 0; n < FloatRegisterImpl::number_of_registers; n++) {
+    __ fstp_d(Address(rsp, off*wordSize));
+    off += delta;
+  }
+
+  off = xmm0_off;
+  delta = xmm1_off - off;
+  if(UseSSE == 1) {           // Save the XMM state
+    for (int n = 0; n < num_xmm_regs; n++) {
+      __ movflt(Address(rsp, off*wordSize), as_XMMRegister(n));
+      off += delta;
+    }
+  } else if(UseSSE >= 2) {
     // Save whole 128bit (16 bytes) XMM regiters
-    __ movdqu(Address(rsp,xmm0_off*wordSize),xmm0);
-    __ movdqu(Address(rsp,xmm1_off*wordSize),xmm1);
-    __ movdqu(Address(rsp,xmm2_off*wordSize),xmm2);
-    __ movdqu(Address(rsp,xmm3_off*wordSize),xmm3);
-    __ movdqu(Address(rsp,xmm4_off*wordSize),xmm4);
-    __ movdqu(Address(rsp,xmm5_off*wordSize),xmm5);
-    __ movdqu(Address(rsp,xmm6_off*wordSize),xmm6);
-    __ movdqu(Address(rsp,xmm7_off*wordSize),xmm7);
+    if (VM_Version::supports_avx512novl()) {
+      for (int n = 0; n < num_xmm_regs; n++) {
+        __ vextractf32x4h(Address(rsp, off*wordSize), as_XMMRegister(n), 0);
+        off += delta;
+      }
+    } else {
+      for (int n = 0; n < num_xmm_regs; n++) {
+        __ movdqu(Address(rsp, off*wordSize), as_XMMRegister(n));
+        off += delta;
+      }
+    }
   }
 
   if (vect_words > 0) {
     assert(vect_words*wordSize == 128, "");
     __ subptr(rsp, 128); // Save upper half of YMM registes
-    __ vextractf128h(Address(rsp,  0),xmm0);
-    __ vextractf128h(Address(rsp, 16),xmm1);
-    __ vextractf128h(Address(rsp, 32),xmm2);
-    __ vextractf128h(Address(rsp, 48),xmm3);
-    __ vextractf128h(Address(rsp, 64),xmm4);
-    __ vextractf128h(Address(rsp, 80),xmm5);
-    __ vextractf128h(Address(rsp, 96),xmm6);
-    __ vextractf128h(Address(rsp,112),xmm7);
+    off = 0;
+    for (int n = 0; n < num_xmm_regs; n++) {
+      __ vextractf128h(Address(rsp, off++*16), as_XMMRegister(n));
+    }
     if (UseAVX > 2) {
       __ subptr(rsp, 256); // Save upper half of ZMM registes
-      __ vextractf64x4h(Address(rsp, 0), xmm0);
-      __ vextractf64x4h(Address(rsp, 32), xmm1);
-      __ vextractf64x4h(Address(rsp, 64), xmm2);
-      __ vextractf64x4h(Address(rsp, 96), xmm3);
-      __ vextractf64x4h(Address(rsp, 128), xmm4);
-      __ vextractf64x4h(Address(rsp, 160), xmm5);
-      __ vextractf64x4h(Address(rsp, 192), xmm6);
-      __ vextractf64x4h(Address(rsp, 224), xmm7);
+      off = 0;
+      for (int n = 0; n < num_xmm_regs; n++) {
+        __ vextractf64x4h(Address(rsp, off++*32), as_XMMRegister(n));
+      }
     }
   }
 
@@ -238,58 +230,40 @@
   OopMap* map =  new OopMap( frame_words, 0 );
 
 #define STACK_OFFSET(x) VMRegImpl::stack2reg((x) + additional_frame_words)
-
-  map->set_callee_saved(STACK_OFFSET( rax_off), rax->as_VMReg());
-  map->set_callee_saved(STACK_OFFSET( rcx_off), rcx->as_VMReg());
-  map->set_callee_saved(STACK_OFFSET( rdx_off), rdx->as_VMReg());
-  map->set_callee_saved(STACK_OFFSET( rbx_off), rbx->as_VMReg());
+#define NEXTREG(x) (x)->as_VMReg()->next()
+
+  map->set_callee_saved(STACK_OFFSET(rax_off), rax->as_VMReg());
+  map->set_callee_saved(STACK_OFFSET(rcx_off), rcx->as_VMReg());
+  map->set_callee_saved(STACK_OFFSET(rdx_off), rdx->as_VMReg());
+  map->set_callee_saved(STACK_OFFSET(rbx_off), rbx->as_VMReg());
   // rbp, location is known implicitly, no oopMap
-  map->set_callee_saved(STACK_OFFSET( rsi_off), rsi->as_VMReg());
-  map->set_callee_saved(STACK_OFFSET( rdi_off), rdi->as_VMReg());
-  map->set_callee_saved(STACK_OFFSET(st0_off), as_FloatRegister(0)->as_VMReg());
-  map->set_callee_saved(STACK_OFFSET(st1_off), as_FloatRegister(1)->as_VMReg());
-  map->set_callee_saved(STACK_OFFSET(st2_off), as_FloatRegister(2)->as_VMReg());
-  map->set_callee_saved(STACK_OFFSET(st3_off), as_FloatRegister(3)->as_VMReg());
-  map->set_callee_saved(STACK_OFFSET(st4_off), as_FloatRegister(4)->as_VMReg());
-  map->set_callee_saved(STACK_OFFSET(st5_off), as_FloatRegister(5)->as_VMReg());
-  map->set_callee_saved(STACK_OFFSET(st6_off), as_FloatRegister(6)->as_VMReg());
-  map->set_callee_saved(STACK_OFFSET(st7_off), as_FloatRegister(7)->as_VMReg());
-  map->set_callee_saved(STACK_OFFSET(xmm0_off), xmm0->as_VMReg());
-  map->set_callee_saved(STACK_OFFSET(xmm1_off), xmm1->as_VMReg());
-  map->set_callee_saved(STACK_OFFSET(xmm2_off), xmm2->as_VMReg());
-  map->set_callee_saved(STACK_OFFSET(xmm3_off), xmm3->as_VMReg());
-  map->set_callee_saved(STACK_OFFSET(xmm4_off), xmm4->as_VMReg());
-  map->set_callee_saved(STACK_OFFSET(xmm5_off), xmm5->as_VMReg());
-  map->set_callee_saved(STACK_OFFSET(xmm6_off), xmm6->as_VMReg());
-  map->set_callee_saved(STACK_OFFSET(xmm7_off), xmm7->as_VMReg());
-  // %%% This is really a waste but we'll keep things as they were for now
-  if (true) {
-#define NEXTREG(x) (x)->as_VMReg()->next()
-    map->set_callee_saved(STACK_OFFSET(st0H_off), NEXTREG(as_FloatRegister(0)));
-    map->set_callee_saved(STACK_OFFSET(st1H_off), NEXTREG(as_FloatRegister(1)));
-    map->set_callee_saved(STACK_OFFSET(st2H_off), NEXTREG(as_FloatRegister(2)));
-    map->set_callee_saved(STACK_OFFSET(st3H_off), NEXTREG(as_FloatRegister(3)));
-    map->set_callee_saved(STACK_OFFSET(st4H_off), NEXTREG(as_FloatRegister(4)));
-    map->set_callee_saved(STACK_OFFSET(st5H_off), NEXTREG(as_FloatRegister(5)));
-    map->set_callee_saved(STACK_OFFSET(st6H_off), NEXTREG(as_FloatRegister(6)));
-    map->set_callee_saved(STACK_OFFSET(st7H_off), NEXTREG(as_FloatRegister(7)));
-    map->set_callee_saved(STACK_OFFSET(xmm0H_off), NEXTREG(xmm0));
-    map->set_callee_saved(STACK_OFFSET(xmm1H_off), NEXTREG(xmm1));
-    map->set_callee_saved(STACK_OFFSET(xmm2H_off), NEXTREG(xmm2));
-    map->set_callee_saved(STACK_OFFSET(xmm3H_off), NEXTREG(xmm3));
-    map->set_callee_saved(STACK_OFFSET(xmm4H_off), NEXTREG(xmm4));
-    map->set_callee_saved(STACK_OFFSET(xmm5H_off), NEXTREG(xmm5));
-    map->set_callee_saved(STACK_OFFSET(xmm6H_off), NEXTREG(xmm6));
-    map->set_callee_saved(STACK_OFFSET(xmm7H_off), NEXTREG(xmm7));
+  map->set_callee_saved(STACK_OFFSET(rsi_off), rsi->as_VMReg());
+  map->set_callee_saved(STACK_OFFSET(rdi_off), rdi->as_VMReg());
+  // %%% This is really a waste but we'll keep things as they were for now for the upper component
+  off = st0_off;
+  delta = st1_off - off;
+  for (int n = 0; n < FloatRegisterImpl::number_of_registers; n++) {
+    FloatRegister freg_name = as_FloatRegister(n);
+    map->set_callee_saved(STACK_OFFSET(off), freg_name->as_VMReg());
+    map->set_callee_saved(STACK_OFFSET(off+1), NEXTREG(freg_name));
+    off += delta;
+  }
+  off = xmm0_off;
+  delta = xmm1_off - off;
+  for (int n = 0; n < num_xmm_regs; n++) {
+    XMMRegister xmm_name = as_XMMRegister(n);
+    map->set_callee_saved(STACK_OFFSET(off), xmm_name->as_VMReg());
+    map->set_callee_saved(STACK_OFFSET(off+1), NEXTREG(xmm_name));
+    off += delta;
+  }
 #undef NEXTREG
 #undef STACK_OFFSET
-  }
 
   return map;
-
 }
 
 void RegisterSaver::restore_live_registers(MacroAssembler* masm, bool restore_vectors) {
+  int num_xmm_regs = XMMRegisterImpl::number_of_registers;
   // Recover XMM & FPU state
   int additional_frame_bytes = 0;
 #ifdef COMPILER2
@@ -301,52 +275,43 @@
 #else
   assert(!restore_vectors, "vectors are generated only by C2");
 #endif
+  int off = xmm0_off;
+  int delta = xmm1_off - off;
+
   if (UseSSE == 1) {
     assert(additional_frame_bytes == 0, "");
-    __ movflt(xmm0,Address(rsp,xmm0_off*wordSize));
-    __ movflt(xmm1,Address(rsp,xmm1_off*wordSize));
-    __ movflt(xmm2,Address(rsp,xmm2_off*wordSize));
-    __ movflt(xmm3,Address(rsp,xmm3_off*wordSize));
-    __ movflt(xmm4,Address(rsp,xmm4_off*wordSize));
-    __ movflt(xmm5,Address(rsp,xmm5_off*wordSize));
-    __ movflt(xmm6,Address(rsp,xmm6_off*wordSize));
-    __ movflt(xmm7,Address(rsp,xmm7_off*wordSize));
+    for (int n = 0; n < num_xmm_regs; n++) {
+      __ movflt(as_XMMRegister(n), Address(rsp, off*wordSize));
+      off += delta;
+    }
   } else if (UseSSE >= 2) {
-#define STACK_ADDRESS(x) Address(rsp,(x)*wordSize + additional_frame_bytes)
-    __ movdqu(xmm0,STACK_ADDRESS(xmm0_off));
-    __ movdqu(xmm1,STACK_ADDRESS(xmm1_off));
-    __ movdqu(xmm2,STACK_ADDRESS(xmm2_off));
-    __ movdqu(xmm3,STACK_ADDRESS(xmm3_off));
-    __ movdqu(xmm4,STACK_ADDRESS(xmm4_off));
-    __ movdqu(xmm5,STACK_ADDRESS(xmm5_off));
-    __ movdqu(xmm6,STACK_ADDRESS(xmm6_off));
-    __ movdqu(xmm7,STACK_ADDRESS(xmm7_off));
-#undef STACK_ADDRESS
+    if (VM_Version::supports_avx512novl()) {
+      for (int n = 0; n < num_xmm_regs; n++) {
+        __ vinsertf32x4h(as_XMMRegister(n), Address(rsp, off*wordSize+additional_frame_bytes), 0);
+        off += delta;
+      }
+    } else {
+      for (int n = 0; n < num_xmm_regs; n++) {
+        __ movdqu(as_XMMRegister(n), Address(rsp, off*wordSize+additional_frame_bytes));
+        off += delta;
+      }
+    }
   }
   if (restore_vectors) {
+    if (UseAVX > 2) {
+      off = 0;
+      for (int n = 0; n < num_xmm_regs; n++) {
+        __ vinsertf64x4h(as_XMMRegister(n), Address(rsp, off++*32));
+      }
+      __ addptr(rsp, additional_frame_bytes*2); // Save upper half of ZMM registes
+    }
     // Restore upper half of YMM registes.
     assert(additional_frame_bytes == 128, "");
-    __ vinsertf128h(xmm0, Address(rsp,  0));
-    __ vinsertf128h(xmm1, Address(rsp, 16));
-    __ vinsertf128h(xmm2, Address(rsp, 32));
-    __ vinsertf128h(xmm3, Address(rsp, 48));
-    __ vinsertf128h(xmm4, Address(rsp, 64));
-    __ vinsertf128h(xmm5, Address(rsp, 80));
-    __ vinsertf128h(xmm6, Address(rsp, 96));
-    __ vinsertf128h(xmm7, Address(rsp,112));
-    __ addptr(rsp, additional_frame_bytes);
-    if (UseAVX > 2) {
-      additional_frame_bytes = 256;
-      __ vinsertf64x4h(xmm0, Address(rsp, 0));
-      __ vinsertf64x4h(xmm1, Address(rsp, 32));
-      __ vinsertf64x4h(xmm2, Address(rsp, 64));
-      __ vinsertf64x4h(xmm3, Address(rsp, 96));
-      __ vinsertf64x4h(xmm4, Address(rsp, 128));
-      __ vinsertf64x4h(xmm5, Address(rsp, 160));
-      __ vinsertf64x4h(xmm6, Address(rsp, 192));
-      __ vinsertf64x4h(xmm7, Address(rsp, 224));
-      __ addptr(rsp, additional_frame_bytes);
+    off = 0;
+    for (int n = 0; n < num_xmm_regs; n++) {
+      __ vinsertf128h(as_XMMRegister(n), Address(rsp, off++*16));
     }
+    __ addptr(rsp, additional_frame_bytes); // Save upper half of YMM registes
   }
   __ pop_FPU_state();
   __ addptr(rsp, FPU_regs_live*wordSize); // Pop FPU registers
--- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp	Sat Sep 26 09:22:24 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp	Wed Jul 05 20:51:27 2017 +0200
@@ -69,7 +69,9 @@
 class RegisterSaver {
   // Capture info about frame layout.  Layout offsets are in jint
   // units because compiler frame slots are jints.
+#define HALF_ZMM_BANK_WORDS 128
 #define DEF_XMM_OFFS(regnum) xmm ## regnum ## _off = xmm_off + (regnum)*16/BytesPerInt, xmm ## regnum ## H_off
+#define DEF_ZMM_OFFS(regnum) zmm ## regnum ## _off = zmm_off + (regnum-16)*64/BytesPerInt, zmm ## regnum ## H_off
   enum layout {
     fpu_state_off = frame::arg_reg_save_area_bytes/BytesPerInt, // fxsave save area
     xmm_off       = fpu_state_off + 160/BytesPerInt,            // offset in fxsave save area
@@ -89,23 +91,24 @@
     DEF_XMM_OFFS(13),
     DEF_XMM_OFFS(14),
     DEF_XMM_OFFS(15),
-    DEF_XMM_OFFS(16),
-    DEF_XMM_OFFS(17),
-    DEF_XMM_OFFS(18),
-    DEF_XMM_OFFS(19),
-    DEF_XMM_OFFS(20),
-    DEF_XMM_OFFS(21),
-    DEF_XMM_OFFS(22),
-    DEF_XMM_OFFS(23),
-    DEF_XMM_OFFS(24),
-    DEF_XMM_OFFS(25),
-    DEF_XMM_OFFS(26),
-    DEF_XMM_OFFS(27),
-    DEF_XMM_OFFS(28),
-    DEF_XMM_OFFS(29),
-    DEF_XMM_OFFS(30),
-    DEF_XMM_OFFS(31),
-    fpu_state_end = fpu_state_off + ((FPUStateSizeInWords - 1)*wordSize / BytesPerInt),
+    zmm_off = fpu_state_off + ((FPUStateSizeInWords - (HALF_ZMM_BANK_WORDS + 1))*wordSize / BytesPerInt),
+    DEF_ZMM_OFFS(16),
+    DEF_ZMM_OFFS(17),
+    DEF_ZMM_OFFS(18),
+    DEF_ZMM_OFFS(19),
+    DEF_ZMM_OFFS(20),
+    DEF_ZMM_OFFS(21),
+    DEF_ZMM_OFFS(22),
+    DEF_ZMM_OFFS(23),
+    DEF_ZMM_OFFS(24),
+    DEF_ZMM_OFFS(25),
+    DEF_ZMM_OFFS(26),
+    DEF_ZMM_OFFS(27),
+    DEF_ZMM_OFFS(28),
+    DEF_ZMM_OFFS(29),
+    DEF_ZMM_OFFS(30),
+    DEF_ZMM_OFFS(31),
+    fpu_state_end = fpu_state_off + ((FPUStateSizeInWords-1)*wordSize / BytesPerInt),
     fpu_stateH_end,
     r15_off, r15H_off,
     r14_off, r14H_off,
@@ -155,9 +158,10 @@
 
 OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_frame_words, int* total_frame_words, bool save_vectors) {
   int vect_words = 0;
-  int num_xmm_regs = 16;
-  if (UseAVX > 2) {
-    num_xmm_regs = 32;
+  int off = 0;
+  int num_xmm_regs = XMMRegisterImpl::number_of_registers;
+  if (UseAVX < 3) {
+    num_xmm_regs = num_xmm_regs/2;
   }
 #ifdef COMPILER2
   if (save_vectors) {
@@ -165,9 +169,7 @@
     assert(MaxVectorSize == 64, "only 512bit vectors are supported now");
     // Save upper half of YMM registers
     vect_words = 16 * num_xmm_regs / wordSize;
-    additional_frame_words += vect_words;
-    if (UseAVX > 2) {
-      // Save upper half of ZMM registers as well
+    if (UseAVX < 3) {
       additional_frame_words += vect_words;
     }
   }
@@ -195,77 +197,13 @@
   __ enter();          // rsp becomes 16-byte aligned here
   __ push_CPU_state(); // Push a multiple of 16 bytes
 
-  if (vect_words > 0) {
+  // push cpu state handles this on EVEX enabled targets
+  if ((vect_words > 0) && (UseAVX < 3)) {
     assert(vect_words*wordSize >= 256, "");
-    __ subptr(rsp, 256); // Save upper half of YMM registes(0..15)
-    __ vextractf128h(Address(rsp, 0), xmm0);
-    __ vextractf128h(Address(rsp, 16), xmm1);
-    __ vextractf128h(Address(rsp, 32), xmm2);
-    __ vextractf128h(Address(rsp, 48), xmm3);
-    __ vextractf128h(Address(rsp, 64), xmm4);
-    __ vextractf128h(Address(rsp, 80), xmm5);
-    __ vextractf128h(Address(rsp, 96), xmm6);
-    __ vextractf128h(Address(rsp, 112), xmm7);
-    __ vextractf128h(Address(rsp, 128), xmm8);
-    __ vextractf128h(Address(rsp, 144), xmm9);
-    __ vextractf128h(Address(rsp, 160), xmm10);
-    __ vextractf128h(Address(rsp, 176), xmm11);
-    __ vextractf128h(Address(rsp, 192), xmm12);
-    __ vextractf128h(Address(rsp, 208), xmm13);
-    __ vextractf128h(Address(rsp, 224), xmm14);
-    __ vextractf128h(Address(rsp, 240), xmm15);
-    if (UseAVX > 2) {
-      __ subptr(rsp, 256); // Save upper half of YMM registes(16..31)
-      __ vextractf128h(Address(rsp, 0), xmm16);
-      __ vextractf128h(Address(rsp, 16), xmm17);
-      __ vextractf128h(Address(rsp, 32), xmm18);
-      __ vextractf128h(Address(rsp, 48), xmm19);
-      __ vextractf128h(Address(rsp, 64), xmm20);
-      __ vextractf128h(Address(rsp, 80), xmm21);
-      __ vextractf128h(Address(rsp, 96), xmm22);
-      __ vextractf128h(Address(rsp, 112), xmm23);
-      __ vextractf128h(Address(rsp, 128), xmm24);
-      __ vextractf128h(Address(rsp, 144), xmm25);
-      __ vextractf128h(Address(rsp, 160), xmm26);
-      __ vextractf128h(Address(rsp, 176), xmm27);
-      __ vextractf128h(Address(rsp, 192), xmm28);
-      __ vextractf128h(Address(rsp, 208), xmm29);
-      __ vextractf128h(Address(rsp, 224), xmm30);
-      __ vextractf128h(Address(rsp, 240), xmm31);
-      // Now handle the ZMM registers (0..31)
-      __ subptr(rsp, 1024); // Save upper half of ZMM registes
-      __ vextractf64x4h(Address(rsp, 0), xmm0);
-      __ vextractf64x4h(Address(rsp, 32), xmm1);
-      __ vextractf64x4h(Address(rsp, 64), xmm2);
-      __ vextractf64x4h(Address(rsp, 96), xmm3);
-      __ vextractf64x4h(Address(rsp, 128), xmm4);
-      __ vextractf64x4h(Address(rsp, 160), xmm5);
-      __ vextractf64x4h(Address(rsp, 192), xmm6);
-      __ vextractf64x4h(Address(rsp, 224), xmm7);
-      __ vextractf64x4h(Address(rsp, 256), xmm8);
-      __ vextractf64x4h(Address(rsp, 288), xmm9);
-      __ vextractf64x4h(Address(rsp, 320), xmm10);
-      __ vextractf64x4h(Address(rsp, 352), xmm11);
-      __ vextractf64x4h(Address(rsp, 384), xmm12);
-      __ vextractf64x4h(Address(rsp, 416), xmm13);
-      __ vextractf64x4h(Address(rsp, 448), xmm14);
-      __ vextractf64x4h(Address(rsp, 480), xmm15);
-      __ vextractf64x4h(Address(rsp, 512), xmm16);
-      __ vextractf64x4h(Address(rsp, 544), xmm17);
-      __ vextractf64x4h(Address(rsp, 576), xmm18);
-      __ vextractf64x4h(Address(rsp, 608), xmm19);
-      __ vextractf64x4h(Address(rsp, 640), xmm20);
-      __ vextractf64x4h(Address(rsp, 672), xmm21);
-      __ vextractf64x4h(Address(rsp, 704), xmm22);
-      __ vextractf64x4h(Address(rsp, 736), xmm23);
-      __ vextractf64x4h(Address(rsp, 768), xmm24);
-      __ vextractf64x4h(Address(rsp, 800), xmm25);
-      __ vextractf64x4h(Address(rsp, 832), xmm26);
-      __ vextractf64x4h(Address(rsp, 864), xmm27);
-      __ vextractf64x4h(Address(rsp, 896), xmm28);
-      __ vextractf64x4h(Address(rsp, 928), xmm29);
-      __ vextractf64x4h(Address(rsp, 960), xmm30);
-      __ vextractf64x4h(Address(rsp, 992), xmm31);
+    // Save upper half of YMM registes(0..num_xmm_regs)
+    __ subptr(rsp, num_xmm_regs*16);
+    for (int n = 0; n < num_xmm_regs; n++) {
+      __ vextractf128h(Address(rsp, off++*16), as_XMMRegister(n));
     }
   }
   if (frame::arg_reg_save_area_bytes != 0) {
@@ -299,39 +237,24 @@
   map->set_callee_saved(STACK_OFFSET( r13_off ), r13->as_VMReg());
   map->set_callee_saved(STACK_OFFSET( r14_off ), r14->as_VMReg());
   map->set_callee_saved(STACK_OFFSET( r15_off ), r15->as_VMReg());
-  map->set_callee_saved(STACK_OFFSET(xmm0_off ), xmm0->as_VMReg());
-  map->set_callee_saved(STACK_OFFSET(xmm1_off ), xmm1->as_VMReg());
-  map->set_callee_saved(STACK_OFFSET(xmm2_off ), xmm2->as_VMReg());
-  map->set_callee_saved(STACK_OFFSET(xmm3_off ), xmm3->as_VMReg());
-  map->set_callee_saved(STACK_OFFSET(xmm4_off ), xmm4->as_VMReg());
-  map->set_callee_saved(STACK_OFFSET(xmm5_off ), xmm5->as_VMReg());
-  map->set_callee_saved(STACK_OFFSET(xmm6_off ), xmm6->as_VMReg());
-  map->set_callee_saved(STACK_OFFSET(xmm7_off ), xmm7->as_VMReg());
-  map->set_callee_saved(STACK_OFFSET(xmm8_off ), xmm8->as_VMReg());
-  map->set_callee_saved(STACK_OFFSET(xmm9_off ), xmm9->as_VMReg());
-  map->set_callee_saved(STACK_OFFSET(xmm10_off), xmm10->as_VMReg());
-  map->set_callee_saved(STACK_OFFSET(xmm11_off), xmm11->as_VMReg());
-  map->set_callee_saved(STACK_OFFSET(xmm12_off), xmm12->as_VMReg());
-  map->set_callee_saved(STACK_OFFSET(xmm13_off), xmm13->as_VMReg());
-  map->set_callee_saved(STACK_OFFSET(xmm14_off), xmm14->as_VMReg());
-  map->set_callee_saved(STACK_OFFSET(xmm15_off), xmm15->as_VMReg());
-  if (UseAVX > 2) {
-    map->set_callee_saved(STACK_OFFSET(xmm16_off), xmm16->as_VMReg());
-    map->set_callee_saved(STACK_OFFSET(xmm17_off), xmm17->as_VMReg());
-    map->set_callee_saved(STACK_OFFSET(xmm18_off), xmm18->as_VMReg());
-    map->set_callee_saved(STACK_OFFSET(xmm19_off), xmm19->as_VMReg());
-    map->set_callee_saved(STACK_OFFSET(xmm20_off), xmm20->as_VMReg());
-    map->set_callee_saved(STACK_OFFSET(xmm21_off), xmm21->as_VMReg());
-    map->set_callee_saved(STACK_OFFSET(xmm22_off), xmm22->as_VMReg());
-    map->set_callee_saved(STACK_OFFSET(xmm23_off), xmm23->as_VMReg());
-    map->set_callee_saved(STACK_OFFSET(xmm24_off), xmm24->as_VMReg());
-    map->set_callee_saved(STACK_OFFSET(xmm25_off), xmm25->as_VMReg());
-    map->set_callee_saved(STACK_OFFSET(xmm26_off), xmm26->as_VMReg());
-    map->set_callee_saved(STACK_OFFSET(xmm27_off), xmm27->as_VMReg());
-    map->set_callee_saved(STACK_OFFSET(xmm28_off), xmm28->as_VMReg());
-    map->set_callee_saved(STACK_OFFSET(xmm29_off), xmm29->as_VMReg());
-    map->set_callee_saved(STACK_OFFSET(xmm30_off), xmm30->as_VMReg());
-    map->set_callee_saved(STACK_OFFSET(xmm31_off), xmm31->as_VMReg());
+  // For both AVX and EVEX we will use the legacy FXSAVE area for xmm0..xmm15,
+  // on EVEX enabled targets, we get it included in the xsave area
+  off = xmm0_off;
+  int delta = xmm1_off - off;
+  for (int n = 0; n < 16; n++) {
+    XMMRegister xmm_name = as_XMMRegister(n);
+    map->set_callee_saved(STACK_OFFSET(off), xmm_name->as_VMReg());
+    off += delta;
+  }
+  if(UseAVX > 2) {
+    // Obtain xmm16..xmm31 from the XSAVE area on EVEX enabled targets
+    off = zmm16_off;
+    delta = zmm17_off - off;
+    for (int n = 16; n < num_xmm_regs; n++) {
+      XMMRegister xmm_name = as_XMMRegister(n);
+      map->set_callee_saved(STACK_OFFSET(off), xmm_name->as_VMReg());
+      off += delta;
+    }
   }
 
   // %%% These should all be a waste but we'll keep things as they were for now
@@ -351,39 +274,24 @@
     map->set_callee_saved(STACK_OFFSET( r13H_off ), r13->as_VMReg()->next());
     map->set_callee_saved(STACK_OFFSET( r14H_off ), r14->as_VMReg()->next());
     map->set_callee_saved(STACK_OFFSET( r15H_off ), r15->as_VMReg()->next());
-    map->set_callee_saved(STACK_OFFSET(xmm0H_off ), xmm0->as_VMReg()->next());
-    map->set_callee_saved(STACK_OFFSET(xmm1H_off ), xmm1->as_VMReg()->next());
-    map->set_callee_saved(STACK_OFFSET(xmm2H_off ), xmm2->as_VMReg()->next());
-    map->set_callee_saved(STACK_OFFSET(xmm3H_off ), xmm3->as_VMReg()->next());
-    map->set_callee_saved(STACK_OFFSET(xmm4H_off ), xmm4->as_VMReg()->next());
-    map->set_callee_saved(STACK_OFFSET(xmm5H_off ), xmm5->as_VMReg()->next());
-    map->set_callee_saved(STACK_OFFSET(xmm6H_off ), xmm6->as_VMReg()->next());
-    map->set_callee_saved(STACK_OFFSET(xmm7H_off ), xmm7->as_VMReg()->next());
-    map->set_callee_saved(STACK_OFFSET(xmm8H_off ), xmm8->as_VMReg()->next());
-    map->set_callee_saved(STACK_OFFSET(xmm9H_off ), xmm9->as_VMReg()->next());
-    map->set_callee_saved(STACK_OFFSET(xmm10H_off), xmm10->as_VMReg()->next());
-    map->set_callee_saved(STACK_OFFSET(xmm11H_off), xmm11->as_VMReg()->next());
-    map->set_callee_saved(STACK_OFFSET(xmm12H_off), xmm12->as_VMReg()->next());
-    map->set_callee_saved(STACK_OFFSET(xmm13H_off), xmm13->as_VMReg()->next());
-    map->set_callee_saved(STACK_OFFSET(xmm14H_off), xmm14->as_VMReg()->next());
-    map->set_callee_saved(STACK_OFFSET(xmm15H_off), xmm15->as_VMReg()->next());
+    // For both AVX and EVEX we will use the legacy FXSAVE area for xmm0..xmm15,
+    // on EVEX enabled targets, we get it included in the xsave area
+    off = xmm0H_off;
+    delta = xmm1H_off - off;
+    for (int n = 0; n < 16; n++) {
+      XMMRegister xmm_name = as_XMMRegister(n);
+      map->set_callee_saved(STACK_OFFSET(off), xmm_name->as_VMReg()->next());
+      off += delta;
+    }
     if (UseAVX > 2) {
-      map->set_callee_saved(STACK_OFFSET(xmm16H_off), xmm16->as_VMReg()->next());
-      map->set_callee_saved(STACK_OFFSET(xmm17H_off), xmm17->as_VMReg()->next());
-      map->set_callee_saved(STACK_OFFSET(xmm18H_off), xmm18->as_VMReg()->next());
-      map->set_callee_saved(STACK_OFFSET(xmm19H_off), xmm19->as_VMReg()->next());
-      map->set_callee_saved(STACK_OFFSET(xmm20H_off), xmm20->as_VMReg()->next());
-      map->set_callee_saved(STACK_OFFSET(xmm21H_off), xmm21->as_VMReg()->next());
-      map->set_callee_saved(STACK_OFFSET(xmm22H_off), xmm22->as_VMReg()->next());
-      map->set_callee_saved(STACK_OFFSET(xmm23H_off), xmm23->as_VMReg()->next());
-      map->set_callee_saved(STACK_OFFSET(xmm24H_off), xmm24->as_VMReg()->next());
-      map->set_callee_saved(STACK_OFFSET(xmm25H_off), xmm25->as_VMReg()->next());
-      map->set_callee_saved(STACK_OFFSET(xmm26H_off), xmm26->as_VMReg()->next());
-      map->set_callee_saved(STACK_OFFSET(xmm27H_off), xmm27->as_VMReg()->next());
-      map->set_callee_saved(STACK_OFFSET(xmm28H_off), xmm28->as_VMReg()->next());
-      map->set_callee_saved(STACK_OFFSET(xmm29H_off), xmm29->as_VMReg()->next());
-      map->set_callee_saved(STACK_OFFSET(xmm30H_off), xmm30->as_VMReg()->next());
-      map->set_callee_saved(STACK_OFFSET(xmm31H_off), xmm31->as_VMReg()->next());
+      // Obtain xmm16..xmm31 from the XSAVE area on EVEX enabled targets
+      off = zmm16H_off;
+      delta = zmm17H_off - off;
+      for (int n = 16; n < num_xmm_regs; n++) {
+        XMMRegister xmm_name = as_XMMRegister(n);
+        map->set_callee_saved(STACK_OFFSET(off), xmm_name->as_VMReg()->next());
+        off += delta;
+      }
     }
   }
 
@@ -391,86 +299,25 @@
 }
 
 void RegisterSaver::restore_live_registers(MacroAssembler* masm, bool restore_vectors) {
+  int num_xmm_regs = XMMRegisterImpl::number_of_registers;
+  if (UseAVX < 3) {
+    num_xmm_regs = num_xmm_regs/2;
+  }
   if (frame::arg_reg_save_area_bytes != 0) {
     // Pop arg register save area
     __ addptr(rsp, frame::arg_reg_save_area_bytes);
   }
 #ifdef COMPILER2
-  if (restore_vectors) {
-    // Restore upper half of YMM registes (0..15)
-    assert(UseAVX > 0, "512bit vectors are supported only with AVX");
-    assert(MaxVectorSize == 64, "only 512bit vectors are supported now");
-    __ vinsertf128h(xmm0, Address(rsp,  0));
-    __ vinsertf128h(xmm1, Address(rsp, 16));
-    __ vinsertf128h(xmm2, Address(rsp, 32));
-    __ vinsertf128h(xmm3, Address(rsp, 48));
-    __ vinsertf128h(xmm4, Address(rsp, 64));
-    __ vinsertf128h(xmm5, Address(rsp, 80));
-    __ vinsertf128h(xmm6, Address(rsp, 96));
-    __ vinsertf128h(xmm7, Address(rsp,112));
-    __ vinsertf128h(xmm8, Address(rsp,128));
-    __ vinsertf128h(xmm9, Address(rsp,144));
-    __ vinsertf128h(xmm10, Address(rsp,160));
-    __ vinsertf128h(xmm11, Address(rsp,176));
-    __ vinsertf128h(xmm12, Address(rsp,192));
-    __ vinsertf128h(xmm13, Address(rsp,208));
-    __ vinsertf128h(xmm14, Address(rsp,224));
-    __ vinsertf128h(xmm15, Address(rsp,240));
-    __ addptr(rsp, 256);
-    if (UseAVX > 2) {
-      // Restore upper half of YMM registes (16..31)
-      __ vinsertf128h(xmm16, Address(rsp,  0));
-      __ vinsertf128h(xmm17, Address(rsp, 16));
-      __ vinsertf128h(xmm18, Address(rsp, 32));
-      __ vinsertf128h(xmm19, Address(rsp, 48));
-      __ vinsertf128h(xmm20, Address(rsp, 64));
-      __ vinsertf128h(xmm21, Address(rsp, 80));
-      __ vinsertf128h(xmm22, Address(rsp, 96));
-      __ vinsertf128h(xmm23, Address(rsp,112));
-      __ vinsertf128h(xmm24, Address(rsp,128));
-      __ vinsertf128h(xmm25, Address(rsp,144));
-      __ vinsertf128h(xmm26, Address(rsp,160));
-      __ vinsertf128h(xmm27, Address(rsp,176));
-      __ vinsertf128h(xmm28, Address(rsp,192));
-      __ vinsertf128h(xmm29, Address(rsp,208));
-      __ vinsertf128h(xmm30, Address(rsp,224));
-      __ vinsertf128h(xmm31, Address(rsp,240));
-      __ addptr(rsp, 256);
-      // Restore upper half of ZMM registes.
-      __ vinsertf64x4h(xmm0, Address(rsp, 0));
-      __ vinsertf64x4h(xmm1, Address(rsp, 32));
-      __ vinsertf64x4h(xmm2, Address(rsp, 64));
-      __ vinsertf64x4h(xmm3, Address(rsp, 96));
-      __ vinsertf64x4h(xmm4, Address(rsp, 128));
-      __ vinsertf64x4h(xmm5, Address(rsp, 160));
-      __ vinsertf64x4h(xmm6, Address(rsp, 192));
-      __ vinsertf64x4h(xmm7, Address(rsp, 224));
-      __ vinsertf64x4h(xmm8, Address(rsp, 256));
-      __ vinsertf64x4h(xmm9, Address(rsp, 288));
-      __ vinsertf64x4h(xmm10, Address(rsp, 320));
-      __ vinsertf64x4h(xmm11, Address(rsp, 352));
-      __ vinsertf64x4h(xmm12, Address(rsp, 384));
-      __ vinsertf64x4h(xmm13, Address(rsp, 416));
-      __ vinsertf64x4h(xmm14, Address(rsp, 448));
-      __ vinsertf64x4h(xmm15, Address(rsp, 480));
-      __ vinsertf64x4h(xmm16, Address(rsp, 512));
-      __ vinsertf64x4h(xmm17, Address(rsp, 544));
-      __ vinsertf64x4h(xmm18, Address(rsp, 576));
-      __ vinsertf64x4h(xmm19, Address(rsp, 608));
-      __ vinsertf64x4h(xmm20, Address(rsp, 640));
-      __ vinsertf64x4h(xmm21, Address(rsp, 672));
-      __ vinsertf64x4h(xmm22, Address(rsp, 704));
-      __ vinsertf64x4h(xmm23, Address(rsp, 736));
-      __ vinsertf64x4h(xmm24, Address(rsp, 768));
-      __ vinsertf64x4h(xmm25, Address(rsp, 800));
-      __ vinsertf64x4h(xmm26, Address(rsp, 832));
-      __ vinsertf64x4h(xmm27, Address(rsp, 864));
-      __ vinsertf64x4h(xmm28, Address(rsp, 896));
-      __ vinsertf64x4h(xmm29, Address(rsp, 928));
-      __ vinsertf64x4h(xmm30, Address(rsp, 960));
-      __ vinsertf64x4h(xmm31, Address(rsp, 992));
-      __ addptr(rsp, 1024);
+  // On EVEX enabled targets everything is handled in pop fpu state
+  if ((restore_vectors) && (UseAVX < 3)) {
+    assert(UseAVX > 0, "256/512-bit vectors are supported only with AVX");
+    assert(MaxVectorSize == 64, "up to 512bit vectors are supported now");
+    int off = 0;
+    // Restore upper half of YMM registes (0..num_xmm_regs)
+    for (int n = 0; n < num_xmm_regs; n++) {
+      __ vinsertf128h(as_XMMRegister(n), Address(rsp,  off++*16));
     }
+    __ addptr(rsp, num_xmm_regs*16);
   }
 #else
   assert(!restore_vectors, "vectors are generated only by C2");
--- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp	Sat Sep 26 09:22:24 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp	Wed Jul 05 20:51:27 2017 +0200
@@ -795,6 +795,12 @@
   void xmm_copy_forward(Register from, Register to_from, Register qword_count) {
     assert( UseSSE >= 2, "supported cpu only" );
     Label L_copy_64_bytes_loop, L_copy_64_bytes, L_copy_8_bytes, L_exit;
+    if (UseAVX > 2) {
+      __ push(rbx);
+      __ movl(rbx, 0xffff);
+      __ kmovdl(k1, rbx);
+      __ pop(rbx);
+    }
     // Copy 64-byte chunks
     __ jmpb(L_copy_64_bytes);
     __ align(OptoLoopAlignment);
@@ -802,8 +808,8 @@
 
     if (UseUnalignedLoadStores) {
       if (UseAVX > 2) {
-        __ evmovdqu(xmm0, Address(from, 0), Assembler::AVX_512bit);
-        __ evmovdqu(Address(from, to_from, Address::times_1, 0), xmm0, Assembler::AVX_512bit);
+        __ evmovdqul(xmm0, Address(from, 0), Assembler::AVX_512bit);
+        __ evmovdqul(Address(from, to_from, Address::times_1, 0), xmm0, Assembler::AVX_512bit);
       } else if (UseAVX == 2) {
         __ vmovdqu(xmm0, Address(from,  0));
         __ vmovdqu(Address(from, to_from, Address::times_1,  0), xmm0);
@@ -2217,6 +2223,15 @@
     const XMMRegister xmm_temp4  = xmm5;
 
     __ enter();   // required for proper stackwalking of RuntimeStub frame
+
+    // For EVEX with VL and BW, provide a standard mask, VL = 128 will guide the merge
+    // context for the registers used, where all instructions below are using 128-bit mode
+    // On EVEX without VL and BW, these instructions will all be AVX.
+    if (VM_Version::supports_avx512vlbw()) {
+      __ movl(rdx, 0xffff);
+      __ kmovdl(k1, rdx);
+    }
+
     __ movptr(from, from_param);
     __ movptr(key, key_param);
 
@@ -2315,6 +2330,15 @@
     const XMMRegister xmm_temp4  = xmm5;
 
     __ enter(); // required for proper stackwalking of RuntimeStub frame
+
+    // For EVEX with VL and BW, provide a standard mask, VL = 128 will guide the merge
+    // context for the registers used, where all instructions below are using 128-bit mode
+    // On EVEX without VL and BW, these instructions will all be AVX.
+    if (VM_Version::supports_avx512vlbw()) {
+      __ movl(rdx, 0xffff);
+      __ kmovdl(k1, rdx);
+    }
+
     __ movptr(from, from_param);
     __ movptr(key, key_param);
 
@@ -2441,6 +2465,14 @@
     __ enter(); // required for proper stackwalking of RuntimeStub frame
     handleSOERegisters(true /*saving*/);
 
+    // For EVEX with VL and BW, provide a standard mask, VL = 128 will guide the merge
+    // context for the registers used, where all instructions below are using 128-bit mode
+    // On EVEX without VL and BW, these instructions will all be AVX.
+    if (VM_Version::supports_avx512vlbw()) {
+      __ movl(rdx, 0xffff);
+      __ kmovdl(k1, rdx);
+    }
+
     // load registers from incoming parameters
     const Address  from_param(rbp, 8+0);
     const Address  to_param  (rbp, 8+4);
@@ -2602,6 +2634,14 @@
     __ enter(); // required for proper stackwalking of RuntimeStub frame
     handleSOERegisters(true /*saving*/);
 
+    // For EVEX with VL and BW, provide a standard mask, VL = 128 will guide the merge
+    // context for the registers used, where all instructions below are using 128-bit mode
+    // On EVEX without VL and BW, these instructions will all be AVX.
+    if (VM_Version::supports_avx512vlbw()) {
+      __ movl(rdx, 0xffff);
+      __ kmovdl(k1, rdx);
+    }
+
     // load registers from incoming parameters
     const Address  from_param(rbp, 8+0);
     const Address  to_param  (rbp, 8+4);
@@ -2782,6 +2822,14 @@
     __ enter();
     handleSOERegisters(true);  // Save registers
 
+    // For EVEX with VL and BW, provide a standard mask, VL = 128 will guide the merge
+    // context for the registers used, where all instructions below are using 128-bit mode
+    // On EVEX without VL and BW, these instructions will all be AVX.
+    if (VM_Version::supports_avx512vlbw()) {
+      __ movl(rdx, 0xffff);
+      __ kmovdl(k1, rdx);
+    }
+
     __ movptr(state, state_param);
     __ movptr(subkeyH, subkeyH_param);
     __ movptr(data, data_param);
--- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp	Sat Sep 26 09:22:24 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp	Wed Jul 05 20:51:27 2017 +0200
@@ -269,12 +269,16 @@
       __ kmovql(k1, rbx);
     }
 #ifdef _WIN64
+    int last_reg = 15;
     if (UseAVX > 2) {
-      for (int i = 6; i <= 31; i++) {
-        __ movdqu(xmm_save(i), as_XMMRegister(i));
+      last_reg = 31;
+    }
+    if (VM_Version::supports_avx512novl()) {
+      for (int i = xmm_save_first; i <= last_reg; i++) {
+        __ vextractf32x4h(xmm_save(i), as_XMMRegister(i), 0);
       }
     } else {
-      for (int i = 6; i <= 15; i++) {
+      for (int i = xmm_save_first; i <= last_reg; i++) {
         __ movdqu(xmm_save(i), as_XMMRegister(i));
       }
     }
@@ -386,13 +390,15 @@
 
     // restore regs belonging to calling function
 #ifdef _WIN64
-    int xmm_ub = 15;
-    if (UseAVX > 2) {
-      xmm_ub = 31;
-    }
     // emit the restores for xmm regs
-    for (int i = 6; i <= xmm_ub; i++) {
-      __ movdqu(as_XMMRegister(i), xmm_save(i));
+    if (VM_Version::supports_avx512novl()) {
+      for (int i = xmm_save_first; i <= last_reg; i++) {
+        __ vinsertf32x4h(as_XMMRegister(i), xmm_save(i), 0);
+      }
+    } else {
+      for (int i = xmm_save_first; i <= last_reg; i++) {
+        __ movdqu(as_XMMRegister(i), xmm_save(i));
+      }
     }
 #endif
     __ movptr(r15, r15_save);
@@ -1342,11 +1348,15 @@
     __ align(OptoLoopAlignment);
     if (UseUnalignedLoadStores) {
       Label L_end;
+      if (UseAVX > 2) {
+        __ movl(to, 0xffff);
+        __ kmovql(k1, to);
+      }
       // Copy 64-bytes per iteration
       __ BIND(L_loop);
       if (UseAVX > 2) {
-        __ evmovdqu(xmm0, Address(end_from, qword_count, Address::times_8, -56), Assembler::AVX_512bit);
-        __ evmovdqu(Address(end_to, qword_count, Address::times_8, -56), xmm0, Assembler::AVX_512bit);
+        __ evmovdqul(xmm0, Address(end_from, qword_count, Address::times_8, -56), Assembler::AVX_512bit);
+        __ evmovdqul(Address(end_to, qword_count, Address::times_8, -56), xmm0, Assembler::AVX_512bit);
       } else if (UseAVX == 2) {
         __ vmovdqu(xmm0, Address(end_from, qword_count, Address::times_8, -56));
         __ vmovdqu(Address(end_to, qword_count, Address::times_8, -56), xmm0);
@@ -1422,11 +1432,15 @@
     __ align(OptoLoopAlignment);
     if (UseUnalignedLoadStores) {
       Label L_end;
+      if (UseAVX > 2) {
+        __ movl(to, 0xffff);
+        __ kmovql(k1, to);
+      }
       // Copy 64-bytes per iteration
       __ BIND(L_loop);
       if (UseAVX > 2) {
-        __ evmovdqu(xmm0, Address(from, qword_count, Address::times_8, 32), Assembler::AVX_512bit);
-        __ evmovdqu(Address(dest, qword_count, Address::times_8, 32), xmm0, Assembler::AVX_512bit);
+        __ evmovdqul(xmm0, Address(from, qword_count, Address::times_8, 32), Assembler::AVX_512bit);
+        __ evmovdqul(Address(dest, qword_count, Address::times_8, 32), xmm0, Assembler::AVX_512bit);
       } else if (UseAVX == 2) {
         __ vmovdqu(xmm0, Address(from, qword_count, Address::times_8, 32));
         __ vmovdqu(Address(dest, qword_count, Address::times_8, 32), xmm0);
@@ -3106,6 +3120,14 @@
 
     __ enter(); // required for proper stackwalking of RuntimeStub frame
 
+    // For EVEX with VL and BW, provide a standard mask, VL = 128 will guide the merge
+    // context for the registers used, where all instructions below are using 128-bit mode
+    // On EVEX without VL and BW, these instructions will all be AVX.
+    if (VM_Version::supports_avx512vlbw()) {
+      __ movl(rax, 0xffff);
+      __ kmovql(k1, rax);
+    }
+
     // keylen could be only {11, 13, 15} * 4 = {44, 52, 60}
     __ movl(keylen, Address(key, arrayOopDesc::length_offset_in_bytes() - arrayOopDesc::base_offset_in_bytes(T_INT)));
 
@@ -3200,6 +3222,14 @@
 
     __ enter(); // required for proper stackwalking of RuntimeStub frame
 
+    // For EVEX with VL and BW, provide a standard mask, VL = 128 will guide the merge
+    // context for the registers used, where all instructions below are using 128-bit mode
+    // On EVEX without VL and BW, these instructions will all be AVX.
+    if (VM_Version::supports_avx512vlbw()) {
+      __ movl(rax, 0xffff);
+      __ kmovql(k1, rax);
+    }
+
     // keylen could be only {11, 13, 15} * 4 = {44, 52, 60}
     __ movl(keylen, Address(key, arrayOopDesc::length_offset_in_bytes() - arrayOopDesc::base_offset_in_bytes(T_INT)));
 
@@ -3312,6 +3342,14 @@
 
     __ enter(); // required for proper stackwalking of RuntimeStub frame
 
+    // For EVEX with VL and BW, provide a standard mask, VL = 128 will guide the merge
+    // context for the registers used, where all instructions below are using 128-bit mode
+    // On EVEX without VL and BW, these instructions will all be AVX.
+    if (VM_Version::supports_avx512vlbw()) {
+      __ movl(rax, 0xffff);
+      __ kmovql(k1, rax);
+    }
+
 #ifdef _WIN64
     // on win64, fill len_reg from stack position
     __ movl(len_reg, len_mem);
@@ -3508,6 +3546,14 @@
 
     __ enter(); // required for proper stackwalking of RuntimeStub frame
 
+    // For EVEX with VL and BW, provide a standard mask, VL = 128 will guide the merge
+    // context for the registers used, where all instructions below are using 128-bit mode
+    // On EVEX without VL and BW, these instructions will all be AVX.
+    if (VM_Version::supports_avx512vlbw()) {
+      __ movl(rax, 0xffff);
+      __ kmovql(k1, rax);
+    }
+
 #ifdef _WIN64
     // on win64, fill len_reg from stack position
     __ movl(len_reg, len_mem);
@@ -3746,6 +3792,14 @@
 
     __ enter();
 
+    // For EVEX with VL and BW, provide a standard mask, VL = 128 will guide the merge
+    // context for the registers used, where all instructions below are using 128-bit mode
+    // On EVEX without VL and BW, these instructions will all be AVX.
+    if (VM_Version::supports_avx512vlbw()) {
+      __ movl(rax, 0xffff);
+      __ kmovql(k1, rax);
+    }
+
 #ifdef _WIN64
     // save the xmm registers which must be preserved 6-10
     __ subptr(rsp, -rsp_after_call_off * wordSize);
--- a/hotspot/src/cpu/x86/vm/stubRoutines_x86_32.hpp	Sat Sep 26 09:22:24 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/stubRoutines_x86_32.hpp	Wed Jul 05 20:51:27 2017 +0200
@@ -31,7 +31,7 @@
 
 enum platform_dependent_constants {
   code_size1 =  9000,           // simply increase if too small (assembler will crash if too small)
-  code_size2 = 22000            // simply increase if too small (assembler will crash if too small)
+  code_size2 = 30000            // simply increase if too small (assembler will crash if too small)
 };
 
 class x86 {
--- a/hotspot/src/cpu/x86/vm/stubRoutines_x86_64.hpp	Sat Sep 26 09:22:24 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/stubRoutines_x86_64.hpp	Wed Jul 05 20:51:27 2017 +0200
@@ -33,7 +33,7 @@
 
 enum platform_dependent_constants {
   code_size1 = 19000,          // simply increase if too small (assembler will crash if too small)
-  code_size2 = 24000           // simply increase if too small (assembler will crash if too small)
+  code_size2 = 32000           // simply increase if too small (assembler will crash if too small)
 };
 
 class x86 {
--- a/hotspot/src/cpu/x86/vm/vm_version_x86.cpp	Sat Sep 26 09:22:24 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/vm_version_x86.cpp	Wed Jul 05 20:51:27 2017 +0200
@@ -367,16 +367,12 @@
     __ movl(rcx, VM_Version::ymm_test_value());
     __ movdl(xmm0, rcx);
     __ movl(rcx, 0xffff);
+    __ kmovwl(k1, rcx);
+    __ evpbroadcastd(xmm0, xmm0, Assembler::AVX_512bit);
+    __ evmovdqul(xmm7, xmm0, Assembler::AVX_512bit);
 #ifdef _LP64
-    __ kmovql(k1, rcx);
-#else
-    __ kmovdl(k1, rcx);
-#endif
-    __ evpbroadcastd(xmm0, xmm0, Assembler::AVX_512bit);
-    __ evmovdqu(xmm7, xmm0, Assembler::AVX_512bit);
-#ifdef _LP64
-    __ evmovdqu(xmm8, xmm0, Assembler::AVX_512bit);
-    __ evmovdqu(xmm31, xmm0, Assembler::AVX_512bit);
+    __ evmovdqul(xmm8, xmm0, Assembler::AVX_512bit);
+    __ evmovdqul(xmm31, xmm0, Assembler::AVX_512bit);
 #endif
     VM_Version::clean_cpuFeatures();
     __ jmp(save_restore_except);
@@ -427,11 +423,11 @@
     UseAVX = 3;
     UseSSE = 2;
     __ lea(rsi, Address(rbp, in_bytes(VM_Version::zmm_save_offset())));
-    __ evmovdqu(Address(rsi, 0), xmm0, Assembler::AVX_512bit);
-    __ evmovdqu(Address(rsi, 64), xmm7, Assembler::AVX_512bit);
+    __ evmovdqul(Address(rsi, 0), xmm0, Assembler::AVX_512bit);
+    __ evmovdqul(Address(rsi, 64), xmm7, Assembler::AVX_512bit);
 #ifdef _LP64
-    __ evmovdqu(Address(rsi, 128), xmm8, Assembler::AVX_512bit);
-    __ evmovdqu(Address(rsi, 192), xmm31, Assembler::AVX_512bit);
+    __ evmovdqul(Address(rsi, 128), xmm8, Assembler::AVX_512bit);
+    __ evmovdqul(Address(rsi, 192), xmm31, Assembler::AVX_512bit);
 #endif
     VM_Version::clean_cpuFeatures();
     UseAVX = saved_useavx;
--- a/hotspot/src/cpu/x86/vm/vm_version_x86.hpp	Sat Sep 26 09:22:24 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/vm_version_x86.hpp	Wed Jul 05 20:51:27 2017 +0200
@@ -227,14 +227,15 @@
   union XemXcr0Eax {
     uint32_t value;
     struct {
-      uint32_t x87    : 1,
-               sse    : 1,
-               ymm    : 1,
-                      : 2,
-               opmask : 1,
-               zmm512 : 1,
-                zmm32 : 1,
-                      : 24;
+      uint32_t x87     : 1,
+               sse     : 1,
+               ymm     : 1,
+               bndregs : 1,
+               bndcsr  : 1,
+               opmask  : 1,
+               zmm512  : 1,
+               zmm32   : 1,
+                       : 24;
     } bits;
   };
 
@@ -703,6 +704,7 @@
   static bool supports_avx512bw() { return (_cpuFeatures & CPU_AVX512BW) != 0; }
   static bool supports_avx512vl() { return (_cpuFeatures & CPU_AVX512VL) != 0; }
   static bool supports_avx512vlbw() { return (supports_avx512bw() && supports_avx512vl()); }
+  static bool supports_avx512novl() { return (supports_evex() && !supports_avx512vl()); }
   // Intel features
   static bool is_intel_family_core() { return is_intel() &&
                                        extended_cpu_family() == CPU_FAMILY_INTEL_CORE; }
@@ -817,6 +819,12 @@
     intx count = PrefetchFieldsAhead;
     return count >= 0 ? count : 1;
   }
+  static uint32_t get_xsave_header_lower_segment() {
+    return _cpuid_info.xem_xcr0_eax.value;
+  }
+  static uint32_t get_xsave_header_upper_segment() {
+    return _cpuid_info.xem_xcr0_edx;
+  }
 };
 
 #endif // CPU_X86_VM_VM_VERSION_X86_HPP
--- a/hotspot/src/cpu/x86/vm/x86.ad	Sat Sep 26 09:22:24 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/x86.ad	Wed Jul 05 20:51:27 2017 +0200
@@ -1661,46 +1661,55 @@
   if (!has_match_rule(opcode))
     return false;
 
+  bool ret_value = true;
   switch (opcode) {
     case Op_PopCountI:
     case Op_PopCountL:
       if (!UsePopCountInstruction)
-        return false;
-    break;
+        ret_value = false;
+      break;
     case Op_MulVI:
       if ((UseSSE < 4) && (UseAVX < 1)) // only with SSE4_1 or AVX
-        return false;
-    break;
+        ret_value = false;
+      break;
     case Op_MulVL:
     case Op_MulReductionVL:
       if (VM_Version::supports_avx512dq() == false)
-        return false;
+        ret_value = false;
+      break;
     case Op_AddReductionVL:
       if (UseAVX < 3) // only EVEX : vector connectivity becomes an issue here
-        return false;
+        ret_value = false;
+      break;
     case Op_AddReductionVI:
       if (UseSSE < 3) // requires at least SSE3
-        return false;
+        ret_value = false;
+      break;
     case Op_MulReductionVI:
       if (UseSSE < 4) // requires at least SSE4
-        return false;
+        ret_value = false;
+      break;
     case Op_AddReductionVF:
     case Op_AddReductionVD:
     case Op_MulReductionVF:
     case Op_MulReductionVD:
       if (UseSSE < 1) // requires at least SSE
-        return false;
-    break;
+        ret_value = false;
+      break;
+    case Op_SqrtVD:
+      if (UseAVX < 1) // enabled for AVX only
+        ret_value = false;
+      break;
     case Op_CompareAndSwapL:
 #ifdef _LP64
     case Op_CompareAndSwapP:
 #endif
       if (!VM_Version::supports_cx8())
-        return false;
-    break;
+        ret_value = false;
+      break;
   }
 
-  return true;  // Per default match rules are supported.
+  return ret_value;  // Per default match rules are supported.
 }
 
 // Max vector size in bytes. 0 if not supported.
@@ -1721,14 +1730,24 @@
   case T_DOUBLE:
   case T_LONG:
     if (size < 16) return 0;
+    break;
   case T_FLOAT:
   case T_INT:
     if (size < 8) return 0;
+    break;
   case T_BOOLEAN:
+    if (size < 4) return 0;
+    break;
+  case T_CHAR:
+    if (size < 4) return 0;
+    break;
   case T_BYTE:
-  case T_CHAR:
+    if (size < 4) return 0;
+    if ((size > 32) && !VM_Version::supports_avx512bw()) return 0;
+    break;
   case T_SHORT:
     if (size < 4) return 0;
+    if ((size > 16) && !VM_Version::supports_avx512bw()) return 0;
     break;
   default:
     ShouldNotReachHere();
@@ -1800,7 +1819,7 @@
       __ vmovdqu(as_XMMRegister(Matcher::_regEncode[dst_lo]), as_XMMRegister(Matcher::_regEncode[src_lo]));
       break;
     case Op_VecZ:
-      __ evmovdqu(as_XMMRegister(Matcher::_regEncode[dst_lo]), as_XMMRegister(Matcher::_regEncode[src_lo]), 2);
+      __ evmovdqul(as_XMMRegister(Matcher::_regEncode[dst_lo]), as_XMMRegister(Matcher::_regEncode[src_lo]), 2);
       break;
     default:
       ShouldNotReachHere();
@@ -1855,7 +1874,7 @@
         __ vmovdqu(as_XMMRegister(Matcher::_regEncode[reg]), Address(rsp, stack_offset));
         break;
       case Op_VecZ:
-        __ evmovdqu(as_XMMRegister(Matcher::_regEncode[reg]), Address(rsp, stack_offset), 2);
+        __ evmovdqul(as_XMMRegister(Matcher::_regEncode[reg]), Address(rsp, stack_offset), 2);
         break;
       default:
         ShouldNotReachHere();
@@ -1875,7 +1894,7 @@
         __ vmovdqu(Address(rsp, stack_offset), as_XMMRegister(Matcher::_regEncode[reg]));
         break;
       case Op_VecZ:
-        __ evmovdqu(Address(rsp, stack_offset), as_XMMRegister(Matcher::_regEncode[reg]), 2);
+        __ evmovdqul(Address(rsp, stack_offset), as_XMMRegister(Matcher::_regEncode[reg]), 2);
         break;
       default:
         ShouldNotReachHere();
@@ -1929,9 +1948,40 @@
     }
 #endif
   }
-  int offset_size = (stack_offset == 0) ? 0 : ((stack_offset < 0x80) ? 1 : (UseAVX > 2) ? 6 : 4);
+  bool is_single_byte = false;
+  int vec_len = 0;
+  if ((UseAVX > 2) && (stack_offset != 0)) {
+    switch (ireg) {
+	case Op_VecS:
+    case Op_VecD:
+    case Op_VecX:
+	  break;
+	case Op_VecY:
+	  vec_len = 1;
+	  break;
+    case Op_VecZ:
+	  vec_len = 2;
+	  break;
+    }
+    is_single_byte = Assembler::query_compressed_disp_byte(stack_offset, true, vec_len, Assembler::EVEX_FVM, Assembler::EVEX_32bit, 0);
+  }
+  int offset_size = 0;
+  int size = 5;
+  if (UseAVX > 2 ) {
+    if ((VM_Version::supports_avx512vl() == false) && (vec_len == 2)) { 
+      offset_size = (stack_offset == 0) ? 0 : ((is_single_byte) ? 1 : 4);
+      size += 2; // Need an additional two bytes for EVEX encoding
+    } else if ((VM_Version::supports_avx512vl() == false) && (vec_len < 2)) { 
+      offset_size = (stack_offset == 0) ? 0 : ((stack_offset <= 127) ? 1 : 4);
+    } else {
+      offset_size = (stack_offset == 0) ? 0 : ((is_single_byte) ? 1 : 4);
+      size += 2; // Need an additional two bytes for EVEX encodding
+    }
+  } else {
+    offset_size = (stack_offset == 0) ? 0 : ((stack_offset <= 127) ? 1 : 4);
+  }
   // VEX_2bytes prefix is used if UseAVX > 0, so it takes the same 2 bytes as SIMD prefix.
-  return 5+offset_size;
+  return size+offset_size;
 }
 
 static inline jfloat replicate4_imm(int con, int width) {
@@ -2675,11 +2725,10 @@
   predicate(UseAVX > 0);
   match(Set dst (NegF src));
   ins_cost(150);
-  format %{ "vxorps  $dst, $src, [0x80000000]\t# neg float by sign flipping" %}
-  ins_encode %{
-    int vector_len = 0;
-    __ vxorps($dst$$XMMRegister, $src$$XMMRegister,
-              ExternalAddress(float_signflip()), vector_len);
+  format %{ "vnegatess  $dst, $src, [0x80000000]\t# neg float by sign flipping" %}
+  ins_encode %{
+    __ vnegatess($dst$$XMMRegister, $src$$XMMRegister,
+                 ExternalAddress(float_signflip()));
   %}
   ins_pipe(pipe_slow);
 %}
@@ -2700,12 +2749,11 @@
   predicate(UseAVX > 0);
   match(Set dst (NegD src));
   ins_cost(150);
-  format %{ "vxorpd  $dst, $src, [0x8000000000000000]\t"
+  format %{ "vnegatess  $dst, $src, [0x8000000000000000]\t"
             "# neg double by sign flipping" %}
   ins_encode %{
-    int vector_len = 0;
-    __ vxorpd($dst$$XMMRegister, $src$$XMMRegister,
-              ExternalAddress(double_signflip()), vector_len);
+    __ vnegatesd($dst$$XMMRegister, $src$$XMMRegister,
+                 ExternalAddress(double_signflip()));
   %}
   ins_pipe(pipe_slow);
 %}
@@ -2838,7 +2886,7 @@
   format %{ "vmovdqu $dst k0,$mem\t! load vector (64 bytes)" %}
   ins_encode %{
     int vector_len = 2;
-    __ evmovdqu($dst$$XMMRegister, $mem$$Address, vector_len);
+    __ evmovdqul($dst$$XMMRegister, $mem$$Address, vector_len);
   %}
   ins_pipe( pipe_slow );
 %}
@@ -2895,7 +2943,7 @@
   format %{ "vmovdqu $mem k0,$src\t! store vector (64 bytes)" %}
   ins_encode %{
     int vector_len = 2;
-    __ evmovdqu($mem$$Address, $src$$XMMRegister, vector_len);
+    __ evmovdqul($mem$$Address, $src$$XMMRegister, vector_len);
   %}
   ins_pipe( pipe_slow );
 %}
@@ -3315,6 +3363,37 @@
   ins_pipe( pipe_slow );
 %}
 
+instruct Repl2F_zero(vecD dst, immF0 zero) %{
+  predicate(n->as_Vector()->length() == 2 && UseAVX < 3);
+  match(Set dst (ReplicateF zero));
+  format %{ "xorps   $dst,$dst\t! replicate2F zero" %}
+  ins_encode %{
+    __ xorps($dst$$XMMRegister, $dst$$XMMRegister);
+  %}
+  ins_pipe( fpu_reg_reg );
+%}
+
+instruct Repl4F_zero(vecX dst, immF0 zero) %{
+  predicate(n->as_Vector()->length() == 4 && UseAVX < 3);
+  match(Set dst (ReplicateF zero));
+  format %{ "xorps   $dst,$dst\t! replicate4F zero" %}
+  ins_encode %{
+    __ xorps($dst$$XMMRegister, $dst$$XMMRegister);
+  %}
+  ins_pipe( fpu_reg_reg );
+%}
+
+instruct Repl8F_zero(vecY dst, immF0 zero) %{
+  predicate(n->as_Vector()->length() == 8 && UseAVX < 3);
+  match(Set dst (ReplicateF zero));
+  format %{ "vxorps  $dst,$dst,$dst\t! replicate8F zero" %}
+  ins_encode %{
+    int vector_len = 1;
+    __ vxorps($dst$$XMMRegister, $dst$$XMMRegister, $dst$$XMMRegister, vector_len);
+  %}
+  ins_pipe( fpu_reg_reg );
+%}
+
 instruct Repl2D_mem(vecX dst, memory mem) %{
   predicate(n->as_Vector()->length() == 2 && UseAVX > 0 && !VM_Version::supports_avx512vl());
   match(Set dst (ReplicateD (LoadD mem)));
@@ -3349,6 +3428,28 @@
   ins_pipe( pipe_slow );
 %}
 
+// Replicate double (8 byte) scalar zero to be vector
+instruct Repl2D_zero(vecX dst, immD0 zero) %{
+  predicate(n->as_Vector()->length() == 2 && UseAVX < 3);
+  match(Set dst (ReplicateD zero));
+  format %{ "xorpd   $dst,$dst\t! replicate2D zero" %}
+  ins_encode %{
+    __ xorpd($dst$$XMMRegister, $dst$$XMMRegister);
+  %}
+  ins_pipe( fpu_reg_reg );
+%}
+
+instruct Repl4D_zero(vecY dst, immD0 zero) %{
+  predicate(n->as_Vector()->length() == 4 && UseAVX < 3);
+  match(Set dst (ReplicateD zero));
+  format %{ "vxorpd  $dst,$dst,$dst,vect256\t! replicate4D zero" %}
+  ins_encode %{
+    int vector_len = 1;
+    __ vxorpd($dst$$XMMRegister, $dst$$XMMRegister, $dst$$XMMRegister, vector_len);
+  %}
+  ins_pipe( fpu_reg_reg );
+%}
+
 // ====================GENERIC REPLICATE==========================================
 
 // Replicate byte scalar to be vector
@@ -3680,38 +3781,6 @@
   ins_pipe( pipe_slow );
 %}
 
-// Replicate float (4 byte) scalar zero to be vector
-instruct Repl2F_zero(vecD dst, immF0 zero) %{
-  predicate(n->as_Vector()->length() == 2);
-  match(Set dst (ReplicateF zero));
-  format %{ "xorps   $dst,$dst\t! replicate2F zero" %}
-  ins_encode %{
-    __ xorps($dst$$XMMRegister, $dst$$XMMRegister);
-  %}
-  ins_pipe( fpu_reg_reg );
-%}
-
-instruct Repl4F_zero(vecX dst, immF0 zero) %{
-  predicate(n->as_Vector()->length() == 4);
-  match(Set dst (ReplicateF zero));
-  format %{ "xorps   $dst,$dst\t! replicate4F zero" %}
-  ins_encode %{
-    __ xorps($dst$$XMMRegister, $dst$$XMMRegister);
-  %}
-  ins_pipe( fpu_reg_reg );
-%}
-
-instruct Repl8F_zero(vecY dst, immF0 zero) %{
-  predicate(n->as_Vector()->length() == 8);
-  match(Set dst (ReplicateF zero));
-  format %{ "vxorps  $dst,$dst,$dst\t! replicate8F zero" %}
-  ins_encode %{
-    int vector_len = 1;
-    __ vxorps($dst$$XMMRegister, $dst$$XMMRegister, $dst$$XMMRegister, vector_len);
-  %}
-  ins_pipe( fpu_reg_reg );
-%}
-
 // Replicate double (8 bytes) scalar to be vector
 instruct Repl2D(vecX dst, regD src) %{
   predicate(n->as_Vector()->length() == 2);
@@ -3723,28 +3792,6 @@
   ins_pipe( pipe_slow );
 %}
 
-// Replicate double (8 byte) scalar zero to be vector
-instruct Repl2D_zero(vecX dst, immD0 zero) %{
-  predicate(n->as_Vector()->length() == 2);
-  match(Set dst (ReplicateD zero));
-  format %{ "xorpd   $dst,$dst\t! replicate2D zero" %}
-  ins_encode %{
-    __ xorpd($dst$$XMMRegister, $dst$$XMMRegister);
-  %}
-  ins_pipe( fpu_reg_reg );
-%}
-
-instruct Repl4D_zero(vecY dst, immD0 zero) %{
-  predicate(n->as_Vector()->length() == 4);
-  match(Set dst (ReplicateD zero));
-  format %{ "vxorpd  $dst,$dst,$dst,vect256\t! replicate4D zero" %}
-  ins_encode %{
-    int vector_len = 1;
-    __ vxorpd($dst$$XMMRegister, $dst$$XMMRegister, $dst$$XMMRegister, vector_len);
-  %}
-  ins_pipe( fpu_reg_reg );
-%}
-
 // ====================EVEX REPLICATE=============================================
 
 instruct Repl4B_mem_evex(vecS dst, memory mem) %{
@@ -3814,7 +3861,7 @@
 %}
 
 instruct Repl64B_evex(vecZ dst, rRegI src) %{
-  predicate(n->as_Vector()->length() == 64 && UseAVX > 2);
+  predicate(n->as_Vector()->length() == 64 && VM_Version::supports_avx512bw());
   match(Set dst (ReplicateB src));
   format %{ "vpbroadcastb $dst,$src\t! upper replicate64B" %}
   ins_encode %{
@@ -3825,7 +3872,7 @@
 %}
 
 instruct Repl64B_mem_evex(vecZ dst, memory mem) %{
-  predicate(n->as_Vector()->length() == 64 && VM_Version::supports_avx512vlbw());
+  predicate(n->as_Vector()->length() == 64 && VM_Version::supports_avx512bw());
   match(Set dst (ReplicateB (LoadB mem)));
   format %{ "vpbroadcastb  $dst,$mem\t! replicate64B" %}
   ins_encode %{
@@ -3862,7 +3909,7 @@
 %}
 
 instruct Repl64B_imm_evex(vecZ dst, immI con) %{
-  predicate(n->as_Vector()->length() == 64 && UseAVX > 2);
+  predicate(n->as_Vector()->length() == 64 && VM_Version::supports_avx512bw());
   match(Set dst (ReplicateB con));
   format %{ "movq    $dst,[$constantaddress]\n\t"
             "vpbroadcastb $dst,$dst\t! upper replicate64B" %}
@@ -3953,7 +4000,7 @@
 %}
 
 instruct Repl32S_evex(vecZ dst, rRegI src) %{
-  predicate(n->as_Vector()->length() == 32 && UseAVX > 2);
+  predicate(n->as_Vector()->length() == 32 && VM_Version::supports_avx512bw());
   match(Set dst (ReplicateS src));
   format %{ "vpbroadcastw $dst,$src\t! replicate32S" %}
   ins_encode %{
@@ -3964,7 +4011,7 @@
 %}
 
 instruct Repl32S_mem_evex(vecZ dst, memory mem) %{
-  predicate(n->as_Vector()->length() == 32 && UseAVX > 2);
+  predicate(n->as_Vector()->length() == 32 && VM_Version::supports_avx512bw());
   match(Set dst (ReplicateS (LoadS mem)));
   format %{ "vpbroadcastw  $dst,$mem\t! replicate32S" %}
   ins_encode %{
@@ -4001,7 +4048,7 @@
 %}
 
 instruct Repl32S_imm_evex(vecZ dst, immI con) %{
-  predicate(n->as_Vector()->length() == 32 && UseAVX > 2);
+  predicate(n->as_Vector()->length() == 32 && VM_Version::supports_avx512bw());
   match(Set dst (ReplicateS con));
   format %{ "movq    $dst,[$constantaddress]\n\t"
             "vpbroadcastw $dst,$dst\t! replicate32S" %}
@@ -4318,13 +4365,50 @@
   ins_pipe( pipe_slow );
 %}
 
+instruct Repl2F_zero_evex(vecD dst, immF0 zero) %{
+  predicate(n->as_Vector()->length() == 2 && UseAVX > 2);
+  match(Set dst (ReplicateF zero));
+  format %{ "vpxor  $dst k0,$dst,$dst\t! replicate2F zero" %}
+  ins_encode %{
+    // Use vpxor in place of vxorps since EVEX has a constriant on dq for vxorps: this is a 512-bit operation
+    int vector_len = 2;
+    __ vpxor($dst$$XMMRegister,$dst$$XMMRegister, $dst$$XMMRegister, vector_len);
+  %}
+  ins_pipe( fpu_reg_reg );
+%}
+
+instruct Repl4F_zero_evex(vecX dst, immF0 zero) %{
+  predicate(n->as_Vector()->length() == 4 && UseAVX > 2);
+  match(Set dst (ReplicateF zero));
+  format %{ "vpxor  $dst k0,$dst,$dst\t! replicate4F zero" %}
+  ins_encode %{
+    // Use vpxor in place of vxorps since EVEX has a constriant on dq for vxorps: this is a 512-bit operation
+    int vector_len = 2;
+    __ vpxor($dst$$XMMRegister,$dst$$XMMRegister, $dst$$XMMRegister, vector_len);
+  %}
+  ins_pipe( fpu_reg_reg );
+%}
+
+instruct Repl8F_zero_evex(vecY dst, immF0 zero) %{
+  predicate(n->as_Vector()->length() == 8 && UseAVX > 2);
+  match(Set dst (ReplicateF zero));
+  format %{ "vpxor  $dst k0,$dst,$dst\t! replicate8F zero" %}
+  ins_encode %{
+    // Use vpxor in place of vxorps since EVEX has a constriant on dq for vxorps: this is a 512-bit operation
+    int vector_len = 2;
+    __ vpxor($dst$$XMMRegister,$dst$$XMMRegister, $dst$$XMMRegister, vector_len);
+  %}
+  ins_pipe( fpu_reg_reg );
+%}
+
 instruct Repl16F_zero_evex(vecZ dst, immF0 zero) %{
   predicate(n->as_Vector()->length() == 16 && UseAVX > 2);
   match(Set dst (ReplicateF zero));
-  format %{ "vxorps  $dst k0,$dst,$dst\t! replicate16F zero" %}
-  ins_encode %{
+  format %{ "vpxor  $dst k0,$dst,$dst\t! replicate16F zero" %}
+  ins_encode %{
+    // Use vpxor in place of vxorps since EVEX has a constriant on dq for vxorps: this is a 512-bit operation
     int vector_len = 2;
-    __ vxorps($dst$$XMMRegister, $dst$$XMMRegister, $dst$$XMMRegister, vector_len);
+    __ vpxor($dst$$XMMRegister,$dst$$XMMRegister, $dst$$XMMRegister, vector_len);
   %}
   ins_pipe( fpu_reg_reg );
 %}
@@ -4373,13 +4457,38 @@
   ins_pipe( pipe_slow );
 %}
 
+instruct Repl2D_zero_evex(vecX dst, immD0 zero) %{
+  predicate(n->as_Vector()->length() == 2 && UseAVX > 2);
+  match(Set dst (ReplicateD zero));
+  format %{ "vpxor  $dst k0,$dst,$dst\t! replicate2D zero" %}
+  ins_encode %{
+    // Use vpxor in place of vxorpd since EVEX has a constriant on dq for vxorpd: this is a 512-bit operation
+    int vector_len = 2;
+    __ vpxor($dst$$XMMRegister,$dst$$XMMRegister, $dst$$XMMRegister, vector_len);
+  %}
+  ins_pipe( fpu_reg_reg );
+%}
+
+instruct Repl4D_zero_evex(vecY dst, immD0 zero) %{
+  predicate(n->as_Vector()->length() == 4 && UseAVX > 2);
+  match(Set dst (ReplicateD zero));
+  format %{ "vpxor  $dst k0,$dst,$dst\t! replicate4D zero" %}
+  ins_encode %{
+    // Use vpxor in place of vxorpd since EVEX has a constriant on dq for vxorpd: this is a 512-bit operation
+    int vector_len = 2;
+    __ vpxor($dst$$XMMRegister,$dst$$XMMRegister, $dst$$XMMRegister, vector_len);
+  %}
+  ins_pipe( fpu_reg_reg );
+%}
+
 instruct Repl8D_zero_evex(vecZ dst, immD0 zero) %{
   predicate(n->as_Vector()->length() == 8 && UseAVX > 2);
   match(Set dst (ReplicateD zero));
-  format %{ "vxorpd  $dst k0,$dst,$dst,vect512\t! replicate8D zero" %}
-  ins_encode %{
+  format %{ "vpxor  $dst k0,$dst,$dst,vect512\t! replicate8D zero" %}
+  ins_encode %{
+    // Use vpxor in place of vxorpd since EVEX has a constriant on dq for vxorpd: this is a 512-bit operation
     int vector_len = 2;
-    __ vxorpd($dst$$XMMRegister, $dst$$XMMRegister, $dst$$XMMRegister, vector_len);
+    __ vpxor($dst$$XMMRegister,$dst$$XMMRegister, $dst$$XMMRegister, vector_len);
   %}
   ins_pipe( fpu_reg_reg );
 %}
@@ -7474,6 +7583,75 @@
   ins_pipe( pipe_slow );
 %}
 
+// --------------------------------- Sqrt --------------------------------------
+
+// Floating point vector sqrt - double precision only
+instruct vsqrt2D_reg(vecX dst, vecX src) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
+  match(Set dst (SqrtVD src));
+  format %{ "vsqrtpd  $dst,$src\t! sqrt packed2D" %}
+  ins_encode %{
+    int vector_len = 0;
+    __ vsqrtpd($dst$$XMMRegister, $src$$XMMRegister, vector_len);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsqrt2D_mem(vecX dst, memory mem) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
+  match(Set dst (SqrtVD (LoadVector mem)));
+  format %{ "vsqrtpd  $dst,$mem\t! sqrt packed2D" %}
+  ins_encode %{
+    int vector_len = 0;
+    __ vsqrtpd($dst$$XMMRegister, $mem$$Address, vector_len);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsqrt4D_reg(vecY dst, vecY src) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
+  match(Set dst (SqrtVD src));
+  format %{ "vsqrtpd  $dst,$src\t! sqrt packed4D" %}
+  ins_encode %{
+    int vector_len = 1;
+    __ vsqrtpd($dst$$XMMRegister, $src$$XMMRegister, vector_len);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsqrt4D_mem(vecY dst, memory mem) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
+  match(Set dst (SqrtVD (LoadVector mem)));
+  format %{ "vsqrtpd  $dst,$mem\t! sqrt packed4D" %}
+  ins_encode %{
+    int vector_len = 1;
+    __ vsqrtpd($dst$$XMMRegister, $mem$$Address, vector_len);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsqrt8D_reg(vecZ dst, vecZ src) %{
+  predicate(UseAVX > 2 && n->as_Vector()->length() == 8);
+  match(Set dst (SqrtVD src));
+  format %{ "vsqrtpd  $dst,$src\t! sqrt packed8D" %}
+  ins_encode %{
+    int vector_len = 2;
+    __ vsqrtpd($dst$$XMMRegister, $src$$XMMRegister, vector_len);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsqrt8D_mem(vecZ dst, memory mem) %{
+  predicate(UseAVX > 2 && n->as_Vector()->length() == 8);
+  match(Set dst (SqrtVD (LoadVector mem)));
+  format %{ "vsqrtpd  $dst,$mem\t! sqrt packed8D" %}
+  ins_encode %{
+    int vector_len = 2;
+    __ vsqrtpd($dst$$XMMRegister, $mem$$Address, vector_len);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
 // ------------------------------ LeftShift -----------------------------------
 
 // Shorts/Chars vector left shift
--- a/hotspot/src/cpu/x86/vm/x86_32.ad	Sat Sep 26 09:22:24 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/x86_32.ad	Wed Jul 05 20:51:27 2017 +0200
@@ -1004,10 +1004,10 @@
       __ vmovdqu(Address(rsp, dst_offset), xmm0);
       __ vmovdqu(xmm0, Address(rsp, -32));
     case Op_VecZ:
-      __ evmovdqu(Address(rsp, -64), xmm0, 2);
-      __ evmovdqu(xmm0, Address(rsp, src_offset), 2);
-      __ evmovdqu(Address(rsp, dst_offset), xmm0, 2);
-      __ evmovdqu(xmm0, Address(rsp, -64), 2);
+      __ evmovdqul(Address(rsp, -64), xmm0, 2);
+      __ evmovdqul(xmm0, Address(rsp, src_offset), 2);
+      __ evmovdqul(Address(rsp, dst_offset), xmm0, 2);
+      __ evmovdqul(xmm0, Address(rsp, -64), 2);
       break;
     default:
       ShouldNotReachHere();
--- a/hotspot/src/cpu/x86/vm/x86_64.ad	Sat Sep 26 09:22:24 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/x86_64.ad	Wed Jul 05 20:51:27 2017 +0200
@@ -1075,10 +1075,10 @@
       __ vmovdqu(Address(rsp, dst_offset), xmm0);
       __ vmovdqu(xmm0, Address(rsp, -32));
     case Op_VecZ:
-      __ evmovdqu(Address(rsp, -64), xmm0, 2);
-      __ evmovdqu(xmm0, Address(rsp, src_offset), 2);
-      __ evmovdqu(Address(rsp, dst_offset), xmm0, 2);
-      __ evmovdqu(xmm0, Address(rsp, -64), 2);
+      __ evmovdqul(Address(rsp, -64), xmm0, 2);
+      __ evmovdqul(xmm0, Address(rsp, src_offset), 2);
+      __ evmovdqul(Address(rsp, dst_offset), xmm0, 2);
+      __ evmovdqul(xmm0, Address(rsp, -64), 2);
       break;
     default:
       ShouldNotReachHere();
--- a/hotspot/src/os/linux/vm/os_linux.cpp	Sat Sep 26 09:22:24 2015 -0700
+++ b/hotspot/src/os/linux/vm/os_linux.cpp	Wed Jul 05 20:51:27 2017 +0200
@@ -2211,9 +2211,13 @@
   }
 }
 
-const char* search_string = IA32_ONLY("model name") AMD64_ONLY("model name")
-                            IA64_ONLY("") SPARC_ONLY("cpu")
-                            ARM32_ONLY("Processor") PPC_ONLY("Processor") AARCH64_ONLY("Processor");
+#if defined(AMD64) || defined(IA32) || defined(X32)
+const char* search_string = "model name";
+#elif defined(SPARC)
+const char* search_string = "cpu";
+#else
+const char* search_string = "Processor";
+#endif
 
 // Parses the cpuinfo file for string representing the model name.
 void os::get_summary_cpu_info(char* cpuinfo, size_t length) {
@@ -2248,9 +2252,25 @@
   }
   // cpuinfo not found or parsing failed, just print generic string.  The entire
   // /proc/cpuinfo file will be printed later in the file (or enough of it for x86)
-  strncpy(cpuinfo, IA32_ONLY("x86_32") AMD64_ONLY("x86_32")
-                   IA64_ONLY("IA64") SPARC_ONLY("sparcv9")
-                   ARM32_ONLY("ARM") PPC_ONLY("PPC64") AARCH64_ONLY("AArch64"), length);
+#if defined(AMD64)
+  strncpy(cpuinfo, "x86_64", length);
+#elif defined(IA32)
+  strncpy(cpuinfo, "x86_32", length);
+#elif defined(IA64)
+  strncpy(cpuinfo, "IA64", length);
+#elif defined(SPARC)
+  strncpy(cpuinfo, "sparcv9", length);
+#elif defined(AARCH64)
+  strncpy(cpuinfo, "AArch64", length);
+#elif defined(ARM)
+  strncpy(cpuinfo, "ARM", length);
+#elif defined(PPC)
+  strncpy(cpuinfo, "PPC64", length);
+#elif defined(ZERO_LIBARCH)
+  strncpy(cpuinfo, ZERO_LIBARCH, length);
+#else
+  strncpy(cpuinfo, "unknown", length);
+#endif
 }
 
 void os::print_siginfo(outputStream* st, void* siginfo) {
--- a/hotspot/src/os/windows/vm/os_windows.cpp	Sat Sep 26 09:22:24 2015 -0700
+++ b/hotspot/src/os/windows/vm/os_windows.cpp	Wed Jul 05 20:51:27 2017 +0200
@@ -4877,6 +4877,26 @@
 // Returns true=success, otherwise false.
 
 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);
+    }
+    return false;
+  }
+
+  // Executable memory was not mapped using CreateFileMapping/MapViewOfFileEx.
+  // Instead, executable region was allocated using VirtualAlloc(). See
+  // pd_map_memory() above.
+  //
+  // The following flags should match the 'exec_access' flages used for
+  // VirtualProtect() in pd_map_memory().
+  if (mem_info.Protect == PAGE_EXECUTE_READ ||
+      mem_info.Protect == PAGE_EXECUTE_READWRITE) {
+    return pd_release_memory(addr, bytes);
+  }
+
   BOOL result = UnmapViewOfFile(addr);
   if (result == 0) {
     if (PrintMiscellaneous && Verbose) {
--- a/hotspot/src/share/vm/adlc/formssel.cpp	Sat Sep 26 09:22:24 2015 -0700
+++ b/hotspot/src/share/vm/adlc/formssel.cpp	Wed Jul 05 20:51:27 2017 +0200
@@ -4143,6 +4143,7 @@
     "SubVB","SubVS","SubVI","SubVL","SubVF","SubVD",
     "MulVS","MulVI","MulVL","MulVF","MulVD",
     "DivVF","DivVD",
+    "SqrtVD",
     "AndV" ,"XorV" ,"OrV",
     "AddReductionVI", "AddReductionVL",
     "AddReductionVF", "AddReductionVD",
--- a/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp	Sat Sep 26 09:22:24 2015 -0700
+++ b/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp	Wed Jul 05 20:51:27 2017 +0200
@@ -304,8 +304,7 @@
 void ConcurrentMarkSweepGeneration::initialize_performance_counters() {
 
   const char* gen_name = "old";
-  GenCollectorPolicy* gcp = (GenCollectorPolicy*) GenCollectedHeap::heap()->collector_policy();
-
+  GenCollectorPolicy* gcp = GenCollectedHeap::heap()->gen_policy();
   // Generation Counters - generation 1, 1 subspace
   _gen_counters = new GenerationCounters(gen_name, 1, 1,
       gcp->min_old_size(), gcp->max_old_size(), &_virtual_space);
--- a/hotspot/src/share/vm/gc/g1/collectionSetChooser.cpp	Sat Sep 26 09:22:24 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/collectionSetChooser.cpp	Wed Jul 05 20:51:27 2017 +0200
@@ -83,7 +83,7 @@
   _regions((ResourceObj::set_allocation_type((address) &_regions,
                                              ResourceObj::C_HEAP),
                   100), true /* C_Heap */),
-    _curr_index(0), _length(0), _first_par_unreserved_idx(0),
+    _front(0), _end(0), _first_par_unreserved_idx(0),
     _region_live_threshold_bytes(0), _remaining_reclaimable_bytes(0) {
   _region_live_threshold_bytes =
     HeapRegion::GrainBytes * (size_t) G1MixedGCLiveThresholdPercent / 100;
@@ -91,19 +91,19 @@
 
 #ifndef PRODUCT
 void CollectionSetChooser::verify() {
-  guarantee(_length <= regions_length(),
-         err_msg("_length: %u regions length: %u", _length, regions_length()));
-  guarantee(_curr_index <= _length,
-            err_msg("_curr_index: %u _length: %u", _curr_index, _length));
+  guarantee(_end <= regions_length(),
+         err_msg("_end: %u regions length: %u", _end, regions_length()));
+  guarantee(_front <= _end,
+            err_msg("_front: %u _end: %u", _front, _end));
   uint index = 0;
   size_t sum_of_reclaimable_bytes = 0;
-  while (index < _curr_index) {
+  while (index < _front) {
     guarantee(regions_at(index) == NULL,
-              "all entries before _curr_index should be NULL");
+              "all entries before _front should be NULL");
     index += 1;
   }
   HeapRegion *prev = NULL;
-  while (index < _length) {
+  while (index < _end) {
     HeapRegion *curr = regions_at(index++);
     guarantee(curr != NULL, "Regions in _regions array cannot be NULL");
     guarantee(!curr->is_young(), "should not be young!");
@@ -132,15 +132,15 @@
     regions_trunc_to(_first_par_unreserved_idx);
   }
   _regions.sort(order_regions);
-  assert(_length <= regions_length(), "Requirement");
+  assert(_end <= regions_length(), "Requirement");
 #ifdef ASSERT
-  for (uint i = 0; i < _length; i++) {
+  for (uint i = 0; i < _end; i++) {
     assert(regions_at(i) != NULL, "Should be true by sorting!");
   }
 #endif // ASSERT
   if (G1PrintRegionLivenessInfo) {
     G1PrintRegionLivenessInfoClosure cl(gclog_or_tty, "Post-Sorting");
-    for (uint i = 0; i < _length; ++i) {
+    for (uint i = 0; i < _end; ++i) {
       HeapRegion* r = regions_at(i);
       cl.doHeapRegion(r);
     }
@@ -154,11 +154,19 @@
          err_msg("Pinned region shouldn't be added to the collection set (index %u)", hr->hrm_index()));
   assert(!hr->is_young(), "should not be young!");
   _regions.append(hr);
-  _length++;
+  _end++;
   _remaining_reclaimable_bytes += hr->reclaimable_bytes();
   hr->calc_gc_efficiency();
 }
 
+void CollectionSetChooser::push(HeapRegion* hr) {
+  assert(hr != NULL, "Can't put back a NULL region");
+  assert(_front >= 1, "Too many regions have been put back");
+  _front--;
+  regions_at_put(_front, hr);
+  _remaining_reclaimable_bytes += hr->reclaimable_bytes();
+}
+
 void CollectionSetChooser::prepare_for_par_region_addition(uint n_threads,
                                                            uint n_regions,
                                                            uint chunk_size) {
@@ -193,7 +201,7 @@
     // We could have just used atomics instead of taking the
     // lock. However, we currently don't have an atomic add for size_t.
     MutexLockerEx x(ParGCRareEvent_lock, Mutex::_no_safepoint_check_flag);
-    _length += region_num;
+    _end += region_num;
     _remaining_reclaimable_bytes += reclaimable_bytes;
   } else {
     assert(reclaimable_bytes == 0, "invariant");
@@ -202,7 +210,7 @@
 
 void CollectionSetChooser::clear() {
   _regions.clear();
-  _curr_index = 0;
-  _length = 0;
+  _front = 0;
+  _end = 0;
   _remaining_reclaimable_bytes = 0;
 };
--- a/hotspot/src/share/vm/gc/g1/collectionSetChooser.hpp	Sat Sep 26 09:22:24 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/collectionSetChooser.hpp	Wed Jul 05 20:51:27 2017 +0200
@@ -48,12 +48,10 @@
 
   // The index of the next candidate old region to be considered for
   // addition to the CSet.
-  uint _curr_index;
+  uint _front;
 
-  // The number of candidate old regions added to the CSet chooser.
-  // Note: this is not updated when removing a region using
-  // remove_and_move_to_next() below.
-  uint _length;
+  // The index of the last candidate old region
+  uint _end;
 
   // Keeps track of the start of the next array chunk to be claimed by
   // parallel GC workers.
@@ -73,31 +71,33 @@
   // collection without removing it from the CSet chooser.
   HeapRegion* peek() {
     HeapRegion* res = NULL;
-    if (_curr_index < _length) {
-      res = regions_at(_curr_index);
+    if (_front < _end) {
+      res = regions_at(_front);
       assert(res != NULL,
              err_msg("Unexpected NULL hr in _regions at index %u",
-                     _curr_index));
+                     _front));
     }
     return res;
   }
 
   // Remove the given region from the CSet chooser and move to the
-  // next one. The given region should be the current candidate region
-  // in the CSet chooser.
-  void remove_and_move_to_next(HeapRegion* hr) {
+  // next one.
+  HeapRegion* pop() {
+    HeapRegion* hr = regions_at(_front);
     assert(hr != NULL, "pre-condition");
-    assert(_curr_index < _length, "pre-condition");
-    assert(regions_at(_curr_index) == hr, "pre-condition");
-    regions_at_put(_curr_index, NULL);
+    assert(_front < _end, "pre-condition");
+    regions_at_put(_front, NULL);
     assert(hr->reclaimable_bytes() <= _remaining_reclaimable_bytes,
            err_msg("remaining reclaimable bytes inconsistent "
                    "from region: " SIZE_FORMAT " remaining: " SIZE_FORMAT,
                    hr->reclaimable_bytes(), _remaining_reclaimable_bytes));
     _remaining_reclaimable_bytes -= hr->reclaimable_bytes();
-    _curr_index += 1;
+    _front += 1;
+    return hr;
   }
 
+  void push(HeapRegion* hr);
+
   CollectionSetChooser();
 
   void sort_regions();
@@ -113,7 +113,7 @@
   }
 
   // Returns the number candidate old regions added
-  uint length() { return _length; }
+  uint length() { return _end; }
 
   // Serial version.
   void add_region(HeapRegion *hr);
@@ -135,7 +135,7 @@
   void clear();
 
   // Return the number of candidate regions that remain to be collected.
-  uint remaining_regions() { return _length - _curr_index; }
+  uint remaining_regions() { return _end - _front; }
 
   // Determine whether the CSet chooser has more candidate regions or not.
   bool is_empty() { return remaining_regions() == 0; }
--- a/hotspot/src/share/vm/gc/g1/concurrentG1Refine.cpp	Sat Sep 26 09:22:24 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/concurrentG1Refine.cpp	Wed Jul 05 20:51:27 2017 +0200
@@ -29,7 +29,7 @@
 #include "gc/g1/g1HotCardCache.hpp"
 #include "runtime/java.hpp"
 
-ConcurrentG1Refine::ConcurrentG1Refine(G1CollectedHeap* g1h, CardTableEntryClosure* refine_closure) :
+ConcurrentG1Refine::ConcurrentG1Refine(G1CollectedHeap* g1h) :
   _threads(NULL), _n_threads(0),
   _hot_card_cache(g1h)
 {
@@ -48,29 +48,46 @@
     FLAG_SET_DEFAULT(G1ConcRefinementRedZone, yellow_zone() * 2);
   }
   set_red_zone(MAX2<int>(G1ConcRefinementRedZone, yellow_zone()));
+}
 
-  _n_worker_threads = thread_num();
+ConcurrentG1Refine* ConcurrentG1Refine::create(G1CollectedHeap* g1h, CardTableEntryClosure* refine_closure, jint* ecode) {
+  ConcurrentG1Refine* cg1r = new ConcurrentG1Refine(g1h);
+  if (cg1r == NULL) {
+    *ecode = JNI_ENOMEM;
+    vm_shutdown_during_initialization("Could not create ConcurrentG1Refine");
+    return NULL;
+  }
+  cg1r->_n_worker_threads = thread_num();
   // We need one extra thread to do the young gen rset size sampling.
-  _n_threads = _n_worker_threads + 1;
+  cg1r->_n_threads = cg1r->_n_worker_threads + 1;
+
+  cg1r->reset_threshold_step();
 
-  reset_threshold_step();
-
-  _threads = NEW_C_HEAP_ARRAY(ConcurrentG1RefineThread*, _n_threads, mtGC);
+  cg1r->_threads = NEW_C_HEAP_ARRAY_RETURN_NULL(ConcurrentG1RefineThread*, cg1r->_n_threads, mtGC);
+  if (cg1r->_threads == NULL) {
+    *ecode = JNI_ENOMEM;
+    vm_shutdown_during_initialization("Could not allocate an array for ConcurrentG1RefineThread");
+    return NULL;
+  }
 
   uint worker_id_offset = DirtyCardQueueSet::num_par_ids();
 
   ConcurrentG1RefineThread *next = NULL;
-  for (uint i = _n_threads - 1; i != UINT_MAX; i--) {
-    ConcurrentG1RefineThread* t = new ConcurrentG1RefineThread(this, next, refine_closure, worker_id_offset, i);
+  for (uint i = cg1r->_n_threads - 1; i != UINT_MAX; i--) {
+    ConcurrentG1RefineThread* t = new ConcurrentG1RefineThread(cg1r, next, refine_closure, worker_id_offset, i);
     assert(t != NULL, "Conc refine should have been created");
     if (t->osthread() == NULL) {
-        vm_shutdown_during_initialization("Could not create ConcurrentG1RefineThread");
+      *ecode = JNI_ENOMEM;
+      vm_shutdown_during_initialization("Could not create ConcurrentG1RefineThread");
+      return NULL;
     }
 
-    assert(t->cg1r() == this, "Conc refine thread should refer to this");
-    _threads[i] = t;
+    assert(t->cg1r() == cg1r, "Conc refine thread should refer to this");
+    cg1r->_threads[i] = t;
     next = t;
   }
+  *ecode = JNI_OK;
+  return cg1r;
 }
 
 void ConcurrentG1Refine::reset_threshold_step() {
--- a/hotspot/src/share/vm/gc/g1/concurrentG1Refine.hpp	Sat Sep 26 09:22:24 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/concurrentG1Refine.hpp	Wed Jul 05 20:51:27 2017 +0200
@@ -71,10 +71,15 @@
   // Reset the threshold step value based of the current zone boundaries.
   void reset_threshold_step();
 
+  ConcurrentG1Refine(G1CollectedHeap* g1h);
+
  public:
-  ConcurrentG1Refine(G1CollectedHeap* g1h, CardTableEntryClosure* refine_closure);
   ~ConcurrentG1Refine();
 
+  // Returns ConcurrentG1Refine instance if succeeded to create/initialize ConcurrentG1Refine and ConcurrentG1RefineThread.
+  // Otherwise, returns NULL with error code.
+  static ConcurrentG1Refine* create(G1CollectedHeap* g1h, CardTableEntryClosure* refine_closure, jint* ecode);
+
   void init(G1RegionToSpaceMapper* card_counts_storage);
   void stop();
 
--- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp	Sat Sep 26 09:22:24 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp	Wed Jul 05 20:51:27 2017 +0200
@@ -2025,7 +2025,6 @@
   _survivor_evac_stats(YoungPLABSize, PLABWeight),
   _old_evac_stats(OldPLABSize, PLABWeight),
   _expand_heap_after_alloc_failure(true),
-  _surviving_young_words(NULL),
   _old_marking_cycles_started(0),
   _old_marking_cycles_completed(0),
   _heap_summary_sent(false),
@@ -2126,7 +2125,11 @@
 
   _refine_cte_cl = new RefineCardTableEntryClosure();
 
-  _cg1r = new ConcurrentG1Refine(this, _refine_cte_cl);
+  jint ecode = JNI_OK;
+  _cg1r = ConcurrentG1Refine::create(this, _refine_cte_cl, &ecode);
+  if (_cg1r == NULL) {
+    return ecode;
+  }
 
   // Reserve the maximum.
 
@@ -2397,6 +2400,10 @@
                                 // (for efficiency/performance)
 }
 
+CollectorPolicy* G1CollectedHeap::collector_policy() const {
+  return g1_policy();
+}
+
 size_t G1CollectedHeap::capacity() const {
   return _hrm.length() * HeapRegion::GrainBytes;
 }
@@ -3694,10 +3701,6 @@
   return (buffer_size * buffer_num + extra_cards) / oopSize;
 }
 
-size_t G1CollectedHeap::cards_scanned() {
-  return g1_rem_set()->cardsScanned();
-}
-
 class RegisterHumongousWithInCSetFastTestClosure : public HeapRegionClosure {
  private:
   size_t _total_humongous;
@@ -3838,36 +3841,6 @@
   cl.flush_rem_set_entries();
 }
 
-void G1CollectedHeap::setup_surviving_young_words() {
-  assert(_surviving_young_words == NULL, "pre-condition");
-  uint array_length = g1_policy()->young_cset_region_length();
-  _surviving_young_words = NEW_C_HEAP_ARRAY(size_t, (size_t) array_length, mtGC);
-  if (_surviving_young_words == NULL) {
-    vm_exit_out_of_memory(sizeof(size_t) * array_length, OOM_MALLOC_ERROR,
-                          "Not enough space for young surv words summary.");
-  }
-  memset(_surviving_young_words, 0, (size_t) array_length * sizeof(size_t));
-#ifdef ASSERT
-  for (uint i = 0;  i < array_length; ++i) {
-    assert( _surviving_young_words[i] == 0, "memset above" );
-  }
-#endif // !ASSERT
-}
-
-void G1CollectedHeap::update_surviving_young_words(size_t* surv_young_words) {
-  assert_at_safepoint(true);
-  uint array_length = g1_policy()->young_cset_region_length();
-  for (uint i = 0; i < array_length; ++i) {
-    _surviving_young_words[i] += surv_young_words[i];
-  }
-}
-
-void G1CollectedHeap::cleanup_surviving_young_words() {
-  guarantee( _surviving_young_words != NULL, "pre-condition" );
-  FREE_C_HEAP_ARRAY(size_t, _surviving_young_words);
-  _surviving_young_words = NULL;
-}
-
 #ifdef ASSERT
 class VerifyCSetClosure: public HeapRegionClosure {
 public:
@@ -4129,7 +4102,8 @@
         g1_policy()->print_collection_set(g1_policy()->inc_cset_head(), gclog_or_tty);
 #endif // YOUNG_LIST_VERBOSE
 
-        g1_policy()->finalize_cset(target_pause_time_ms);
+        double time_remaining_ms = g1_policy()->finalize_young_cset_part(target_pause_time_ms);
+        g1_policy()->finalize_old_cset_part(time_remaining_ms);
 
         evacuation_info.set_collectionset_regions(g1_policy()->cset_region_length());
 
@@ -4155,22 +4129,20 @@
         collection_set_iterate(&cl);
 #endif // ASSERT
 
-        setup_surviving_young_words();
-
         // Initialize the GC alloc regions.
         _allocator->init_gc_alloc_regions(evacuation_info);
 
+        G1ParScanThreadStateSet per_thread_states(this, workers()->active_workers(), g1_policy()->young_cset_region_length());
         // Actually do the work...
-        evacuate_collection_set(evacuation_info);
-
-        free_collection_set(g1_policy()->collection_set(), evacuation_info);
+        evacuate_collection_set(evacuation_info, &per_thread_states);
+
+        const size_t* surviving_young_words = per_thread_states.surviving_young_words();
+        free_collection_set(g1_policy()->collection_set(), evacuation_info, surviving_young_words);
 
         eagerly_reclaim_humongous_regions();
 
         g1_policy()->clear_collection_set();
 
-        cleanup_surviving_young_words();
-
         // Start a new incremental collection set for the next pause.
         g1_policy()->start_incremental_cset_building();
 
@@ -4255,7 +4227,8 @@
         // investigate this in CR 7178365.
         double sample_end_time_sec = os::elapsedTime();
         double pause_time_ms = (sample_end_time_sec - sample_start_time_sec) * MILLIUNITS;
-        g1_policy()->record_collection_pause_end(pause_time_ms);
+        size_t total_cards_scanned = per_thread_states.total_cards_scanned();
+        g1_policy()->record_collection_pause_end(pause_time_ms, total_cards_scanned);
 
         evacuation_info.set_collectionset_used_before(g1_policy()->collection_set_bytes_used_before());
         evacuation_info.set_bytes_copied(g1_policy()->bytes_copied_during_gc());
@@ -4541,15 +4514,15 @@
 
 class G1ParTask : public AbstractGangTask {
 protected:
-  G1CollectedHeap*       _g1h;
-  G1ParScanThreadState** _pss;
-  RefToScanQueueSet*     _queues;
-  G1RootProcessor*       _root_processor;
-  ParallelTaskTerminator _terminator;
-  uint _n_workers;
+  G1CollectedHeap*         _g1h;
+  G1ParScanThreadStateSet* _pss;
+  RefToScanQueueSet*       _queues;
+  G1RootProcessor*         _root_processor;
+  ParallelTaskTerminator   _terminator;
+  uint                     _n_workers;
 
 public:
-  G1ParTask(G1CollectedHeap* g1h, G1ParScanThreadState** per_thread_states, RefToScanQueueSet *task_queues, G1RootProcessor* root_processor, uint n_workers)
+  G1ParTask(G1CollectedHeap* g1h, G1ParScanThreadStateSet* per_thread_states, RefToScanQueueSet *task_queues, G1RootProcessor* root_processor, uint n_workers)
     : AbstractGangTask("G1 collection"),
       _g1h(g1h),
       _pss(per_thread_states),
@@ -4607,7 +4580,7 @@
 
       ReferenceProcessor*             rp = _g1h->ref_processor_stw();
 
-      G1ParScanThreadState*           pss = _pss[worker_id];
+      G1ParScanThreadState*           pss = _pss->state_for_worker(worker_id);
       pss->set_ref_processor(rp);
 
       bool only_young = _g1h->collector_state()->gcs_are_young();
@@ -4664,9 +4637,12 @@
                                       worker_id);
 
       G1ParPushHeapRSClosure push_heap_rs_cl(_g1h, pss);
-      _g1h->g1_rem_set()->oops_into_collection_set_do(&push_heap_rs_cl,
-                                                      weak_root_cl,
-                                                      worker_id);
+      size_t cards_scanned = _g1h->g1_rem_set()->oops_into_collection_set_do(&push_heap_rs_cl,
+                                                                             weak_root_cl,
+                                                                             worker_id);
+
+      _pss->add_cards_scanned(worker_id, cards_scanned);
+
       double strong_roots_sec = os::elapsedTime() - start_strong_roots_sec;
 
       double term_sec = 0.0;
@@ -5263,15 +5239,15 @@
 
 class G1STWRefProcTaskExecutor: public AbstractRefProcTaskExecutor {
 private:
-  G1CollectedHeap*        _g1h;
-  G1ParScanThreadState**  _pss;
-  RefToScanQueueSet*      _queues;
-  WorkGang*               _workers;
-  uint                    _active_workers;
+  G1CollectedHeap*          _g1h;
+  G1ParScanThreadStateSet*  _pss;
+  RefToScanQueueSet*        _queues;
+  WorkGang*                 _workers;
+  uint                      _active_workers;
 
 public:
   G1STWRefProcTaskExecutor(G1CollectedHeap* g1h,
-                           G1ParScanThreadState** per_thread_states,
+                           G1ParScanThreadStateSet* per_thread_states,
                            WorkGang* workers,
                            RefToScanQueueSet *task_queues,
                            uint n_workers) :
@@ -5295,14 +5271,14 @@
   typedef AbstractRefProcTaskExecutor::ProcessTask ProcessTask;
   ProcessTask&     _proc_task;
   G1CollectedHeap* _g1h;
-  G1ParScanThreadState** _pss;
+  G1ParScanThreadStateSet* _pss;
   RefToScanQueueSet* _task_queues;
   ParallelTaskTerminator* _terminator;
 
 public:
   G1STWRefProcTaskProxy(ProcessTask& proc_task,
                         G1CollectedHeap* g1h,
-                        G1ParScanThreadState** per_thread_states,
+                        G1ParScanThreadStateSet* per_thread_states,
                         RefToScanQueueSet *task_queues,
                         ParallelTaskTerminator* terminator) :
     AbstractGangTask("Process reference objects in parallel"),
@@ -5320,7 +5296,7 @@
 
     G1STWIsAliveClosure is_alive(_g1h);
 
-    G1ParScanThreadState*           pss = _pss[worker_id];
+    G1ParScanThreadState*          pss = _pss->state_for_worker(worker_id);
     pss->set_ref_processor(NULL);
 
     G1ParScanExtRootClosure        only_copy_non_heap_cl(_g1h, pss);
@@ -5399,14 +5375,14 @@
 
 class G1ParPreserveCMReferentsTask: public AbstractGangTask {
 protected:
-  G1CollectedHeap*       _g1h;
-  G1ParScanThreadState** _pss;
-  RefToScanQueueSet*     _queues;
-  ParallelTaskTerminator _terminator;
-  uint _n_workers;
+  G1CollectedHeap*         _g1h;
+  G1ParScanThreadStateSet* _pss;
+  RefToScanQueueSet*       _queues;
+  ParallelTaskTerminator   _terminator;
+  uint                     _n_workers;
 
 public:
-  G1ParPreserveCMReferentsTask(G1CollectedHeap* g1h, G1ParScanThreadState** per_thread_states, int workers, RefToScanQueueSet *task_queues) :
+  G1ParPreserveCMReferentsTask(G1CollectedHeap* g1h, G1ParScanThreadStateSet* per_thread_states, int workers, RefToScanQueueSet *task_queues) :
     AbstractGangTask("ParPreserveCMReferents"),
     _g1h(g1h),
     _pss(per_thread_states),
@@ -5419,7 +5395,7 @@
     ResourceMark rm;
     HandleMark   hm;
 
-    G1ParScanThreadState*          pss = _pss[worker_id];
+    G1ParScanThreadState*          pss = _pss->state_for_worker(worker_id);
     pss->set_ref_processor(NULL);
     assert(pss->queue_is_empty(), "both queue and overflow should be empty");
 
@@ -5480,7 +5456,7 @@
 };
 
 // Weak Reference processing during an evacuation pause (part 1).
-void G1CollectedHeap::process_discovered_references(G1ParScanThreadState** per_thread_states) {
+void G1CollectedHeap::process_discovered_references(G1ParScanThreadStateSet* per_thread_states) {
   double ref_proc_start = os::elapsedTime();
 
   ReferenceProcessor* rp = _ref_processor_stw;
@@ -5525,7 +5501,7 @@
   // JNI refs.
 
   // Use only a single queue for this PSS.
-  G1ParScanThreadState*           pss = per_thread_states[0];
+  G1ParScanThreadState*          pss = per_thread_states->state_for_worker(0);
   pss->set_ref_processor(NULL);
   assert(pss->queue_is_empty(), "pre-condition");
 
@@ -5586,7 +5562,7 @@
 }
 
 // Weak Reference processing during an evacuation pause (part 2).
-void G1CollectedHeap::enqueue_discovered_references(G1ParScanThreadState** per_thread_states) {
+void G1CollectedHeap::enqueue_discovered_references(G1ParScanThreadStateSet* per_thread_states) {
   double ref_enq_start = os::elapsedTime();
 
   ReferenceProcessor* rp = _ref_processor_stw;
@@ -5621,7 +5597,7 @@
   g1_policy()->phase_times()->record_ref_enq_time(ref_enq_time * 1000.0);
 }
 
-void G1CollectedHeap::evacuate_collection_set(EvacuationInfo& evacuation_info) {
+void G1CollectedHeap::evacuate_collection_set(EvacuationInfo& evacuation_info, G1ParScanThreadStateSet* per_thread_states) {
   _expand_heap_after_alloc_failure = true;
   _evacuation_failed = false;
 
@@ -5641,11 +5617,6 @@
   double start_par_time_sec = os::elapsedTime();
   double end_par_time_sec;
 
-  G1ParScanThreadState** per_thread_states = NEW_C_HEAP_ARRAY(G1ParScanThreadState*, n_workers, mtGC);
-  for (uint i = 0; i < n_workers; i++) {
-    per_thread_states[i] = new_par_scan_state(i);
-  }
-
   {
     G1RootProcessor root_processor(this, n_workers);
     G1ParTask g1_par_task(this, per_thread_states, _task_queues, &root_processor, n_workers);
@@ -5699,11 +5670,7 @@
   _allocator->release_gc_alloc_regions(evacuation_info);
   g1_rem_set()->cleanup_after_oops_into_collection_set_do();
 
-  for (uint i = 0; i < n_workers; i++) {
-    G1ParScanThreadState* pss = per_thread_states[i];
-    delete pss;
-  }
-  FREE_C_HEAP_ARRAY(G1ParScanThreadState*, per_thread_states);
+  per_thread_states->flush();
 
   record_obj_copy_mem_stats();
 
@@ -6054,7 +6021,7 @@
   g1_policy()->phase_times()->record_clear_ct_time(elapsed * 1000.0);
 }
 
-void G1CollectedHeap::free_collection_set(HeapRegion* cs_head, EvacuationInfo& evacuation_info) {
+void G1CollectedHeap::free_collection_set(HeapRegion* cs_head, EvacuationInfo& evacuation_info, const size_t* surviving_young_words) {
   size_t pre_used = 0;
   FreeRegionList local_free_list("Local List for CSet Freeing");
 
@@ -6108,7 +6075,7 @@
       int index = cur->young_index_in_cset();
       assert(index != -1, "invariant");
       assert((uint) index < policy->young_cset_region_length(), "invariant");
-      size_t words_survived = _surviving_young_words[index];
+      size_t words_survived = surviving_young_words[index];
       cur->record_surv_words_in_group(words_survived);
 
       // At this point the we have 'popped' cur from the collection set
--- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.hpp	Sat Sep 26 09:22:24 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.hpp	Wed Jul 05 20:51:27 2017 +0200
@@ -56,6 +56,7 @@
 class GenerationSpec;
 class OopsInHeapRegionClosure;
 class G1ParScanThreadState;
+class G1ParScanThreadStateSet;
 class G1KlassScanClosure;
 class G1ParScanThreadState;
 class ObjectClosure;
@@ -192,6 +193,7 @@
 
   // Closures used in implementation.
   friend class G1ParScanThreadState;
+  friend class G1ParScanThreadStateSet;
   friend class G1ParTask;
   friend class G1PLABAllocator;
   friend class G1PrepareCompactClosure;
@@ -309,14 +311,8 @@
 
   volatile unsigned _gc_time_stamp;
 
-  size_t* _surviving_young_words;
-
   G1HRPrinter _hr_printer;
 
-  void setup_surviving_young_words();
-  void update_surviving_young_words(size_t* surv_young_words);
-  void cleanup_surviving_young_words();
-
   // It decides whether an explicit GC should start a concurrent cycle
   // instead of doing a STW GC. Currently, a concurrent cycle is
   // explicitly started if:
@@ -584,11 +580,11 @@
 
   // Process any reference objects discovered during
   // an incremental evacuation pause.
-  void process_discovered_references(G1ParScanThreadState** per_thread_states);
+  void process_discovered_references(G1ParScanThreadStateSet* per_thread_states);
 
   // Enqueue any remaining discovered references
   // after processing.
-  void enqueue_discovered_references(G1ParScanThreadState** per_thread_states);
+  void enqueue_discovered_references(G1ParScanThreadStateSet* per_thread_states);
 
 public:
   WorkGang* workers() const { return _workers; }
@@ -683,9 +679,6 @@
   // Allocates a new heap region instance.
   HeapRegion* new_heap_region(uint hrs_index, MemRegion mr);
 
-  // Allocates a new per thread par scan state for the given thread id.
-  G1ParScanThreadState* new_par_scan_state(uint worker_id);
-
   // Allocate the highest free region in the reserved heap. This will commit
   // regions as necessary.
   HeapRegion* alloc_highest_free_region();
@@ -799,7 +792,7 @@
   bool do_collection_pause_at_safepoint(double target_pause_time_ms);
 
   // Actually do the work of evacuating the collection set.
-  void evacuate_collection_set(EvacuationInfo& evacuation_info);
+  void evacuate_collection_set(EvacuationInfo& evacuation_info, G1ParScanThreadStateSet* per_thread_states);
 
   // Print the header for the per-thread termination statistics.
   static void print_termination_stats_hdr(outputStream* const st);
@@ -833,7 +826,7 @@
 
   // After a collection pause, make the regions in the CS into free
   // regions.
-  void free_collection_set(HeapRegion* cs_head, EvacuationInfo& evacuation_info);
+  void free_collection_set(HeapRegion* cs_head, EvacuationInfo& evacuation_info, const size_t* surviving_young_words);
 
   // Abandon the current collection set without recording policy
   // statistics or updating free lists.
@@ -1057,7 +1050,7 @@
   // The current policy object for the collector.
   G1CollectorPolicy* g1_policy() const { return _g1_policy; }
 
-  virtual CollectorPolicy* collector_policy() const { return (CollectorPolicy*) g1_policy(); }
+  virtual CollectorPolicy* collector_policy() const;
 
   // Adaptive size policy.  No such thing for g1.
   virtual AdaptiveSizePolicy* size_policy() { return NULL; }
@@ -1610,7 +1603,6 @@
 
 public:
   size_t pending_card_num();
-  size_t cards_scanned();
 
 protected:
   size_t _max_heap_capacity;
--- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap_ext.cpp	Sat Sep 26 09:22:24 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap_ext.cpp	Wed Jul 05 20:51:27 2017 +0200
@@ -38,7 +38,3 @@
                                              MemRegion mr) {
   return new HeapRegion(hrs_index, bot_shared(), mr);
 }
-
-G1ParScanThreadState* G1CollectedHeap::new_par_scan_state(uint worker_id) {
-  return new G1ParScanThreadState(this, worker_id);
-}
--- a/hotspot/src/share/vm/gc/g1/g1CollectorPolicy.cpp	Sat Sep 26 09:22:24 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1CollectorPolicy.cpp	Wed Jul 05 20:51:27 2017 +0200
@@ -923,7 +923,7 @@
 // Anything below that is considered to be zero
 #define MIN_TIMER_GRANULARITY 0.0000001
 
-void G1CollectorPolicy::record_collection_pause_end(double pause_time_ms) {
+void G1CollectorPolicy::record_collection_pause_end(double pause_time_ms, size_t cards_scanned) {
   double end_time_sec = os::elapsedTime();
   assert(_cur_collection_pause_used_regions_at_start >= cset_region_length(),
          "otherwise, the subtraction below does not make sense");
@@ -1052,8 +1052,6 @@
       _cost_per_card_ms_seq->add(cost_per_card_ms);
     }
 
-    size_t cards_scanned = _g1->cards_scanned();
-
     double cost_per_entry_ms = 0.0;
     if (cards_scanned > 10) {
       cost_per_entry_ms = phase_times()->average_time_ms(G1GCPhaseTimes::ScanRS) / (double) cards_scanned;
@@ -1871,7 +1869,7 @@
 }
 
 
-void G1CollectorPolicy::finalize_cset(double target_pause_time_ms) {
+double G1CollectorPolicy::finalize_young_cset_part(double target_pause_time_ms) {
   double young_start_time_sec = os::elapsedTime();
 
   YoungList* young_list = _g1->young_list();
@@ -1883,7 +1881,6 @@
   guarantee(_collection_set == NULL, "Precondition");
 
   double base_time_ms = predict_base_elapsed_time_ms(_pending_cards);
-  double predicted_pause_time_ms = base_time_ms;
   double time_remaining_ms = MAX2(target_pause_time_ms - base_time_ms, 0.0);
 
   ergo_verbose4(ErgoCSetConstruction | ErgoHigh,
@@ -1927,15 +1924,16 @@
   _collection_set = _inc_cset_head;
   _collection_set_bytes_used_before = _inc_cset_bytes_used_before;
   time_remaining_ms = MAX2(time_remaining_ms - _inc_cset_predicted_elapsed_time_ms, 0.0);
-  predicted_pause_time_ms += _inc_cset_predicted_elapsed_time_ms;
 
-  ergo_verbose3(ErgoCSetConstruction | ErgoHigh,
+  ergo_verbose4(ErgoCSetConstruction | ErgoHigh,
                 "add young regions to CSet",
                 ergo_format_region("eden")
                 ergo_format_region("survivors")
-                ergo_format_ms("predicted young region time"),
+                ergo_format_ms("predicted young region time")
+                ergo_format_ms("target pause time"),
                 eden_region_length, survivor_region_length,
-                _inc_cset_predicted_elapsed_time_ms);
+                _inc_cset_predicted_elapsed_time_ms,
+                target_pause_time_ms);
 
   // The number of recorded young regions is the incremental
   // collection set's current size
@@ -1944,8 +1942,13 @@
   double young_end_time_sec = os::elapsedTime();
   phase_times()->record_young_cset_choice_time_ms((young_end_time_sec - young_start_time_sec) * 1000.0);
 
-  // Set the start of the non-young choice time.
-  double non_young_start_time_sec = young_end_time_sec;
+  return time_remaining_ms;
+}
+
+void G1CollectorPolicy::finalize_old_cset_part(double time_remaining_ms) {
+  double non_young_start_time_sec = os::elapsedTime();
+  double predicted_old_time_ms = 0.0;
+
 
   if (!collector_state()->gcs_are_young()) {
     CollectionSetChooser* cset_chooser = _collectionSetChooser;
@@ -2033,8 +2036,8 @@
 
       // We will add this region to the CSet.
       time_remaining_ms = MAX2(time_remaining_ms - predicted_time_ms, 0.0);
-      predicted_pause_time_ms += predicted_time_ms;
-      cset_chooser->remove_and_move_to_next(hr);
+      predicted_old_time_ms += predicted_time_ms;
+      cset_chooser->pop(); // already have region via peek()
       _g1->old_set_remove(hr);
       add_old_region_to_cset(hr);
 
@@ -2068,16 +2071,13 @@
 
   stop_incremental_cset_building();
 
-  ergo_verbose5(ErgoCSetConstruction,
+  ergo_verbose3(ErgoCSetConstruction,
                 "finish choosing CSet",
-                ergo_format_region("eden")
-                ergo_format_region("survivors")
                 ergo_format_region("old")
-                ergo_format_ms("predicted pause time")
-                ergo_format_ms("target pause time"),
-                eden_region_length, survivor_region_length,
+                ergo_format_ms("predicted old region time")
+                ergo_format_ms("time remaining"),
                 old_cset_region_length(),
-                predicted_pause_time_ms, target_pause_time_ms);
+                predicted_old_time_ms, time_remaining_ms);
 
   double non_young_end_time_sec = os::elapsedTime();
   phase_times()->record_non_young_cset_choice_time_ms((non_young_end_time_sec - non_young_start_time_sec) * 1000.0);
--- a/hotspot/src/share/vm/gc/g1/g1CollectorPolicy.hpp	Sat Sep 26 09:22:24 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1CollectorPolicy.hpp	Wed Jul 05 20:51:27 2017 +0200
@@ -473,7 +473,7 @@
 
   // The number of bytes in the collection set before the pause. Set from
   // the incrementally built collection set at the start of an evacuation
-  // pause, and incremented in finalize_cset() when adding old regions
+  // pause, and incremented in finalize_old_cset_part() when adding old regions
   // (if any) to the collection set.
   size_t _collection_set_bytes_used_before;
 
@@ -634,7 +634,7 @@
 
   // Record the start and end of an evacuation pause.
   void record_collection_pause_start(double start_time_sec);
-  void record_collection_pause_end(double pause_time_ms);
+  void record_collection_pause_end(double pause_time_ms, size_t cards_scanned);
 
   // Record the start and end of a full collection.
   void record_full_collection_start();
@@ -689,7 +689,8 @@
   // Choose a new collection set.  Marks the chosen regions as being
   // "in_collection_set", and links them together.  The head and number of
   // the collection set are available via access methods.
-  void finalize_cset(double target_pause_time_ms);
+  double finalize_young_cset_part(double target_pause_time_ms);
+  virtual void finalize_old_cset_part(double time_remaining_ms);
 
   // The head of the list (via "next_in_collection_set()") representing the
   // current collection set.
@@ -865,8 +866,8 @@
     return _recorded_survivor_regions;
   }
 
-  void record_thread_age_table(ageTable* age_table) {
-    _survivors_age_table.merge_par(age_table);
+  void record_age_table(ageTable* age_table) {
+    _survivors_age_table.merge(age_table);
   }
 
   void update_max_gc_locker_expansion();
--- a/hotspot/src/share/vm/gc/g1/g1EvacStats.cpp	Sat Sep 26 09:22:24 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1EvacStats.cpp	Wed Jul 05 20:51:27 2017 +0200
@@ -46,11 +46,11 @@
     if (_allocated == 0) {
       assert((_unused == 0),
              err_msg("Inconsistency in PLAB stats: "
-                     "_allocated: "SIZE_FORMAT", "
-                     "_wasted: "SIZE_FORMAT", "
-                     "_region_end_waste: "SIZE_FORMAT", "
-                     "_unused: "SIZE_FORMAT", "
-                     "_used  : "SIZE_FORMAT,
+                     "_allocated: " SIZE_FORMAT ", "
+                     "_wasted: " SIZE_FORMAT ", "
+                     "_region_end_waste: " SIZE_FORMAT ", "
+                     "_unused: " SIZE_FORMAT ", "
+                     "_used  : " SIZE_FORMAT,
                      _allocated, _wasted, _region_end_waste, _unused, used()));
       _allocated = 1;
     }
--- a/hotspot/src/share/vm/gc/g1/g1ParScanThreadState.cpp	Sat Sep 26 09:22:24 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1ParScanThreadState.cpp	Wed Jul 05 20:51:27 2017 +0200
@@ -32,7 +32,7 @@
 #include "oops/oop.inline.hpp"
 #include "runtime/prefetch.inline.hpp"
 
-G1ParScanThreadState::G1ParScanThreadState(G1CollectedHeap* g1h, uint worker_id)
+G1ParScanThreadState::G1ParScanThreadState(G1CollectedHeap* g1h, uint worker_id, size_t young_cset_length)
   : _g1h(g1h),
     _refs(g1h->task_queue(worker_id)),
     _dcq(&g1h->dirty_card_queue_set()),
@@ -51,8 +51,8 @@
   // non-young regions (where the age is -1)
   // We also add a few elements at the beginning and at the end in
   // an attempt to eliminate cache contention
-  uint real_length = 1 + _g1h->g1_policy()->young_cset_region_length();
-  uint array_length = PADDING_ELEM_NUM +
+  size_t real_length = 1 + young_cset_length;
+  size_t array_length = PADDING_ELEM_NUM +
                       real_length +
                       PADDING_ELEM_NUM;
   _surviving_young_words_base = NEW_C_HEAP_ARRAY(size_t, array_length, mtGC);
@@ -60,7 +60,7 @@
     vm_exit_out_of_memory(array_length * sizeof(size_t), OOM_MALLOC_ERROR,
                           "Not enough space for young surv histo.");
   _surviving_young_words = _surviving_young_words_base + PADDING_ELEM_NUM;
-  memset(_surviving_young_words, 0, (size_t) real_length * sizeof(size_t));
+  memset(_surviving_young_words, 0, real_length * sizeof(size_t));
 
   _plab_allocator = G1PLABAllocator::create_allocator(_g1h->allocator());
 
@@ -71,13 +71,21 @@
   _dest[InCSetState::Old]          = InCSetState::Old;
 }
 
-G1ParScanThreadState::~G1ParScanThreadState() {
+// Pass locally gathered statistics to global state.
+void G1ParScanThreadState::flush(size_t* surviving_young_words) {
+  _dcq.flush();
   // Update allocation statistics.
   _plab_allocator->flush_and_retire_stats();
+  _g1h->g1_policy()->record_age_table(&_age_table);
+
+  uint length = _g1h->g1_policy()->young_cset_region_length();
+  for (uint region_index = 0; region_index < length; region_index++) {
+    surviving_young_words[region_index] += _surviving_young_words[region_index];
+  }
+}
+
+G1ParScanThreadState::~G1ParScanThreadState() {
   delete _plab_allocator;
-  _g1h->g1_policy()->record_thread_age_table(&_age_table);
-  // Update heap statistics.
-  _g1h->update_surviving_young_words(_surviving_young_words);
   FREE_C_HEAP_ARRAY(size_t, _surviving_young_words_base);
 }
 
@@ -314,6 +322,42 @@
   }
 }
 
+G1ParScanThreadState* G1ParScanThreadStateSet::state_for_worker(uint worker_id) {
+  assert(worker_id < _n_workers, "out of bounds access");
+  return _states[worker_id];
+}
+
+void G1ParScanThreadStateSet::add_cards_scanned(uint worker_id, size_t cards_scanned) {
+  assert(worker_id < _n_workers, "out of bounds access");
+  _cards_scanned[worker_id] += cards_scanned;
+}
+
+size_t G1ParScanThreadStateSet::total_cards_scanned() const {
+  assert(_flushed, "thread local state from the per thread states should have been flushed");
+  return _total_cards_scanned;
+}
+
+const size_t* G1ParScanThreadStateSet::surviving_young_words() const {
+  assert(_flushed, "thread local state from the per thread states should have been flushed");
+  return _surviving_young_words_total;
+}
+
+void G1ParScanThreadStateSet::flush() {
+  assert(!_flushed, "thread local state from the per thread states should be flushed once");
+  assert(_total_cards_scanned == 0, "should have been cleared");
+
+  for (uint worker_index = 0; worker_index < _n_workers; ++worker_index) {
+    G1ParScanThreadState* pss = _states[worker_index];
+
+    _total_cards_scanned += _cards_scanned[worker_index];
+
+    pss->flush(_surviving_young_words_total);
+    delete pss;
+    _states[worker_index] = NULL;
+  }
+  _flushed = true;
+}
+
 oop G1ParScanThreadState::handle_evacuation_failure_par(oop old, markOop m) {
   assert(_g1h->obj_in_cs(old),
          err_msg("Object " PTR_FORMAT " should be in the CSet", p2i(old)));
--- a/hotspot/src/share/vm/gc/g1/g1ParScanThreadState.hpp	Sat Sep 26 09:22:24 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1ParScanThreadState.hpp	Wed Jul 05 20:51:27 2017 +0200
@@ -82,7 +82,7 @@
   }
 
  public:
-  G1ParScanThreadState(G1CollectedHeap* g1h, uint worker_id);
+  G1ParScanThreadState(G1CollectedHeap* g1h, uint worker_id, size_t young_cset_length);
   ~G1ParScanThreadState();
 
   void set_ref_processor(ReferenceProcessor* rp) { _scanner.set_ref_processor(rp); }
@@ -121,6 +121,8 @@
     return _surviving_young_words + 1;
   }
 
+  void flush(size_t* surviving_young_words);
+
  private:
   #define G1_PARTIAL_ARRAY_MASK 0x2
 
@@ -189,4 +191,48 @@
   oop handle_evacuation_failure_par(oop obj, markOop m);
 };
 
+class G1ParScanThreadStateSet : public StackObj {
+  G1CollectedHeap* _g1h;
+  G1ParScanThreadState** _states;
+  size_t* _surviving_young_words_total;
+  size_t* _cards_scanned;
+  size_t _total_cards_scanned;
+  uint _n_workers;
+  bool _flushed;
+
+ public:
+  G1ParScanThreadStateSet(G1CollectedHeap* g1h, uint n_workers, size_t young_cset_length) :
+      _g1h(g1h),
+      _states(NEW_C_HEAP_ARRAY(G1ParScanThreadState*, n_workers, mtGC)),
+      _surviving_young_words_total(NEW_C_HEAP_ARRAY(size_t, young_cset_length, mtGC)),
+      _cards_scanned(NEW_C_HEAP_ARRAY(size_t, n_workers, mtGC)),
+      _total_cards_scanned(0),
+      _n_workers(n_workers),
+      _flushed(false) {
+    for (uint i = 0; i < n_workers; ++i) {
+      _states[i] = new_par_scan_state(i, young_cset_length);
+    }
+    memset(_surviving_young_words_total, 0, young_cset_length * sizeof(size_t));
+    memset(_cards_scanned, 0, n_workers * sizeof(size_t));
+  }
+
+  ~G1ParScanThreadStateSet() {
+    assert(_flushed, "thread local state from the per thread states should have been flushed");
+    FREE_C_HEAP_ARRAY(G1ParScanThreadState*, _states);
+    FREE_C_HEAP_ARRAY(size_t, _surviving_young_words_total);
+    FREE_C_HEAP_ARRAY(size_t, _cards_scanned);
+  }
+
+  void flush();
+
+  G1ParScanThreadState* state_for_worker(uint worker_id);
+
+  void add_cards_scanned(uint worker_id, size_t cards_scanned);
+  size_t total_cards_scanned() const;
+  const size_t* surviving_young_words() const;
+
+ private:
+  G1ParScanThreadState* new_par_scan_state(uint worker_id, size_t young_cset_length);
+};
+
 #endif // SHARE_VM_GC_G1_G1PARSCANTHREADSTATE_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/gc/g1/g1ParScanThreadState_ext.cpp	Wed Jul 05 20:51:27 2017 +0200
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ *
+ */
+
+#include "precompiled.hpp"
+
+#include "gc/g1/g1ParScanThreadState.hpp"
+
+G1ParScanThreadState* G1ParScanThreadStateSet::new_par_scan_state(uint worker_id, size_t young_cset_length) {
+  return new G1ParScanThreadState(_g1h, worker_id, young_cset_length);
+}
--- a/hotspot/src/share/vm/gc/g1/g1RemSet.cpp	Sat Sep 26 09:22:24 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1RemSet.cpp	Wed Jul 05 20:51:27 2017 +0200
@@ -76,7 +76,6 @@
     _ct_bs(ct_bs), _g1p(_g1->g1_policy()),
     _cg1r(g1->concurrent_g1_refine()),
     _cset_rs_update_cl(NULL),
-    _cards_scanned(NULL), _total_cards_scanned(0),
     _prev_period_summary()
 {
   _cset_rs_update_cl = NEW_C_HEAP_ARRAY(G1ParPushHeapRSClosure*, n_workers(), mtGC);
@@ -228,9 +227,9 @@
   size_t cards_looked_up() { return _cards;}
 };
 
-void G1RemSet::scanRS(G1ParPushHeapRSClosure* oc,
-                      OopClosure* non_heap_roots,
-                      uint worker_i) {
+size_t G1RemSet::scanRS(G1ParPushHeapRSClosure* oc,
+                        OopClosure* non_heap_roots,
+                        uint worker_i) {
   double rs_time_start = os::elapsedTime();
 
   G1CodeBlobClosure code_root_cl(non_heap_roots);
@@ -246,11 +245,10 @@
   double scan_rs_time_sec = (os::elapsedTime() - rs_time_start)
                             - scanRScl.strong_code_root_scan_time_sec();
 
-  assert(_cards_scanned != NULL, "invariant");
-  _cards_scanned[worker_i] = scanRScl.cards_done();
-
   _g1p->phase_times()->record_time_secs(G1GCPhaseTimes::ScanRS, worker_i, scan_rs_time_sec);
   _g1p->phase_times()->record_time_secs(G1GCPhaseTimes::CodeRoots, worker_i, scanRScl.strong_code_root_scan_time_sec());
+
+  return scanRScl.cards_done();
 }
 
 // Closure used for updating RSets and recording references that
@@ -298,9 +296,9 @@
   HeapRegionRemSet::cleanup();
 }
 
-void G1RemSet::oops_into_collection_set_do(G1ParPushHeapRSClosure* oc,
-                                           OopClosure* non_heap_roots,
-                                           uint worker_i) {
+size_t G1RemSet::oops_into_collection_set_do(G1ParPushHeapRSClosure* oc,
+                                             OopClosure* non_heap_roots,
+                                             uint worker_i) {
 #if CARD_REPEAT_HISTO
   ct_freq_update_histo_and_reset();
 #endif
@@ -322,10 +320,11 @@
   DirtyCardQueue into_cset_dcq(&_g1->into_cset_dirty_card_queue_set());
 
   updateRS(&into_cset_dcq, worker_i);
-  scanRS(oc, non_heap_roots, worker_i);
+  size_t cards_scanned = scanRS(oc, non_heap_roots, worker_i);
 
   // We now clear the cached values of _cset_rs_update_cl for this worker
   _cset_rs_update_cl[worker_i] = NULL;
+  return cards_scanned;
 }
 
 void G1RemSet::prepare_for_oops_into_collection_set_do() {
@@ -333,23 +332,9 @@
   _g1->set_refine_cte_cl_concurrency(false);
   DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
   dcqs.concatenate_logs();
-
-  guarantee( _cards_scanned == NULL, "invariant" );
-  _cards_scanned = NEW_C_HEAP_ARRAY(size_t, n_workers(), mtGC);
-  for (uint i = 0; i < n_workers(); ++i) {
-    _cards_scanned[i] = 0;
-  }
-  _total_cards_scanned = 0;
 }
 
 void G1RemSet::cleanup_after_oops_into_collection_set_do() {
-  guarantee( _cards_scanned != NULL, "invariant" );
-  _total_cards_scanned = 0;
-  for (uint i = 0; i < n_workers(); ++i) {
-    _total_cards_scanned += _cards_scanned[i];
-  }
-  FREE_C_HEAP_ARRAY(size_t, _cards_scanned);
-  _cards_scanned = NULL;
   // Cleanup after copy
   _g1->set_refine_cte_cl_concurrency(true);
   // Set all cards back to clean.
--- a/hotspot/src/share/vm/gc/g1/g1RemSet.hpp	Sat Sep 26 09:22:24 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1RemSet.hpp	Wed Jul 05 20:51:27 2017 +0200
@@ -62,9 +62,6 @@
 
   ConcurrentG1Refine*    _cg1r;
 
-  size_t*                _cards_scanned;
-  size_t                 _total_cards_scanned;
-
   // Used for caching the closure that is responsible for scanning
   // references into the collection set.
   G1ParPushHeapRSClosure** _cset_rs_update_cl;
@@ -94,9 +91,12 @@
   // partitioning the work to be done. It should be the same as
   // the "i" passed to the calling thread's work(i) function.
   // In the sequential case this param will be ignored.
-  void oops_into_collection_set_do(G1ParPushHeapRSClosure* blk,
-                                   OopClosure* non_heap_roots,
-                                   uint worker_i);
+  //
+  // Returns the number of cards scanned while looking for pointers
+  // into the collection set.
+  size_t oops_into_collection_set_do(G1ParPushHeapRSClosure* blk,
+                                     OopClosure* non_heap_roots,
+                                     uint worker_i);
 
   // Prepare for and cleanup after an oops_into_collection_set_do
   // call.  Must call each of these once before and after (in sequential
@@ -106,14 +106,13 @@
   void prepare_for_oops_into_collection_set_do();
   void cleanup_after_oops_into_collection_set_do();
 
-  void scanRS(G1ParPushHeapRSClosure* oc,
-              OopClosure* non_heap_roots,
-              uint worker_i);
+  size_t scanRS(G1ParPushHeapRSClosure* oc,
+                OopClosure* non_heap_roots,
+                uint worker_i);
 
   void updateRS(DirtyCardQueue* into_cset_dcq, uint worker_i);
 
   CardTableModRefBS* ct_bs() { return _ct_bs; }
-  size_t cardsScanned() { return _total_cards_scanned; }
 
   // Record, if necessary, the fact that *p (where "p" is in region "from",
   // which is required to be non-NULL) has changed to a new non-NULL value.
--- a/hotspot/src/share/vm/gc/parallel/parallelScavengeHeap.hpp	Sat Sep 26 09:22:24 2015 -0700
+++ b/hotspot/src/share/vm/gc/parallel/parallelScavengeHeap.hpp	Wed Jul 05 20:51:27 2017 +0200
@@ -87,7 +87,7 @@
     return CollectedHeap::ParallelScavengeHeap;
   }
 
-  virtual CollectorPolicy* collector_policy() const { return (CollectorPolicy*) _collector_policy; }
+  virtual CollectorPolicy* collector_policy() const { return _collector_policy; }
 
   static PSYoungGen* young_gen() { return _young_gen; }
   static PSOldGen* old_gen()     { return _old_gen; }
--- a/hotspot/src/share/vm/gc/serial/defNewGeneration.cpp	Sat Sep 26 09:22:24 2015 -0700
+++ b/hotspot/src/share/vm/gc/serial/defNewGeneration.cpp	Wed Jul 05 20:51:27 2017 +0200
@@ -213,7 +213,7 @@
   _max_eden_size = size - (2*_max_survivor_size);
 
   // allocate the performance counters
-  GenCollectorPolicy* gcp = (GenCollectorPolicy*)gch->collector_policy();
+  GenCollectorPolicy* gcp = gch->gen_policy();
 
   // Generation counters -- generation 0, 3 subspaces
   _gen_counters = new GenerationCounters("new", 0, 3,
--- a/hotspot/src/share/vm/gc/serial/tenuredGeneration.cpp	Sat Sep 26 09:22:24 2015 -0700
+++ b/hotspot/src/share/vm/gc/serial/tenuredGeneration.cpp	Wed Jul 05 20:51:27 2017 +0200
@@ -57,8 +57,7 @@
   // initialize performance counters
 
   const char* gen_name = "old";
-  GenCollectorPolicy* gcp = (GenCollectorPolicy*) GenCollectedHeap::heap()->collector_policy();
-
+  GenCollectorPolicy* gcp = GenCollectedHeap::heap()->gen_policy();
   // Generation Counters -- generation 1, 1 subspace
   _gen_counters = new GenerationCounters(gen_name, 1, 1,
       gcp->min_old_size(), gcp->max_old_size(), &_virtual_space);
--- a/hotspot/src/share/vm/gc/shared/ageTable.cpp	Sat Sep 26 09:22:24 2015 -0700
+++ b/hotspot/src/share/vm/gc/shared/ageTable.cpp	Wed Jul 05 20:51:27 2017 +0200
@@ -28,7 +28,6 @@
 #include "gc/shared/collectorPolicy.hpp"
 #include "gc/shared/gcPolicyCounters.hpp"
 #include "memory/resourceArea.hpp"
-#include "runtime/atomic.inline.hpp"
 #include "utilities/copy.hpp"
 
 /* Copyright (c) 1992, 2015, Oracle and/or its affiliates, and Stanford University.
@@ -73,12 +72,6 @@
   }
 }
 
-void ageTable::merge_par(ageTable* subTable) {
-  for (int i = 0; i < table_size; i++) {
-    Atomic::add_ptr(subTable->sizes[i], &sizes[i]);
-  }
-}
-
 uint ageTable::compute_tenuring_threshold(size_t survivor_capacity, GCPolicyCounters* gc_counters) {
   size_t desired_survivor_size = (size_t)((((double) survivor_capacity)*TargetSurvivorRatio)/100);
   uint result;
--- a/hotspot/src/share/vm/gc/shared/ageTable.hpp	Sat Sep 26 09:22:24 2015 -0700
+++ b/hotspot/src/share/vm/gc/shared/ageTable.hpp	Wed Jul 05 20:51:27 2017 +0200
@@ -68,7 +68,6 @@
   // Merge another age table with the current one.  Used
   // for parallel young generation gc.
   void merge(ageTable* subTable);
-  void merge_par(ageTable* subTable);
 
   // calculate new tenuring threshold based on age information
   uint compute_tenuring_threshold(size_t survivor_capacity, GCPolicyCounters* gc_counters);
--- a/hotspot/src/share/vm/gc/shared/blockOffsetTable.cpp	Sat Sep 26 09:22:24 2015 -0700
+++ b/hotspot/src/share/vm/gc/shared/blockOffsetTable.cpp	Wed Jul 05 20:51:27 2017 +0200
@@ -447,14 +447,16 @@
       } else {
         // Unilaterally fix the first (num_pref_cards - 1) following
         // the "offset card" in the suffix block.
+        const size_t right_most_fixed_index = suff_index + num_pref_cards - 1;
         set_remainder_to_point_to_start_incl(suff_index + 1,
-          suff_index + num_pref_cards - 1, true /* reducing */);
+          right_most_fixed_index, true /* reducing */);
         // Fix the appropriate cards in the remainder of the
         // suffix block -- these are the last num_pref_cards
         // cards in each power block of the "new" range plumbed
         // from suff_addr.
         bool more = true;
         uint i = 1;
+        // Fix the first power block with  back_by > num_pref_cards.
         while (more && (i < N_powers)) {
           size_t back_by = power_to_cards_back(i);
           size_t right_index = suff_index + back_by - 1;
@@ -463,6 +465,9 @@
             right_index = end_index - 1;
             more = false;
           }
+          if (left_index <= right_most_fixed_index) {
+                left_index = right_most_fixed_index + 1;
+          }
           if (back_by > num_pref_cards) {
             // Fill in the remainder of this "power block", if it
             // is non-null.
@@ -471,12 +476,14 @@
                                      N_words + i - 1, true /* reducing */);
             } else {
               more = false; // we are done
+              assert((end_index - 1) == right_index, "Must be at the end.");
             }
             i++;
             break;
           }
           i++;
         }
+        // Fix the rest of the power blocks.
         while (more && (i < N_powers)) {
           size_t back_by = power_to_cards_back(i);
           size_t right_index = suff_index + back_by - 1;
--- a/hotspot/src/share/vm/gc/shared/genCollectedHeap.cpp	Sat Sep 26 09:22:24 2015 -0700
+++ b/hotspot/src/share/vm/gc/shared/genCollectedHeap.cpp	Wed Jul 05 20:51:27 2017 +0200
@@ -172,8 +172,6 @@
 void GenCollectedHeap::post_initialize() {
   CollectedHeap::post_initialize();
   ref_processing_init();
-  GenCollectorPolicy *policy = (GenCollectorPolicy *)collector_policy();
-  guarantee(policy->is_generation_policy(), "Illegal policy type");
   assert((_young_gen->kind() == Generation::DefNew) ||
          (_young_gen->kind() == Generation::ParNew),
     "Wrong youngest generation type");
@@ -183,10 +181,10 @@
          _old_gen->kind() == Generation::MarkSweepCompact,
     "Wrong generation kind");
 
-  policy->initialize_size_policy(def_new_gen->eden()->capacity(),
-                                 _old_gen->capacity(),
-                                 def_new_gen->from()->capacity());
-  policy->initialize_gc_policy_counters();
+  _gen_policy->initialize_size_policy(def_new_gen->eden()->capacity(),
+                                      _old_gen->capacity(),
+                                      def_new_gen->from()->capacity());
+  _gen_policy->initialize_gc_policy_counters();
 }
 
 void GenCollectedHeap::ref_processing_init() {
@@ -822,10 +820,11 @@
          "Unexpected generation kinds");
   // Skip two header words in the block content verification
   NOT_PRODUCT(_skip_header_HeapWords = CMSCollector::skip_header_HeapWords();)
-  CMSCollector* collector = new CMSCollector(
-    (ConcurrentMarkSweepGeneration*)_old_gen,
-    _rem_set->as_CardTableRS(),
-    (ConcurrentMarkSweepPolicy*) collector_policy());
+  assert(_gen_policy->is_concurrent_mark_sweep_policy(), "Unexpected policy type");
+  CMSCollector* collector =
+    new CMSCollector((ConcurrentMarkSweepGeneration*)_old_gen,
+                     _rem_set->as_CardTableRS(),
+                     _gen_policy->as_concurrent_mark_sweep_policy());
 
   if (collector == NULL || !collector->completed_initialization()) {
     if (collector) {
--- a/hotspot/src/share/vm/gc/shared/genCollectedHeap.hpp	Sat Sep 26 09:22:24 2015 -0700
+++ b/hotspot/src/share/vm/gc/shared/genCollectedHeap.hpp	Wed Jul 05 20:51:27 2017 +0200
@@ -153,7 +153,7 @@
   // The generational collector policy.
   GenCollectorPolicy* gen_policy() const { return _gen_policy; }
 
-  virtual CollectorPolicy* collector_policy() const { return (CollectorPolicy*) gen_policy(); }
+  virtual CollectorPolicy* collector_policy() const { return gen_policy(); }
 
   // Adaptive size policy
   virtual AdaptiveSizePolicy* size_policy() {
--- a/hotspot/src/share/vm/opto/classes.hpp	Sat Sep 26 09:22:24 2015 -0700
+++ b/hotspot/src/share/vm/opto/classes.hpp	Wed Jul 05 20:51:27 2017 +0200
@@ -290,6 +290,7 @@
 macro(MulReductionVD)
 macro(DivVF)
 macro(DivVD)
+macro(SqrtVD)
 macro(LShiftCntV)
 macro(RShiftCntV)
 macro(LShiftVB)
--- a/hotspot/src/share/vm/opto/ifnode.cpp	Sat Sep 26 09:22:24 2015 -0700
+++ b/hotspot/src/share/vm/opto/ifnode.cpp	Wed Jul 05 20:51:27 2017 +0200
@@ -858,18 +858,29 @@
     // this_bool = <=
     //   dom_bool = >= (proj = True) or dom_bool = < (proj = False)
     //     x in [a, b] on the fail (= True) projection, b+1 > a-1:
-    //     lo = a, hi = b, adjusted_lim = b-a, cond = <=u
+    //     lo = a, hi = b, adjusted_lim = b-a+1, cond = <u
+    //     lo = a, hi = b, adjusted_lim = b-a, cond = <=u doesn't work because b = a - 1 is possible, then b-a = -1
     //   dom_bool = > (proj = True) or dom_bool = <= (proj = False)
     //     x in ]a, b] on the fail (= True) projection b+1 > a:
     //     lo = a+1, hi = b, adjusted_lim = b-a, cond = <u
-    //     lo = a+1, hi = b, adjusted_lim = b-a-1, cond = <=u doesn't work because a = b is possible, then hi-lo = -1
+    //     lo = a+1, hi = b, adjusted_lim = b-a-1, cond = <=u doesn't work because a = b is possible, then b-a-1 = -1
 
-    if (lo_test == BoolTest::gt || lo_test == BoolTest::le) {
-      if (hi_test == BoolTest::le) {
+    if (hi_test == BoolTest::lt) {
+      if (lo_test == BoolTest::gt || lo_test == BoolTest::le) {
+        lo = igvn->transform(new AddINode(lo, igvn->intcon(1)));
+      }
+    } else {
+      assert(hi_test == BoolTest::le, "bad test");
+      if (lo_test == BoolTest::ge || lo_test == BoolTest::lt) {
         adjusted_lim = igvn->transform(new SubINode(hi, lo));
+        adjusted_lim = igvn->transform(new AddINode(adjusted_lim, igvn->intcon(1)));
+        cond = BoolTest::lt;
+      } else {
+        assert(lo_test == BoolTest::gt || lo_test == BoolTest::le, "bad test");
+        adjusted_lim = igvn->transform(new SubINode(hi, lo));
+        lo = igvn->transform(new AddINode(lo, igvn->intcon(1)));
         cond = BoolTest::lt;
       }
-      lo = igvn->transform(new AddINode(lo, igvn->intcon(1)));
     }
   } else if (lo_type->_lo > hi_type->_hi && lo_type->_hi == max_jint && hi_type->_lo == min_jint) {
 
@@ -879,7 +890,8 @@
     //     lo = b, hi = a, adjusted_lim = a-b, cond = >=u
     //   dom_bool = <= (proj = True) or dom_bool = > (proj = False)
     //     x in [b, a] on the fail (= False) projection, a+1 > b-1:
-    //     lo = b, hi = a, adjusted_lim = a-b, cond = >u
+    //     lo = b, hi = a, adjusted_lim = a-b+1, cond = >=u
+    //     lo = b, hi = a, adjusted_lim = a-b, cond = >u doesn't work because a = b - 1 is possible, then b-a = -1
     // this_bool = <=
     //   dom_bool = < (proj = True) or dom_bool = >= (proj = False)
     //     x in ]b, a[ on the fail (= False) projection, a > b:
@@ -887,7 +899,7 @@
     //   dom_bool = <= (proj = True) or dom_bool = > (proj = False)
     //     x in ]b, a] on the fail (= False) projection, a+1 > b:
     //     lo = b+1, hi = a, adjusted_lim = a-b, cond = >=u
-    //     lo = b+1, hi = a, adjusted_lim = a-b-1, cond = >u doesn't work because a = b is possible, then hi-lo = -1
+    //     lo = b+1, hi = a, adjusted_lim = a-b-1, cond = >u doesn't work because a = b is possible, then b-a-1 = -1
 
     swap(lo, hi);
     swap(lo_type, hi_type);
@@ -900,14 +912,26 @@
 
     cond = (hi_test == BoolTest::le || hi_test == BoolTest::gt) ? BoolTest::gt : BoolTest::ge;
 
-    if (lo_test == BoolTest::le) {
-      if (cond == BoolTest::gt) {
+    if (lo_test == BoolTest::lt) {
+      if (hi_test == BoolTest::lt || hi_test == BoolTest::ge) {
+        cond = BoolTest::ge;
+      } else {
+        assert(hi_test == BoolTest::le || hi_test == BoolTest::gt, "bad test");
         adjusted_lim = igvn->transform(new SubINode(hi, lo));
+        adjusted_lim = igvn->transform(new AddINode(adjusted_lim, igvn->intcon(1)));
         cond = BoolTest::ge;
       }
-      lo = igvn->transform(new AddINode(lo, igvn->intcon(1)));
+    } else if (lo_test == BoolTest::le) {
+      if (hi_test == BoolTest::lt || hi_test == BoolTest::ge) {
+        lo = igvn->transform(new AddINode(lo, igvn->intcon(1)));
+        cond = BoolTest::ge;
+      } else {
+        assert(hi_test == BoolTest::le || hi_test == BoolTest::gt, "bad test");
+        adjusted_lim = igvn->transform(new SubINode(hi, lo));
+        lo = igvn->transform(new AddINode(lo, igvn->intcon(1)));
+        cond = BoolTest::ge;
+      }
     }
-
   } else {
     const TypeInt* failtype  = filtered_int_type(igvn, n, proj);
     if (failtype != NULL) {
--- a/hotspot/src/share/vm/opto/loopPredicate.cpp	Sat Sep 26 09:22:24 2015 -0700
+++ b/hotspot/src/share/vm/opto/loopPredicate.cpp	Wed Jul 05 20:51:27 2017 +0200
@@ -112,6 +112,13 @@
     if (_idom != NULL) {
       set_idom(call, rgn, dom_depth(rgn));
     }
+    for (DUIterator_Fast imax, i = uncommon_proj->fast_outs(imax); i < imax; i++) {
+      Node* n = uncommon_proj->fast_out(i);
+      if (n->is_Load() || n->is_Store()) {
+        _igvn.replace_input_of(n, 0, rgn);
+        --i; --imax;
+      }
+    }
   } else {
     // Find region's edge corresponding to uncommon_proj
     for (; proj_index < rgn->req(); proj_index++)
--- a/hotspot/src/share/vm/opto/loopnode.cpp	Sat Sep 26 09:22:24 2015 -0700
+++ b/hotspot/src/share/vm/opto/loopnode.cpp	Wed Jul 05 20:51:27 2017 +0200
@@ -1901,7 +1901,7 @@
     if (stride_con > 0) tty->print("+");
     tty->print("%d", stride_con);
 
-    tty->print(" (%d iters) ", (int)cl->profile_trip_cnt());
+    tty->print(" (%0.f iters) ", cl->profile_trip_cnt());
 
     if (cl->is_pre_loop ()) tty->print(" pre" );
     if (cl->is_main_loop()) tty->print(" main");
--- a/hotspot/src/share/vm/opto/superword.cpp	Sat Sep 26 09:22:24 2015 -0700
+++ b/hotspot/src/share/vm/opto/superword.cpp	Wed Jul 05 20:51:27 2017 +0200
@@ -1858,6 +1858,11 @@
           vn = VectorNode::make(opc, in1, in2, vlen, velt_basic_type(n));
           vlen_in_bytes = vn->as_Vector()->length_in_bytes();
         }
+      } else if (opc == Op_SqrtD) {
+        // Promote operand to vector (Sqrt is a 2 address instruction)
+        Node* in = vector_opd(p, 1);
+        vn = VectorNode::make(opc, in, NULL, vlen, velt_basic_type(n));
+        vlen_in_bytes = vn->as_Vector()->length_in_bytes();
       } else {
         ShouldNotReachHere();
       }
--- a/hotspot/src/share/vm/opto/vectornode.cpp	Sat Sep 26 09:22:24 2015 -0700
+++ b/hotspot/src/share/vm/opto/vectornode.cpp	Wed Jul 05 20:51:27 2017 +0200
@@ -92,6 +92,9 @@
   case Op_DivD:
     assert(bt == T_DOUBLE, "must be");
     return Op_DivVD;
+  case Op_SqrtD:
+    assert(bt == T_DOUBLE, "must be");
+    return Op_SqrtVD;
   case Op_LShiftI:
     switch (bt) {
     case T_BOOLEAN:
@@ -277,6 +280,9 @@
   case Op_DivVF: return new DivVFNode(n1, n2, vt);
   case Op_DivVD: return new DivVDNode(n1, n2, vt);
 
+  // Currently only supports double precision sqrt
+  case Op_SqrtVD: return new SqrtVDNode(n1, vt);
+
   case Op_LShiftVB: return new LShiftVBNode(n1, n2, vt);
   case Op_LShiftVS: return new LShiftVSNode(n1, n2, vt);
   case Op_LShiftVI: return new LShiftVINode(n1, n2, vt);
--- a/hotspot/src/share/vm/opto/vectornode.hpp	Sat Sep 26 09:22:24 2015 -0700
+++ b/hotspot/src/share/vm/opto/vectornode.hpp	Wed Jul 05 20:51:27 2017 +0200
@@ -309,6 +309,14 @@
   virtual int Opcode() const;
 };
 
+//------------------------------SqrtVDNode--------------------------------------
+// Vector Sqrt double
+class SqrtVDNode : public VectorNode {
+ public:
+  SqrtVDNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {}
+  virtual int Opcode() const;
+};
+
 //------------------------------LShiftVBNode-----------------------------------
 // Vector left shift bytes
 class LShiftVBNode : public VectorNode {
--- a/hotspot/src/share/vm/prims/whitebox.cpp	Sat Sep 26 09:22:24 2015 -0700
+++ b/hotspot/src/share/vm/prims/whitebox.cpp	Wed Jul 05 20:51:27 2017 +0200
@@ -1041,11 +1041,18 @@
 }
 
 WB_ENTRY(jlong, WB_AllocateCodeBlob(JNIEnv* env, jobject o, jint size, jint blob_type))
-    return (jlong) WhiteBox::allocate_code_blob(size, blob_type);
+  if (size < 0) {
+    THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),
+      err_msg("WB_AllocateCodeBlob: size is negative: " INT32_FORMAT, size));
+  }
+  return (jlong) WhiteBox::allocate_code_blob(size, blob_type);
 WB_END
 
 WB_ENTRY(void, WB_FreeCodeBlob(JNIEnv* env, jobject o, jlong addr))
-    BufferBlob::free((BufferBlob*) addr);
+  if (addr == 0) {
+    return;
+  }
+  BufferBlob::free((BufferBlob*) addr);
 WB_END
 
 WB_ENTRY(jobjectArray, WB_GetCodeHeapEntries(JNIEnv* env, jobject o, jint blob_type))
@@ -1090,9 +1097,13 @@
 WB_END
 
 WB_ENTRY(jobjectArray, WB_GetCodeBlob(JNIEnv* env, jobject o, jlong addr))
-    ThreadToNativeFromVM ttn(thread);
-    CodeBlobStub stub((CodeBlob*) addr);
-    return codeBlob2objectArray(thread, env, &stub);
+  if (addr == 0) {
+    THROW_MSG_NULL(vmSymbols::java_lang_NullPointerException(),
+      "WB_GetCodeBlob: addr is null");
+  }
+  ThreadToNativeFromVM ttn(thread);
+  CodeBlobStub stub((CodeBlob*) addr);
+  return codeBlob2objectArray(thread, env, &stub);
 WB_END
 
 WB_ENTRY(jlong, WB_GetThreadStackSize(JNIEnv* env, jobject o))
--- a/hotspot/src/share/vm/services/lowMemoryDetector.cpp	Sat Sep 26 09:22:24 2015 -0700
+++ b/hotspot/src/share/vm/services/lowMemoryDetector.cpp	Wed Jul 05 20:51:27 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -200,9 +200,10 @@
 // any clears unless the usage becomes greater than or equal
 // to the high threshold.
 //
-// If the current level is between high and low threhsold, no change.
+// If the current level is between high and low threshold, no change.
 //
 void SensorInfo::set_gauge_sensor_level(MemoryUsage usage, ThresholdSupport* high_low_threshold) {
+  assert(Service_lock->owned_by_self(), "Must own Service_lock");
   assert(high_low_threshold->is_high_threshold_supported(), "just checking");
 
   bool is_over_high = high_low_threshold->is_high_threshold_crossed(usage);
@@ -257,6 +258,7 @@
 //      the sensor will be on (i.e. sensor is currently off
 //      and has pending trigger requests).
 void SensorInfo::set_counter_sensor_level(MemoryUsage usage, ThresholdSupport* counter_threshold) {
+  assert(Service_lock->owned_by_self(), "Must own Service_lock");
   assert(counter_threshold->is_high_threshold_supported(), "just checking");
 
   bool is_over_high = counter_threshold->is_high_threshold_crossed(usage);
@@ -278,9 +280,7 @@
 }
 
 void SensorInfo::process_pending_requests(TRAPS) {
-  if (!has_pending_requests()) {
-    return;
-  }
+  assert(has_pending_requests(), "Must have pending request");
 
   int pending_count = pending_trigger_count();
   if (pending_clear_count() > 0) {
@@ -293,7 +293,6 @@
 
 void SensorInfo::trigger(int count, TRAPS) {
   assert(count <= _pending_trigger_count, "just checking");
-
   if (_sensor_obj != NULL) {
     Klass* k = Management::sun_management_Sensor_klass(CHECK);
     instanceKlassHandle sensorKlass (THREAD, k);
@@ -316,6 +315,7 @@
   {
     // Holds Service_lock and update the sensor state
     MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag);
+    assert(_pending_trigger_count > 0, "Must have pending trigger");
     _sensor_on = true;
     _sensor_count += count;
     _pending_trigger_count = _pending_trigger_count - count;
@@ -323,6 +323,20 @@
 }
 
 void SensorInfo::clear(int count, TRAPS) {
+  {
+    // Holds Service_lock and update the sensor state
+    MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag);
+    if (_pending_clear_count == 0) {
+      // Bail out if we lost a race to set_*_sensor_level() which may have
+      // reactivated the sensor in the meantime because it was triggered again.
+      return;
+    }
+    _sensor_on = false;
+    _sensor_count += count;
+    _pending_clear_count = 0;
+    _pending_trigger_count = _pending_trigger_count - count;
+  }
+
   if (_sensor_obj != NULL) {
     Klass* k = Management::sun_management_Sensor_klass(CHECK);
     instanceKlassHandle sensorKlass (THREAD, k);
@@ -338,14 +352,6 @@
                             &args,
                             CHECK);
   }
-
-  {
-    // Holds Service_lock and update the sensor state
-    MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag);
-    _sensor_on = false;
-    _pending_clear_count = 0;
-    _pending_trigger_count = _pending_trigger_count - count;
-  }
 }
 
 //--------------------------------------------------------------
--- a/hotspot/src/share/vm/services/lowMemoryDetector.hpp	Sat Sep 26 09:22:24 2015 -0700
+++ b/hotspot/src/share/vm/services/lowMemoryDetector.hpp	Wed Jul 05 20:51:27 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -180,7 +180,7 @@
   // any clears unless the usage becomes greater than or equal
   // to the high threshold.
   //
-  // If the current level is between high and low threhsold, no change.
+  // If the current level is between high and low threshold, no change.
   //
   void set_gauge_sensor_level(MemoryUsage usage, ThresholdSupport* high_low_threshold);
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/arraycopy/TestEliminatedArrayLoopPredicateCopyDeopt.java	Wed Jul 05 20:51:27 2017 +0200
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8134974
+ * @summary Cannot pin eliminated arraycopy loads for deopt state in uncommon trap path if it is a loop predicate unc
+ * @run main/othervm -XX:-BackgroundCompilation -XX:-UseOnStackReplacement TestEliminatedArrayLoopPredicateCopyDeopt
+ *
+ */
+
+public class TestEliminatedArrayLoopPredicateCopyDeopt {
+
+    static boolean test(int[] array_src) {
+        int[] array_dst = new int[10];
+        System.arraycopy(array_src, 0, array_dst, 0, 10);
+
+        for (int i = 0; i < 100; i++) {
+            array_src[i] = i;
+        }
+        if (array_dst[0] == 0) {
+            return true;
+        }
+        return false;
+    }
+
+    static public void main(String[] args) {
+        int[] array_src = new int[100];
+        for (int i = 0; i < 20000; i++) {
+            test(array_src);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/loopopts/superword/SumRedSqrt_Double.java	Wed Jul 05 20:51:27 2017 +0200
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/**
+* @test
+* @summary Add C2 x86 Superword support for scalar sum reduction optimizations : double sqrt test
+*
+* @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+SuperWordReductions -XX:LoopUnrollLimit=250 -XX:LoopMaxUnroll=2 -XX:CompileThresholdScaling=0.1 SumRedSqrt_Double
+* @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-SuperWordReductions -XX:LoopUnrollLimit=250 -XX:LoopMaxUnroll=2 -XX:CompileThresholdScaling=0.1 SumRedSqrt_Double
+*
+* @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+SuperWordReductions -XX:LoopUnrollLimit=250 -XX:LoopMaxUnroll=4 -XX:CompileThresholdScaling=0.1 SumRedSqrt_Double
+* @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-SuperWordReductions -XX:LoopUnrollLimit=250 -XX:LoopMaxUnroll=4 -XX:CompileThresholdScaling=0.1 SumRedSqrt_Double
+*
+* @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+SuperWordReductions -XX:LoopUnrollLimit=250 -XX:LoopMaxUnroll=8 -XX:CompileThresholdScaling=0.1 SumRedSqrt_Double
+* @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-SuperWordReductions -XX:LoopUnrollLimit=250 -XX:LoopMaxUnroll=8 -XX:CompileThresholdScaling=0.1 SumRedSqrt_Double
+*
+* @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+SuperWordReductions -XX:LoopUnrollLimit=250 -XX:LoopMaxUnroll=16 -XX:CompileThresholdScaling=0.1 SumRedSqrt_Double
+* @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-SuperWordReductions -XX:LoopUnrollLimit=250 -XX:LoopMaxUnroll=16 -XX:CompileThresholdScaling=0.1 SumRedSqrt_Double
+*/
+
+public class SumRedSqrt_Double
+{
+  public static void main(String[] args) throws Exception {
+    double[] a = new double[256*1024];
+    double[] b = new double[256*1024];
+    double[] c = new double[256*1024];
+    double[] d = new double[256*1024];
+    sumReductionInit(a,b,c);
+    double total = 0;
+    double valid = 2.06157643776E14;
+    for(int j = 0; j < 2000; j++) {
+      total = sumReductionImplement(a,b,c,d,total);
+    }
+    if(total == valid) {
+      System.out.println("Success");
+    } else {
+      System.out.println("Invalid sum of elements variable in total: " + total);
+      System.out.println("Expected value = " + valid);
+      throw new Exception("Failed");
+    }
+  }
+
+  public static void sumReductionInit(
+    double[] a,
+    double[] b,
+    double[] c)
+  {
+    for(int j = 0; j < 1; j++)
+    {
+      for(int i = 0; i < a.length; i++)
+      {
+        a[i] = i * 1 + j;
+        b[i] = i * 1 - j;
+        c[i] = i + j;
+      }
+    }
+  }
+
+  public static double sumReductionImplement(
+    double[] a,
+    double[] b,
+    double[] c,
+    double[] d,
+    double total)
+  {
+    for(int i = 0; i < a.length; i++)
+    {
+      d[i]= Math.sqrt(a[i] * b[i]) + Math.sqrt(a[i] * c[i]) + Math.sqrt(b[i] * c[i]);
+      total += d[i];
+    }
+    return total;
+  }
+
+}
--- a/hotspot/test/compiler/rangechecks/TestBadFoldCompare.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/hotspot/test/compiler/rangechecks/TestBadFoldCompare.java	Wed Jul 05 20:51:27 2017 +0200
@@ -24,7 +24,8 @@
 /*
  * @test
  * @bug 8085832
- * @summary x <= 0 || x > 0 wrongly folded as (x-1) >u -1
+ * @bug 8135069
+ * @summary x <= 0 || x > 0 wrongly folded as (x-1) >u -1 and x < 0 || x > -1 wrongly folded as x >u -1
  * @run main/othervm -XX:-BackgroundCompilation -XX:-UseOnStackReplacement TestBadFoldCompare
  */
 
@@ -58,6 +59,34 @@
         helper2(i, 0, 0, flag);
     }
 
+    static boolean test3_taken;
+
+    static void helper3(int i, int a, int b, boolean flag) {
+        if (flag) {
+            if (i < a || i > b - 1) {
+                test3_taken = true;
+            }
+        }
+    }
+
+    static void test3(int i, boolean flag) {
+        helper3(i, 0, 0, flag);
+    }
+
+    static boolean test4_taken;
+
+    static void helper4(int i, int a, int b, boolean flag) {
+        if (flag) {
+            if (i > b - 1 || i < a) {
+                test4_taken = true;
+            }
+        }
+    }
+
+    static void test4(int i, boolean flag) {
+        helper4(i, 0, 0, flag);
+    }
+
     static public void main(String[] args) {
         boolean success = true;
 
@@ -87,6 +116,35 @@
             System.out.println("Test2 failed");
             success = false;
         }
+
+        for (int i = 0; i < 20000; i++) {
+            helper3(5, 0,  10, (i%2)==0);
+            helper3(-1, 0,  10, (i%2)==0);
+            helper3(15, 0,  10, (i%2)==0);
+            test3(0, false);
+        }
+        test3_taken = false;
+        test3(0, true);
+
+        if (!test3_taken) {
+            System.out.println("Test3 failed");
+            success = false;
+        }
+
+        for (int i = 0; i < 20000; i++) {
+            helper4(5, 0,  10, (i%2)==0);
+            helper4(-1, 0,  10, (i%2)==0);
+            helper4(15, 0,  10, (i%2)==0);
+            test4(0, false);
+        }
+        test4_taken = false;
+        test4(0, true);
+
+        if (!test4_taken) {
+            System.out.println("Test4 failed");
+            success = false;
+        }
+
         if (!success) {
             throw new RuntimeException("Some tests failed");
         }
--- a/hotspot/test/gc/g1/humongousObjects/TestHumongousThreshold.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/hotspot/test/gc/g1/humongousObjects/TestHumongousThreshold.java	Wed Jul 05 20:51:27 2017 +0200
@@ -56,11 +56,11 @@
  * gc.g1.humongousObjects.TestHumongousThreshold
  *
  * @run main/othervm -XX:+UseG1GC -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:.
- * -XX:G1HeapRegionSize=16M
+ * -Xms128M -XX:G1HeapRegionSize=16M
  * gc.g1.humongousObjects.TestHumongousThreshold
  *
  * @run main/othervm -XX:+UseG1GC -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:.
- * -XX:G1HeapRegionSize=32M
+ * -Xms200M -XX:G1HeapRegionSize=32M
  * gc.g1.humongousObjects.TestHumongousThreshold
  *
  */
--- a/hotspot/test/serviceability/dcmd/compiler/CodelistTest.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/hotspot/test/serviceability/dcmd/compiler/CodelistTest.java	Wed Jul 05 20:51:27 2017 +0200
@@ -90,6 +90,9 @@
             if (methodPrintedInLogFormat.contains("MethodHandle")) {
                 continue;
             }
+            if (methodPrintedInLogFormat.contains("sun.misc.Unsafe.getUnsafe")) {
+                continue;
+            }
 
             MethodIdentifierParser mf = new MethodIdentifierParser(methodPrintedInLogFormat);
             Method m = null;
--- a/hotspot/test/testlibrary/jdk/test/lib/Utils.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/hotspot/test/testlibrary/jdk/test/lib/Utils.java	Wed Jul 05 20:51:27 2017 +0200
@@ -428,4 +428,28 @@
     public static long adjustTimeout(long tOut) {
         return Math.round(tOut * Utils.TIMEOUT_FACTOR);
     }
+
+    /**
+     * Runs runnable and checks that it throws expected exception. If exceptionException is null it means
+     * that we expect no exception to be thrown.
+     * @param runnable what we run
+     * @param expectedException expected exception
+     */
+    public static void runAndCheckException(Runnable runnable, Class<? extends Throwable> expectedException) {
+        try {
+            runnable.run();
+            if (expectedException != null) {
+                throw new AssertionError("Didn't get expected exception " + expectedException.getSimpleName());
+            }
+        } catch (Throwable t) {
+            if (expectedException == null) {
+                throw new AssertionError("Got unexpected exception ", t);
+            }
+            if (!expectedException.isAssignableFrom(t.getClass())) {
+                throw new AssertionError(String.format("Got unexpected exception %s instead of %s",
+                        t.getClass().getSimpleName(), expectedException.getSimpleName()), t);
+            }
+        }
+    }
+
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary_tests/whitebox/BlobSanityTest.java	Wed Jul 05 20:51:27 2017 +0200
@@ -0,0 +1,60 @@
+/*
+ * 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 BlobSanityTest
+ * @bug 8132980
+ * @library /testlibrary /../../test/lib
+ * @modules java.management/sun.management
+ * @build BlobSanityTest
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ *                              sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI BlobSanityTest
+ * @summary sanity testing of allocateCodeBlob, freeCodeBlob and getCodeBlob
+ */
+
+
+import sun.hotspot.WhiteBox;
+
+import java.util.function.Consumer;
+import jdk.test.lib.Utils;
+
+public class BlobSanityTest {
+
+    private static void runTest(Consumer<Integer> consumer, int val, String testCaseName, Class<? extends Throwable>
+            expectedException) {
+            System.out.println("Calling " + testCaseName);
+            Utils.runAndCheckException(() -> consumer.accept(val), expectedException);
+            System.out.println("Looks ok");
+    }
+
+    public static void main(String[] args) throws Exception {
+        System.out.println("Crash means that sanity check failed");
+
+        WhiteBox wb = WhiteBox.getWhiteBox();
+
+        runTest(wb::freeCodeBlob, 0, "wb::freeCodeBlob(0)", null);
+        runTest(wb::getCodeBlob, 0, "wb::getCodeBlob(0)", NullPointerException.class);
+        runTest(x -> wb.allocateCodeBlob(x, 0), -1, "wb::allocateCodeBlob(-1,0)", IllegalArgumentException.class);
+    }
+}
--- a/jaxp/.hgtags	Sat Sep 26 09:22:24 2015 -0700
+++ b/jaxp/.hgtags	Wed Jul 05 20:51:27 2017 +0200
@@ -325,3 +325,4 @@
 f464f9b2fb1178f6a957e5730b4b5252c6149ed9 jdk9-b80
 6a418934997fc4b56664b88f8417e2f0fe658091 jdk9-b81
 53fe3c103b6fdf48e2b2676c0c4818ef5a10fa21 jdk9-b82
+497bc2654e11684b11de46744227883d7e760f35 jdk9-b83
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/ElementImpl.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/ElementImpl.java	Wed Jul 05 20:51:27 2017 +0200
@@ -3,11 +3,12 @@
  * DO NOT REMOVE OR ALTER!
  */
 /*
- * Copyright 1999-2002,2004 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
  *
  *      http://www.apache.org/licenses/LICENSE-2.0
  *
@@ -17,70 +18,75 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package com.sun.org.apache.xerces.internal.dom;
 
 import org.w3c.dom.Attr;
 import org.w3c.dom.DOMException;
 import org.w3c.dom.Element;
+import org.w3c.dom.ElementTraversal;
 import org.w3c.dom.NamedNodeMap;
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
 import org.w3c.dom.Text;
-
 import org.w3c.dom.TypeInfo;
 import com.sun.org.apache.xerces.internal.util.URI;
 
 /**
- * Elements represent most of the "markup" and structure of the
- * document.  They contain both the data for the element itself
- * (element name and attributes), and any contained nodes, including
- * document text (as children).
+ * Elements represent most of the "markup" and structure of the document. They
+ * contain both the data for the element itself (element name and attributes),
+ * and any contained nodes, including document text (as children).
  * <P>
  * Elements may have Attributes associated with them; the API for this is
  * defined in Node, but the function is implemented here. In general, XML
  * applications should retrive Attributes as Nodes, since they may contain
- * entity references and hence be a fairly complex sub-tree. HTML users will
- * be dealing with simple string values, and convenience methods are provided
- * to work in terms of Strings.
+ * entity references and hence be a fairly complex sub-tree. HTML users will be
+ * dealing with simple string values, and convenience methods are provided to
+ * work in terms of Strings.
  * <P>
  * ElementImpl does not support Namespaces. ElementNSImpl, which inherits from
  * it, does.
+ *
  * @see ElementNSImpl
  *
  * @xerces.internal
  *
- * @author Arnaud  Le Hors, IBM
+ * @author Arnaud Le Hors, IBM
  * @author Joe Kesselman, IBM
  * @author Andy Clark, IBM
  * @author Ralf Pfeiffer, IBM
- * @since  PR-DOM-Level-1-19980818.
+ * @since PR-DOM-Level-1-19980818.
  */
 public class ElementImpl
-    extends ParentNode
-    implements Element, TypeInfo {
+        extends ParentNode
+        implements Element, ElementTraversal, TypeInfo {
 
     //
     // Constants
     //
-
-    /** Serialization version. */
+    /**
+     * Serialization version.
+     */
     static final long serialVersionUID = 3717253516652722278L;
     //
     // Data
     //
 
-    /** Element name. */
+    /**
+     * Element name.
+     */
     protected String name;
 
-    /** Attributes. */
+    /**
+     * Attributes.
+     */
     protected AttributeMap attributes;
 
     //
     // Constructors
     //
-
-    /** Factory constructor. */
+    /**
+     * Factory constructor.
+     */
     public ElementImpl(CoreDocumentImpl ownerDoc, String name) {
         super(ownerDoc);
         this.name = name;
@@ -88,7 +94,8 @@
     }
 
     // for ElementNSImpl
-    protected ElementImpl() {}
+    protected ElementImpl() {
+    }
 
     // Support for DOM Level 3 renameNode method.
     // Note: This only deals with part of the pb. CoreDocumentImpl
@@ -97,26 +104,45 @@
         if (needsSyncData()) {
             synchronizeData();
         }
-            this.name = name;
+        if (ownerDocument.errorChecking) {
+            int colon1 = name.indexOf(':');
+            if (colon1 != -1) {
+                String msg
+                        = DOMMessageFormatter.formatMessage(
+                                DOMMessageFormatter.DOM_DOMAIN,
+                                "NAMESPACE_ERR",
+                                null);
+                throw new DOMException(DOMException.NAMESPACE_ERR, msg);
+            }
+            if (!CoreDocumentImpl.isXMLName(name, ownerDocument.isXML11Version())) {
+                String msg = DOMMessageFormatter.formatMessage(
+                        DOMMessageFormatter.DOM_DOMAIN,
+                        "INVALID_CHARACTER_ERR", null);
+                throw new DOMException(DOMException.INVALID_CHARACTER_ERR,
+                        msg);
+            }
+        }
+        this.name = name;
         reconcileDefaultAttributes();
     }
 
     //
     // Node methods
     //
-
-
     /**
-     * A short integer indicating what type of node this is. The named
-     * constants for this value are defined in the org.w3c.dom.Node interface.
+     * A short integer indicating what type of node this is. The named constants
+     * for this value are defined in the org.w3c.dom.Node interface.
      */
     public short getNodeType() {
         return Node.ELEMENT_NODE;
     }
 
     /**
-     * Returns the element name
+     * Returns the node name
+     *
+     * @return the node name
      */
+    @Override
     public String getNodeName() {
         if (needsSyncData()) {
             synchronizeData();
@@ -129,7 +155,10 @@
      * from Node rather than specified on Element; in fact only Elements will
      * ever have Attributes, but they want to allow folks to "blindly" operate
      * on the tree as a set of Nodes.
+     *
+     * @return all Attributes
      */
+    @Override
     public NamedNodeMap getAttributes() {
 
         if (needsSyncData()) {
@@ -143,12 +172,13 @@
     } // getAttributes():NamedNodeMap
 
     /**
-     * Return a duplicate copy of this Element. Note that its children
-     * will not be copied unless the "deep" flag is true, but Attributes
-     * are <i>always</i> replicated.
+     * Return a duplicate copy of this Element. Note that its children will not
+     * be copied unless the "deep" flag is true, but Attributes are
+     * {@code always} replicated.
      *
      * @see org.w3c.dom.Node#cloneNode(boolean)
      */
+    @Override
     public Node cloneNode(boolean deep) {
 
         ElementImpl newnode = (ElementImpl) super.cloneNode(deep);
@@ -160,10 +190,12 @@
 
     } // cloneNode(boolean):Node
 
-   /**
-     * DOM Level 3 WD - Experimental.
-     * Retrieve baseURI
+    /**
+     * DOM Level 3 WD - Experimental. Retrieve baseURI
+     *
+     * @return the baseURI
      */
+    @Override
     public String getBaseURI() {
 
         if (needsSyncData()) {
@@ -174,62 +206,61 @@
         // 1. The base URI specified by an xml:base attribute on the element,
         // if one exists
         if (attributes != null) {
-            Attr attrNode = (Attr)attributes.getNamedItem("xml:base");
+            final Attr attrNode = getXMLBaseAttribute();
             if (attrNode != null) {
-                String uri =  attrNode.getNodeValue();
-                if (uri.length() != 0 ) {// attribute value is always empty string
+                final String uri = attrNode.getNodeValue();
+                if (uri.length() != 0) {// attribute value is always empty string
                     try {
-                       uri = new URI(uri).toString();
-                    }
-                    catch (com.sun.org.apache.xerces.internal.util.URI.MalformedURIException e) {
-                        // This may be a relative URI.
+                        URI _uri = new URI(uri, true);
+                        // If the URI is already absolute return it; otherwise it's relative and we need to resolve it.
+                        if (_uri.isAbsoluteURI()) {
+                            return _uri.toString();
+                        }
 
                         // Make any parentURI into a URI object to use with the URI(URI, String) constructor
                         String parentBaseURI = (this.ownerNode != null) ? this.ownerNode.getBaseURI() : null;
-                        if (parentBaseURI != null){
-                            try{
-                                uri = new URI(new URI(parentBaseURI), uri).toString();
-                            }
-                            catch (com.sun.org.apache.xerces.internal.util.URI.MalformedURIException ex){
+                        if (parentBaseURI != null) {
+                            try {
+                                URI _parentBaseURI = new URI(parentBaseURI);
+                                _uri.absolutize(_parentBaseURI);
+                                return _uri.toString();
+                            } catch (com.sun.org.apache.xerces.internal.util.URI.MalformedURIException ex) {
                                 // This should never happen: parent should have checked the URI and returned null if invalid.
                                 return null;
                             }
-                            return uri;
                         }
+                        // REVISIT: what should happen in this case?
+                        return null;
+                    } catch (com.sun.org.apache.xerces.internal.util.URI.MalformedURIException ex) {
                         return null;
                     }
-                    return uri;
                 }
             }
         }
 
         // 2.the base URI of the element's parent element within the
         // document or external entity, if one exists
-                // 3. the base URI of the document entity or external entity
-                // containing the element
-
-                // ownerNode serves as a parent or as document
-                String baseURI = (this.ownerNode != null) ? this.ownerNode.getBaseURI() : null ;
-        //base URI of parent element is not null
-        if(baseURI != null){
-            try {
-                //return valid absolute base URI
-               return new URI(baseURI).toString();
-            }
-            catch (com.sun.org.apache.xerces.internal.util.URI.MalformedURIException e){
-                return null;
-            }
-        }
-        return null;
+        // 3. the base URI of the document entity or external entity
+        // containing the element
+        // ownerNode serves as a parent or as document
+        return (this.ownerNode != null) ? this.ownerNode.getBaseURI() : null;
     } //getBaseURI
 
-
+    /**
+     * NON-DOM Returns the xml:base attribute.
+     *
+     * @return the xml:base attribute
+     */
+    protected Attr getXMLBaseAttribute() {
+        return (Attr) attributes.getNamedItem("xml:base");
+    } // getXMLBaseAttribute():Attr
 
     /**
-     * NON-DOM
-     * set the ownerDocument of this node, its children, and its attributes
+     * NON-DOM set the ownerDocument of this node, its children, and its
+     * attributes
      */
-    void setOwnerDocument(CoreDocumentImpl doc) {
+    @Override
+    protected void setOwnerDocument(CoreDocumentImpl doc) {
         super.setOwnerDocument(doc);
         if (attributes != null) {
             attributes.setOwnerDocument(doc);
@@ -239,15 +270,14 @@
     //
     // Element methods
     //
-
     /**
-     * Look up a single Attribute by name. Returns the Attribute's
-     * string value, or an empty string (NOT null!) to indicate that the
-     * name did not map to a currently defined attribute.
+     * Look up a single Attribute by name. Returns the Attribute's string value,
+     * or an empty string (NOT null!) to indicate that the name did not map to a
+     * currently defined attribute.
      * <p>
-     * Note: Attributes may contain complex node trees. This method
-     * returns the "flattened" string obtained from Attribute.getValue().
-     * If you need the structure information, see getAttributeNode().
+     * Note: Attributes may contain complex node trees. This method returns the
+     * "flattened" string obtained from Attribute.getValue(). If you need the
+     * structure information, see getAttributeNode().
      */
     public String getAttribute(String name) {
 
@@ -257,16 +287,15 @@
         if (attributes == null) {
             return "";
         }
-        Attr attr = (Attr)(attributes.getNamedItem(name));
+        Attr attr = (Attr) (attributes.getNamedItem(name));
         return (attr == null) ? "" : attr.getValue();
 
     } // getAttribute(String):String
 
-
     /**
-     * Look up a single Attribute by name. Returns the Attribute Node,
-     * so its complete child tree is available. This could be important in
-     * XML, where the string rendering may not be sufficient information.
+     * Look up a single Attribute by name. Returns the Attribute Node, so its
+     * complete child tree is available. This could be important in XML, where
+     * the string rendering may not be sufficient information.
      * <p>
      * If no matching attribute is available, returns null.
      */
@@ -278,36 +307,32 @@
         if (attributes == null) {
             return null;
         }
-        return (Attr)attributes.getNamedItem(name);
+        return (Attr) attributes.getNamedItem(name);
 
     } // getAttributeNode(String):Attr
 
-
     /**
-     * Returns a NodeList of all descendent nodes (children,
-     * grandchildren, and so on) which are Elements and which have the
-     * specified tag name.
+     * Returns a NodeList of all descendent nodes (children, grandchildren, and
+     * so on) which are Elements and which have the specified tag name.
      * <p>
-     * Note: NodeList is a "live" view of the DOM. Its contents will
-     * change as the DOM changes, and alterations made to the NodeList
-     * will be reflected in the DOM.
+     * Note: NodeList is a "live" view of the DOM. Its contents will change as
+     * the DOM changes, and alterations made to the NodeList will be reflected
+     * in the DOM.
      *
-     * @param tagname The type of element to gather. To obtain a list of
-     * all elements no matter what their names, use the wild-card tag
-     * name "*".
+     * @param tagname The type of element to gather. To obtain a list of all
+     * elements no matter what their names, use the wild-card tag name "*".
      *
      * @see DeepNodeListImpl
      */
     public NodeList getElementsByTagName(String tagname) {
-        return new DeepNodeListImpl(this,tagname);
+        return new DeepNodeListImpl(this, tagname);
     }
 
     /**
-     * Returns the name of the Element. Note that Element.nodeName() is
-     * defined to also return the tag name.
+     * Returns the name of the Element. Note that Element.nodeName() is defined
+     * to also return the tag name.
      * <p>
-     * This is case-preserving in XML. HTML should uppercasify it on the
-     * way in.
+     * This is case-preserving in XML. HTML should uppercasify it on the way in.
      */
     public String getTagName() {
         if (needsSyncData()) {
@@ -326,9 +351,9 @@
      * <p>
      * To normalize a Document, normalize its top-level Element child.
      * <p>
-     * As of PR-DOM-Level-1-19980818, CDATA -- despite being a subclass of
-     * Text -- is considered "markup" and will _not_ be merged either with
-     * normal Text or with other CDATASections.
+     * As of PR-DOM-Level-1-19980818, CDATA -- despite being a subclass of Text
+     * -- is considered "markup" and will _not_ be merged either with normal
+     * Text or with other CDATASections.
      */
     public void normalize() {
         // No need to normalize if already normalized.
@@ -347,35 +372,27 @@
             //   1) There is an adjacent text node
             //   2) There is no adjacent text node, but kid is
             //      an empty text node.
-            if ( kid.getNodeType() == Node.TEXT_NODE )
-            {
+            if (kid.getNodeType() == Node.TEXT_NODE) {
                 // If an adjacent text node, merge it with kid
-                if ( next!=null && next.getNodeType() == Node.TEXT_NODE )
-                {
-                    ((Text)kid).appendData(next.getNodeValue());
-                    removeChild( next );
+                if (next != null && next.getNodeType() == Node.TEXT_NODE) {
+                    ((Text) kid).appendData(next.getNodeValue());
+                    removeChild(next);
                     next = kid; // Don't advance; there might be another.
-                }
-                else
-                {
+                } else {
                     // If kid is empty, remove it
-                    if ( kid.getNodeValue() == null || kid.getNodeValue().length() == 0 ) {
-                        removeChild( kid );
+                    if (kid.getNodeValue() == null || kid.getNodeValue().length() == 0) {
+                        removeChild(kid);
                     }
                 }
-            }
-
-            // Otherwise it might be an Element, which is handled recursively
+            } // Otherwise it might be an Element, which is handled recursively
             else if (kid.getNodeType() == Node.ELEMENT_NODE) {
                 kid.normalize();
             }
         }
 
         // We must also normalize all of the attributes
-        if ( attributes!=null )
-        {
-            for( int i=0; i<attributes.getLength(); ++i )
-            {
+        if (attributes != null) {
+            for (int i = 0; i < attributes.getLength(); ++i) {
                 Node attr = attributes.item(i);
                 attr.normalize();
             }
@@ -383,21 +400,20 @@
 
         // changed() will have occurred when the removeChild() was done,
         // so does not have to be reissued.
-
         isNormalized(true);
     } // normalize()
 
     /**
-     * Remove the named attribute from this Element. If the removed
-     * Attribute has a default value, it is immediately replaced thereby.
+     * Remove the named attribute from this Element. If the removed Attribute
+     * has a default value, it is immediately replaced thereby.
      * <P>
      * The default logic is actually implemented in NamedNodeMapImpl.
-     * PR-DOM-Level-1-19980818 doesn't fully address the DTD, so some
-     * of this behavior is likely to change in future versions. ?????
+     * PR-DOM-Level-1-19980818 doesn't fully address the DTD, so some of this
+     * behavior is likely to change in future versions. ?????
      * <P>
-     * Note that this call "succeeds" even if no attribute by this name
-     * existed -- unlike removeAttributeNode, which will throw a not-found
-     * exception in that case.
+     * Note that this call "succeeds" even if no attribute by this name existed
+     * -- unlike removeAttributeNode, which will throw a not-found exception in
+     * that case.
      *
      * @throws DOMException(NO_MODIFICATION_ALLOWED_ERR) if the node is
      * readonly.
@@ -421,16 +437,14 @@
 
     } // removeAttribute(String)
 
-
     /**
-     * Remove the specified attribute/value pair. If the removed
-     * Attribute has a default value, it is immediately replaced.
+     * Remove the specified attribute/value pair. If the removed Attribute has a
+     * default value, it is immediately replaced.
      * <p>
-     * NOTE: Specifically removes THIS NODE -- not the node with this
-     * name, nor the node with these contents. If the specific Attribute
-     * object passed in is not stored in this Element, we throw a
-     * DOMException.  If you really want to remove an attribute by name,
-     * use removeAttribute().
+     * NOTE: Specifically removes THIS NODE -- not the node with this name, nor
+     * the node with these contents. If the specific Attribute object passed in
+     * is not stored in this Element, we throw a DOMException. If you really
+     * want to remove an attribute by name, use removeAttribute().
      *
      * @return the Attribute object that was removed.
      * @throws DOMException(NOT_FOUND_ERR) if oldattr is not an attribute of
@@ -439,7 +453,7 @@
      * readonly.
      */
     public Attr removeAttributeNode(Attr oldAttr)
-        throws DOMException {
+            throws DOMException {
 
         if (ownerDocument.errorChecking && isReadOnly()) {
             String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NO_MODIFICATION_ALLOWED_ERR", null);
@@ -458,19 +472,18 @@
 
     } // removeAttributeNode(Attr):Attr
 
-
     /**
-     * Add a new name/value pair, or replace the value of the existing
-     * attribute having that name.
+     * Add a new name/value pair, or replace the value of the existing attribute
+     * having that name.
      *
-     * Note: this method supports only the simplest kind of Attribute,
-     * one whose value is a string contained in a single Text node.
-     * If you want to assert a more complex value (which XML permits,
-     * though HTML doesn't), see setAttributeNode().
+     * Note: this method supports only the simplest kind of Attribute, one whose
+     * value is a string contained in a single Text node. If you want to assert
+     * a more complex value (which XML permits, though HTML doesn't), see
+     * setAttributeNode().
      *
-     * The attribute is created with specified=true, meaning it's an
-     * explicit value rather than inherited from the DTD as a default.
-     * Again, setAttributeNode can be used to achieve other results.
+     * The attribute is created with specified=true, meaning it's an explicit
+     * value rather than inherited from the DTD as a default. Again,
+     * setAttributeNode can be used to achieve other results.
      *
      * @throws DOMException(INVALID_NAME_ERR) if the name is not acceptable.
      * (Attribute factory will do that test for us.)
@@ -478,54 +491,52 @@
      * @throws DOMException(NO_MODIFICATION_ALLOWED_ERR) if the node is
      * readonly.
      */
-        public void setAttribute(String name, String value) {
+    public void setAttribute(String name, String value) {
 
-                if (ownerDocument.errorChecking && isReadOnly()) {
-                        String msg =
-                                DOMMessageFormatter.formatMessage(
-                                        DOMMessageFormatter.DOM_DOMAIN,
-                                        "NO_MODIFICATION_ALLOWED_ERR",
-                                        null);
-                        throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, msg);
-                }
+        if (ownerDocument.errorChecking && isReadOnly()) {
+            String msg
+                    = DOMMessageFormatter.formatMessage(
+                            DOMMessageFormatter.DOM_DOMAIN,
+                            "NO_MODIFICATION_ALLOWED_ERR",
+                            null);
+            throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, msg);
+        }
 
-                if (needsSyncData()) {
-                        synchronizeData();
-                }
+        if (needsSyncData()) {
+            synchronizeData();
+        }
 
-                Attr newAttr = getAttributeNode(name);
-                if (newAttr == null) {
-                        newAttr = getOwnerDocument().createAttribute(name);
+        Attr newAttr = getAttributeNode(name);
+        if (newAttr == null) {
+            newAttr = getOwnerDocument().createAttribute(name);
 
-                        if (attributes == null) {
-                                attributes = new AttributeMap(this, null);
-                        }
+            if (attributes == null) {
+                attributes = new AttributeMap(this, null);
+            }
 
-                        newAttr.setNodeValue(value);
-                        attributes.setNamedItem(newAttr);
-                }
-                else {
-                        newAttr.setNodeValue(value);
-                }
+            newAttr.setNodeValue(value);
+            attributes.setNamedItem(newAttr);
+        } else {
+            newAttr.setNodeValue(value);
+        }
 
-        } // setAttribute(String,String)
+    } // setAttribute(String,String)
 
     /**
-     * Add a new attribute/value pair, or replace the value of the
-     * existing attribute with that name.
+     * Add a new attribute/value pair, or replace the value of the existing
+     * attribute with that name.
      * <P>
      * This method allows you to add an Attribute that has already been
      * constructed, and hence avoids the limitations of the simple
-     * setAttribute() call. It can handle attribute values that have
-     * arbitrarily complex tree structure -- in particular, those which
-     * had entity references mixed into their text.
+     * setAttribute() call. It can handle attribute values that have arbitrarily
+     * complex tree structure -- in particular, those which had entity
+     * references mixed into their text.
      *
-     * @throws DOMException(INUSE_ATTRIBUTE_ERR) if the Attribute object
-     * has already been assigned to another Element.
+     * @throws DOMException(INUSE_ATTRIBUTE_ERR) if the Attribute object has
+     * already been assigned to another Element.
      */
     public Attr setAttributeNode(Attr newAttr)
-        throws DOMException
-        {
+            throws DOMException {
 
         if (needsSyncData()) {
             synchronizeData();
@@ -535,13 +546,13 @@
             if (isReadOnly()) {
                 String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NO_MODIFICATION_ALLOWED_ERR", null);
                 throw new DOMException(
-                                     DOMException.NO_MODIFICATION_ALLOWED_ERR,
-                                     msg);
+                        DOMException.NO_MODIFICATION_ALLOWED_ERR,
+                        msg);
             }
 
             if (newAttr.getOwnerDocument() != ownerDocument) {
                 String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "WRONG_DOCUMENT_ERR", null);
-                    throw new DOMException(DOMException.WRONG_DOCUMENT_ERR, msg);
+                throw new DOMException(DOMException.WRONG_DOCUMENT_ERR, msg);
             }
         }
 
@@ -556,19 +567,16 @@
     //
     // DOM2: Namespace methods
     //
-
     /**
-     * Introduced in DOM Level 2. <p>
+     * Introduced in DOM Level 2.
+     * <p>
      *
      * Retrieves an attribute value by local name and namespace URI.
      *
-     * @param namespaceURI
-     *                      The namespace URI of the attribute to
-     *                      retrieve.
-     * @param localName     The local name of the attribute to retrieve.
-     * @return String       The Attr value as a string, or empty string
-     *                      if that attribute
-     *                      does not have a specified or default value.
+     * @param namespaceURI The namespace URI of the attribute to retrieve.
+     * @param localName The local name of the attribute to retrieve.
+     * @return String The Attr value as a string, or empty string if that
+     * attribute does not have a specified or default value.
      * @since WD-DOM-Level-2-19990923
      */
     public String getAttributeNS(String namespaceURI, String localName) {
@@ -581,89 +589,85 @@
             return "";
         }
 
-        Attr attr = (Attr)(attributes.getNamedItemNS(namespaceURI, localName));
+        Attr attr = (Attr) (attributes.getNamedItemNS(namespaceURI, localName));
         return (attr == null) ? "" : attr.getValue();
 
     } // getAttributeNS(String,String):String
 
     /**
-     * Introduced in DOM Level 2. <p>
-     *
-     *  Adds a new attribute.
-     *  If the given namespaceURI is null or an empty string and the
-     *  qualifiedName has a prefix that is "xml", the new attribute is bound to
-     *  the predefined namespace "http://www.w3.org/XML/1998/namespace"
-     *  [Namespaces].  If an attribute with the same local name and namespace
-     *  URI is already present on the element, its prefix is changed to be the
-     *  prefix part of the qualifiedName, and its value is changed to be the
-     *  value parameter. This value is a simple string, it is not parsed as it
-     *  is being set. So any markup (such as syntax to be recognized as an
-     *  entity reference) is treated as literal text, and needs to be
-     *  appropriately escaped by the implementation when it is written out. In
-     *  order to assign an attribute value that contains entity references, the
-     *  user must create an Attr node plus any Text and EntityReference nodes,
-     *  build the appropriate subtree, and use setAttributeNodeNS or
-     *  setAttributeNode to assign it as the value of an attribute.
+     * Introduced in DOM Level 2.
+     * <p>
      *
-     * @param namespaceURI      The namespace URI of the attribute to create
-     *                          or alter.
-     * @param qualifiedName     The qualified name of the attribute to create or
-     *                          alter.
-     * @param value             The value to set in string form.
-     * @throws                  INVALID_CHARACTER_ERR: Raised if the specified
-     *                          name contains an invalid character.
+     * Adds a new attribute. If the given namespaceURI is null or an empty
+     * string and the qualifiedName has a prefix that is "xml", the new
+     * attribute is bound to the predefined namespace
+     * "http://www.w3.org/XML/1998/namespace" [Namespaces]. If an attribute with
+     * the same local name and namespace URI is already present on the element,
+     * its prefix is changed to be the prefix part of the qualifiedName, and its
+     * value is changed to be the value parameter. This value is a simple
+     * string, it is not parsed as it is being set. So any markup (such as
+     * syntax to be recognized as an entity reference) is treated as literal
+     * text, and needs to be appropriately escaped by the implementation when it
+     * is written out. In order to assign an attribute value that contains
+     * entity references, the user must create an Attr node plus any Text and
+     * EntityReference nodes, build the appropriate subtree, and use
+     * setAttributeNodeNS or setAttributeNode to assign it as the value of an
+     * attribute.
      *
-     * @throws                  NO_MODIFICATION_ALLOWED_ERR: Raised if this
-     *                          node is readonly.
+     * @param namespaceURI The namespace URI of the attribute to create or
+     * alter.
+     * @param qualifiedName The qualified name of the attribute to create or
+     * alter.
+     * @param value The value to set in string form.
+     * @throws INVALID_CHARACTER_ERR: Raised if the specified name contains an
+     * invalid character.
      *
-     * @throws                  NAMESPACE_ERR: Raised if the qualifiedName
-     *                          has a prefix that is "xml" and the namespaceURI
-     *                          is neither null nor an empty string nor
-     *                          "http://www.w3.org/XML/1998/namespace", or if
-     *                          the qualifiedName has a prefix that is "xmlns"
-     *                          but the namespaceURI is neither null nor an
-     *                          empty string, or if if the qualifiedName has a
-     *                          prefix different from "xml" and "xmlns" and the
-     *                          namespaceURI is null or an empty string.
+     * @throws NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
+     *
+     * @throws NAMESPACE_ERR: Raised if the qualifiedName has a prefix that is
+     * "xml" and the namespaceURI is neither null nor an empty string nor
+     * "http://www.w3.org/XML/1998/namespace", or if the qualifiedName has a
+     * prefix that is "xmlns" but the namespaceURI is neither null nor an empty
+     * string, or if if the qualifiedName has a prefix different from "xml" and
+     * "xmlns" and the namespaceURI is null or an empty string.
      * @since WD-DOM-Level-2-19990923
      */
-     public void setAttributeNS(String namespaceURI,String qualifiedName,
-                                          String value) {
-                if (ownerDocument.errorChecking && isReadOnly()) {
-                        String msg =
-                                DOMMessageFormatter.formatMessage(
-                                        DOMMessageFormatter.DOM_DOMAIN,
-                                        "NO_MODIFICATION_ALLOWED_ERR",
-                                        null);
-                        throw new DOMException(
-                                DOMException.NO_MODIFICATION_ALLOWED_ERR,
-                                msg);
-                }
-                if (needsSyncData()) {
-                        synchronizeData();
-                }
-                int index = qualifiedName.indexOf(':');
-                String prefix, localName;
-                if (index < 0) {
-                        prefix = null;
-                        localName = qualifiedName;
-                }
-                else {
-                        prefix = qualifiedName.substring(0, index);
-                        localName = qualifiedName.substring(index + 1);
-                }
-                Attr newAttr = getAttributeNodeNS(namespaceURI, localName);
-                if (newAttr == null) {
+    public void setAttributeNS(String namespaceURI, String qualifiedName,
+            String value) {
+        if (ownerDocument.errorChecking && isReadOnly()) {
+            String msg
+                    = DOMMessageFormatter.formatMessage(
+                            DOMMessageFormatter.DOM_DOMAIN,
+                            "NO_MODIFICATION_ALLOWED_ERR",
+                            null);
+            throw new DOMException(
+                    DOMException.NO_MODIFICATION_ALLOWED_ERR,
+                    msg);
+        }
+        if (needsSyncData()) {
+            synchronizeData();
+        }
+        int index = qualifiedName.indexOf(':');
+        String prefix, localName;
+        if (index < 0) {
+            prefix = null;
+            localName = qualifiedName;
+        } else {
+            prefix = qualifiedName.substring(0, index);
+            localName = qualifiedName.substring(index + 1);
+        }
+        Attr newAttr = getAttributeNodeNS(namespaceURI, localName);
+        if (newAttr == null) {
             // REVISIT: this is not efficient, we are creating twice the same
             //          strings for prefix and localName.
-                        newAttr = getOwnerDocument().createAttributeNS(
-                                        namespaceURI,
-                                        qualifiedName);
-                        if (attributes == null) {
-                                attributes = new AttributeMap(this, null);
-                        }
-                        newAttr.setNodeValue(value);
-                        attributes.setNamedItemNS(newAttr);
+            newAttr = getOwnerDocument().createAttributeNS(
+                    namespaceURI,
+                    qualifiedName);
+            if (attributes == null) {
+                attributes = new AttributeMap(this, null);
+            }
+            newAttr.setNodeValue(value);
+            attributes.setNamedItemNS(newAttr);
                 }
                 else {
             if (newAttr instanceof AttrNSImpl){
@@ -694,25 +698,24 @@
                 attributes.setNamedItemNS(newAttr);
             }
 
-                        newAttr.setNodeValue(value);
-                }
+            newAttr.setNodeValue(value);
+        }
 
     } // setAttributeNS(String,String,String)
 
-
     /**
-     * Introduced in DOM Level 2. <p>
+     * Introduced in DOM Level 2.
+     * <p>
      *
      * Removes an attribute by local name and namespace URI. If the removed
-     * attribute has a default value it is immediately replaced.
-     * The replacing attribute has the same namespace URI and local name,
-     * as well as the original prefix.<p>
+     * attribute has a default value it is immediately replaced. The replacing
+     * attribute has the same namespace URI and local name, as well as the
+     * original prefix.<p>
      *
-     * @param namespaceURI  The namespace URI of the attribute to remove.
+     * @param namespaceURI The namespace URI of the attribute to remove.
      *
-     * @param localName     The local name of the attribute to remove.
-     * @throws                  NO_MODIFICATION_ALLOWED_ERR: Raised if this
-     *                          node is readonly.
+     * @param localName The local name of the attribute to remove.
+     * @throws NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
      * @since WD-DOM-Level-2-19990923
      */
     public void removeAttributeNS(String namespaceURI, String localName) {
@@ -737,15 +740,13 @@
     /**
      * Retrieves an Attr node by local name and namespace URI.
      *
-     * @param namespaceURI  The namespace URI of the attribute to
-     *                      retrieve.
-     * @param localName     The local name of the attribute to retrieve.
-     * @return Attr         The Attr node with the specified attribute
-     *                      local name and namespace
-     *                      URI or null if there is no such attribute.
+     * @param namespaceURI The namespace URI of the attribute to retrieve.
+     * @param localName The local name of the attribute to retrieve.
+     * @return Attr The Attr node with the specified attribute local name and
+     * namespace URI or null if there is no such attribute.
      * @since WD-DOM-Level-2-19990923
      */
-    public Attr getAttributeNodeNS(String namespaceURI, String localName){
+    public Attr getAttributeNodeNS(String namespaceURI, String localName) {
 
         if (needsSyncData()) {
             synchronizeData();
@@ -753,40 +754,34 @@
         if (attributes == null) {
             return null;
         }
-        return (Attr)attributes.getNamedItemNS(namespaceURI, localName);
+        return (Attr) attributes.getNamedItemNS(namespaceURI, localName);
 
     } // getAttributeNodeNS(String,String):Attr
 
     /**
-     * Introduced in DOM Level 2. <p>
+     * Introduced in DOM Level 2.
+     * <p>
      *
-     * Adds a new attribute. If an attribute with that local name and
-     * namespace URI is already present in the element, it is replaced
-     * by the new one.
+     * Adds a new attribute. If an attribute with that local name and namespace
+     * URI is already present in the element, it is replaced by the new one.
      *
-     * @param Attr      The Attr node to add to the attribute list. When
-     *                  the Node has no namespaceURI, this method behaves
-     *                  like setAttributeNode.
-     * @return Attr     If the newAttr attribute replaces an existing attribute
-     *                  with the same local name and namespace URI, the *
-     *                  previously existing Attr node is returned, otherwise
-     *                  null is returned.
-     * @throws          WRONG_DOCUMENT_ERR: Raised if newAttr
-     *                  was created from a different document than the one that
-     *                  created the element.
+     * @param newAttr The Attr node to add to the attribute list. When the Node
+     * has no namespaceURI, this method behaves like setAttributeNode.
+     * @return Attr If the newAttr attribute replaces an existing attribute with
+     * the same local name and namespace URI, the * previously existing Attr
+     * node is returned, otherwise null is returned.
+     * @throws WRONG_DOCUMENT_ERR: Raised if newAttr was created from a
+     * different document than the one that created the element.
      *
-     * @throws          NO_MODIFICATION_ALLOWED_ERR: Raised if
-     *                  this node is readonly.
+     * @throws NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
      *
-     * @throws          INUSE_ATTRIBUTE_ERR: Raised if newAttr is
-     *                  already an attribute of another Element object. The
-     *                  DOM user must explicitly clone Attr nodes to re-use
-     *                  them in other elements.
+     * @throws INUSE_ATTRIBUTE_ERR: Raised if newAttr is already an attribute of
+     * another Element object. The DOM user must explicitly clone Attr nodes to
+     * re-use them in other elements.
      * @since WD-DOM-Level-2-19990923
      */
     public Attr setAttributeNodeNS(Attr newAttr)
-        throws DOMException
-        {
+            throws DOMException {
 
         if (needsSyncData()) {
             synchronizeData();
@@ -794,9 +789,9 @@
         if (ownerDocument.errorChecking) {
             if (isReadOnly()) {
                 String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NO_MODIFICATION_ALLOWED_ERR", null);
-                    throw new DOMException(
-                                     DOMException.NO_MODIFICATION_ALLOWED_ERR,
-                                     msg);
+                throw new DOMException(
+                        DOMException.NO_MODIFICATION_ALLOWED_ERR,
+                        msg);
             }
             if (newAttr.getOwnerDocument() != ownerDocument) {
                 String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "WRONG_DOCUMENT_ERR", null);
@@ -813,9 +808,9 @@
     } // setAttributeNodeNS(Attr):Attr
 
     /**
-      * NON-DOM: sets attribute node for this element
-      */
-    protected int setXercesAttributeNode (Attr attr){
+     * NON-DOM: sets attribute node for this element
+     */
+    protected int setXercesAttributeNode(Attr attr) {
 
         if (needsSyncData()) {
             synchronizeData();
@@ -829,9 +824,9 @@
     }
 
     /**
-      * NON-DOM: get inded of an attribute
-      */
-    protected int getXercesAttribute(String namespaceURI, String localName){
+     * NON-DOM: get inded of an attribute
+     */
+    protected int getXercesAttribute(String namespaceURI, String localName) {
 
         if (needsSyncData()) {
             synchronizeData();
@@ -868,32 +863,30 @@
     }
 
     /**
-     * Introduced in DOM Level 2. <p>
+     * Introduced in DOM Level 2.
+     * <p>
      *
      * Returns a NodeList of all the Elements with a given local name and
      * namespace URI in the order in which they would be encountered in a
      * preorder traversal of the Document tree, starting from this node.
      *
-     * @param namespaceURI The namespace URI of the elements to match
-     *                     on. The special value "*" matches all
-     *                     namespaces. When it is null or an empty
-     *                     string, this method behaves like
-     *                     getElementsByTagName.
-     * @param localName    The local name of the elements to match on.
-     *                     The special value "*" matches all local names.
-     * @return NodeList    A new NodeList object containing all the matched
-     *                     Elements.
+     * @param namespaceURI The namespace URI of the elements to match on. The
+     * special value "*" matches all namespaces. When it is null or an empty
+     * string, this method behaves like getElementsByTagName.
+     * @param localName The local name of the elements to match on. The special
+     * value "*" matches all local names.
+     * @return NodeList A new NodeList object containing all the matched
+     * Elements.
      * @since WD-DOM-Level-2-19990923
      */
     public NodeList getElementsByTagNameNS(String namespaceURI,
-                                           String localName) {
+            String localName) {
         return new DeepNodeListImpl(this, namespaceURI, localName);
     }
 
     /**
-     * DOM Level 3 WD- Experimental.
-     * Override inherited behavior from NodeImpl and ParentNode to check on
-     * attributes
+     * DOM Level 3 WD- Experimental. Override inherited behavior from NodeImpl
+     * and ParentNode to check on attributes
      */
     public boolean isEqualNode(Node arg) {
         if (!super.isEqualNode(arg)) {
@@ -917,10 +910,9 @@
                     if (n2 == null || !((NodeImpl) n1).isEqualNode(n2)) {
                         return false;
                     }
-                }
-                else {
+                } else {
                     Node n2 = map2.getNamedItemNS(n1.getNamespaceURI(),
-                                                  n1.getLocalName());
+                            n1.getLocalName());
                     if (n2 == null || !((NodeImpl) n1).isEqualNode(n2)) {
                         return false;
                     }
@@ -941,8 +933,8 @@
             if (isReadOnly()) {
                 String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NO_MODIFICATION_ALLOWED_ERR", null);
                 throw new DOMException(
-                                     DOMException.NO_MODIFICATION_ALLOWED_ERR,
-                                     msg);
+                        DOMException.NO_MODIFICATION_ALLOWED_ERR,
+                        msg);
             }
 
             if (at.getOwnerElement() != this) {
@@ -953,8 +945,7 @@
         ((AttrImpl) at).isIdAttribute(makeId);
         if (!makeId) {
             ownerDocument.removeIdentifier(at.getValue());
-        }
-        else {
+        } else {
             ownerDocument.putIdentifier(at.getValue(), this);
         }
     }
@@ -968,19 +959,19 @@
         }
         Attr at = getAttributeNode(name);
 
-                if( at == null){
-                String msg = DOMMessageFormatter.formatMessage(
-                                                                        DOMMessageFormatter.DOM_DOMAIN,
-                                                                        "NOT_FOUND_ERR", null);
+        if (at == null) {
+            String msg = DOMMessageFormatter.formatMessage(
+                    DOMMessageFormatter.DOM_DOMAIN,
+                    "NOT_FOUND_ERR", null);
             throw new DOMException(DOMException.NOT_FOUND_ERR, msg);
-                }
+        }
 
-                if (ownerDocument.errorChecking) {
+        if (ownerDocument.errorChecking) {
             if (isReadOnly()) {
                 String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NO_MODIFICATION_ALLOWED_ERR", null);
                 throw new DOMException(
-                                     DOMException.NO_MODIFICATION_ALLOWED_ERR,
-                                     msg);
+                        DOMException.NO_MODIFICATION_ALLOWED_ERR,
+                        msg);
             }
 
             if (at.getOwnerElement() != this) {
@@ -992,8 +983,7 @@
         ((AttrImpl) at).isIdAttribute(makeId);
         if (!makeId) {
             ownerDocument.removeIdentifier(at.getValue());
-        }
-        else {
+        } else {
             ownerDocument.putIdentifier(at.getValue(), this);
         }
     }
@@ -1002,51 +992,52 @@
      * DOM Level 3: register the given attribute node as an ID attribute
      */
     public void setIdAttributeNS(String namespaceURI, String localName,
-                                    boolean makeId) {
+            boolean makeId) {
         if (needsSyncData()) {
             synchronizeData();
         }
         //if namespace uri is empty string, set it to 'null'
         if (namespaceURI != null) {
-            namespaceURI = (namespaceURI.length() == 0)? null : namespaceURI;
+            namespaceURI = (namespaceURI.length() == 0) ? null : namespaceURI;
         }
         Attr at = getAttributeNodeNS(namespaceURI, localName);
 
-                if( at == null){
-                String msg = DOMMessageFormatter.formatMessage(
-                                                                        DOMMessageFormatter.DOM_DOMAIN,
-                                                                        "NOT_FOUND_ERR", null);
+        if (at == null) {
+            String msg = DOMMessageFormatter.formatMessage(
+                    DOMMessageFormatter.DOM_DOMAIN,
+                    "NOT_FOUND_ERR", null);
             throw new DOMException(DOMException.NOT_FOUND_ERR, msg);
-                }
+        }
 
-                if (ownerDocument.errorChecking) {
+        if (ownerDocument.errorChecking) {
             if (isReadOnly()) {
-                String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NO_MODIFICATION_ALLOWED_ERR", null);
+                String msg = DOMMessageFormatter.formatMessage(
+                        DOMMessageFormatter.DOM_DOMAIN, "NO_MODIFICATION_ALLOWED_ERR", null);
                 throw new DOMException(
-                                     DOMException.NO_MODIFICATION_ALLOWED_ERR,
-                                     msg);
+                        DOMException.NO_MODIFICATION_ALLOWED_ERR,
+                        msg);
             }
 
             if (at.getOwnerElement() != this) {
-                String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NOT_FOUND_ERR", null);
+                String msg = DOMMessageFormatter.formatMessage(
+                        DOMMessageFormatter.DOM_DOMAIN, "NOT_FOUND_ERR", null);
                 throw new DOMException(DOMException.NOT_FOUND_ERR, msg);
             }
         }
         ((AttrImpl) at).isIdAttribute(makeId);
         if (!makeId) {
             ownerDocument.removeIdentifier(at.getValue());
-        }
-        else {
+        } else {
             ownerDocument.putIdentifier(at.getValue(), this);
         }
-   }
+    }
 
     /**
      * @see org.w3c.dom.TypeInfo#getTypeName()
      */
-     public String getTypeName() {
+    public String getTypeName() {
         return null;
-     }
+    }
 
     /**
      * @see org.w3c.dom.TypeInfo#getTypeNamespace()
@@ -1056,33 +1047,32 @@
     }
 
     /**
-     * Introduced in DOM Level 3. <p>
+     * Introduced in DOM Level 3.
+     * <p>
      * Checks if a type is derived from another by restriction. See:
      * http://www.w3.org/TR/DOM-Level-3-Core/core.html#TypeInfo-isDerivedFrom
      *
-     * @param ancestorNS
-     *        The namspace of the ancestor type declaration
-     * @param ancestorName
-     *        The name of the ancestor type declaration
-     * @param type
-     *        The reference type definition
+     * @param typeNamespaceArg The namspace of the ancestor type declaration
+     * @param typeNameArg The name of the ancestor type declaration
+     * @param derivationMethod The derivation method
      *
-     * @return boolean True if the type is derived by restriciton for the
-     *         reference type
+     * @return boolean True if the type is derived by restriction for the
+     * reference type
      */
     public boolean isDerivedFrom(String typeNamespaceArg,
-                                 String typeNameArg,
-                                 int derivationMethod) {
+            String typeNameArg,
+            int derivationMethod) {
 
         return false;
     }
 
-        /**
-         * Method getSchemaTypeInfo.
-         * @return TypeInfo
-         */
-    public TypeInfo getSchemaTypeInfo(){
-        if(needsSyncData()) {
+    /**
+     * Method getSchemaTypeInfo.
+     *
+     * @return TypeInfo
+     */
+    public TypeInfo getSchemaTypeInfo() {
+        if (needsSyncData()) {
             synchronizeData();
         }
         return this;
@@ -1091,25 +1081,24 @@
     //
     // Public methods
     //
-
     /**
      * NON-DOM: Subclassed to flip the attributes' readonly switch as well.
+     *
      * @see NodeImpl#setReadOnly
      */
     public void setReadOnly(boolean readOnly, boolean deep) {
-        super.setReadOnly(readOnly,deep);
+        super.setReadOnly(readOnly, deep);
         if (attributes != null) {
-            attributes.setReadOnly(readOnly,true);
+            attributes.setReadOnly(readOnly, true);
         }
     }
 
-
-
     //
     // Protected methods
     //
-
-    /** Synchronizes the data (name and value) for fast nodes. */
+    /**
+     * Synchronizes the data (name and value) for fast nodes.
+     */
     protected void synchronizeData() {
 
         // no need to sync in the future
@@ -1141,7 +1130,9 @@
         }
     }
 
-    /** Setup the default attributes. */
+    /**
+     * Setup the default attributes.
+     */
     protected void setupDefaultAttributes() {
         NamedNodeMapImpl defaults = getDefaultAttributes();
         if (defaults != null) {
@@ -1149,7 +1140,9 @@
         }
     }
 
-    /** Reconcile default attributes. */
+    /**
+     * Reconcile default attributes.
+     */
     protected void reconcileDefaultAttributes() {
         if (attributes != null) {
             NamedNodeMapImpl defaults = getDefaultAttributes();
@@ -1157,17 +1150,19 @@
         }
     }
 
-    /** Get the default attributes. */
+    /**
+     * Get the default attributes.
+     */
     protected NamedNodeMapImpl getDefaultAttributes() {
 
-        DocumentTypeImpl doctype =
-            (DocumentTypeImpl) ownerDocument.getDoctype();
+        DocumentTypeImpl doctype
+                = (DocumentTypeImpl) ownerDocument.getDoctype();
         if (doctype == null) {
             return null;
         }
-        ElementDefinitionImpl eldef =
-            (ElementDefinitionImpl)doctype.getElements()
-                                               .getNamedItem(getNodeName());
+        ElementDefinitionImpl eldef
+                = (ElementDefinitionImpl) doctype.getElements()
+                .getNamedItem(getNodeName());
         if (eldef == null) {
             return null;
         }
@@ -1175,4 +1170,208 @@
 
     } // getDefaultAttributes()
 
+    //
+    // ElementTraversal methods
+    //
+    /**
+     * @see <a
+     * href="http://www.w3.org/TR/2008/REC-ElementTraversal-20081222/#attribute-childElementCount">
+     * Element Traversal Specification</a>
+     */
+    @Override
+    public final int getChildElementCount() {
+        int count = 0;
+        Element child = getFirstElementChild();
+        while (child != null) {
+            ++count;
+            child = ((ElementImpl) child).getNextElementSibling();
+        }
+        return count;
+    } // getChildElementCount():int
+
+    /**
+     * @see <a
+     * href="http://www.w3.org/TR/2008/REC-ElementTraversal-20081222/#attribute-firstElementChild">
+     * Element Traversal Specification</a>
+     */
+    @Override
+    public final Element getFirstElementChild() {
+        Node n = getFirstChild();
+        while (n != null) {
+            switch (n.getNodeType()) {
+                case Node.ELEMENT_NODE:
+                    return (Element) n;
+                case Node.ENTITY_REFERENCE_NODE:
+                    final Element e = getFirstElementChild(n);
+                    if (e != null) {
+                        return e;
+                    }
+                    break;
+            }
+            n = n.getNextSibling();
+        }
+        return null;
+    } // getFirstElementChild():Element
+
+    /**
+     * @see <a
+     * href="http://www.w3.org/TR/2008/REC-ElementTraversal-20081222/#attribute-lastElementChild">
+     * Element Traversal Specification</a>
+     */
+    @Override
+    public final Element getLastElementChild() {
+        Node n = getLastChild();
+        while (n != null) {
+            switch (n.getNodeType()) {
+                case Node.ELEMENT_NODE:
+                    return (Element) n;
+                case Node.ENTITY_REFERENCE_NODE:
+                    final Element e = getLastElementChild(n);
+                    if (e != null) {
+                        return e;
+                    }
+                    break;
+            }
+            n = n.getPreviousSibling();
+        }
+        return null;
+    } // getLastElementChild():Element
+
+    /**
+     * @see <a
+     * href="http://www.w3.org/TR/2008/REC-ElementTraversal-20081222/#attribute-nextElementSibling">
+     * Element Traversal Specification</a>
+     */
+    @Override
+    public final Element getNextElementSibling() {
+        Node n = getNextLogicalSibling(this);
+        while (n != null) {
+            switch (n.getNodeType()) {
+                case Node.ELEMENT_NODE:
+                    return (Element) n;
+                case Node.ENTITY_REFERENCE_NODE:
+                    final Element e = getFirstElementChild(n);
+                    if (e != null) {
+                        return e;
+                    }
+                    break;
+            }
+            n = getNextLogicalSibling(n);
+        }
+        return null;
+    } // getNextElementSibling():Element
+
+    /**
+     * @see <a
+     * href="http://www.w3.org/TR/2008/REC-ElementTraversal-20081222/#attribute-previousElementSibling">
+     * Element Traversal Specification</a>
+     */
+    @Override
+    public final Element getPreviousElementSibling() {
+        Node n = getPreviousLogicalSibling(this);
+        while (n != null) {
+            switch (n.getNodeType()) {
+                case Node.ELEMENT_NODE:
+                    return (Element) n;
+                case Node.ENTITY_REFERENCE_NODE:
+                    final Element e = getLastElementChild(n);
+                    if (e != null) {
+                        return e;
+                    }
+                    break;
+            }
+            n = getPreviousLogicalSibling(n);
+        }
+        return null;
+    } // getPreviousElementSibling():Element
+
+    // Returns the first element node found from a
+    // non-recursive in order traversal of the given node.
+    private Element getFirstElementChild(Node n) {
+        final Node top = n;
+        while (n != null) {
+            if (n.getNodeType() == Node.ELEMENT_NODE) {
+                return (Element) n;
+            }
+            Node next = n.getFirstChild();
+            while (next == null) {
+                if (top == n) {
+                    break;
+                }
+                next = n.getNextSibling();
+                if (next == null) {
+                    n = n.getParentNode();
+                    if (n == null || top == n) {
+                        return null;
+                    }
+                }
+            }
+            n = next;
+        }
+        return null;
+    } // getFirstElementChild(Node):Element
+
+    // Returns the first element node found from a
+    // non-recursive reverse order traversal of the given node.
+    private Element getLastElementChild(Node n) {
+        final Node top = n;
+        while (n != null) {
+            if (n.getNodeType() == Node.ELEMENT_NODE) {
+                return (Element) n;
+            }
+            Node next = n.getLastChild();
+            while (next == null) {
+                if (top == n) {
+                    break;
+                }
+                next = n.getPreviousSibling();
+                if (next == null) {
+                    n = n.getParentNode();
+                    if (n == null || top == n) {
+                        return null;
+                    }
+                }
+            }
+            n = next;
+        }
+        return null;
+    } // getLastElementChild(Node):Element
+
+    // Returns the next logical sibling with respect to the given node.
+    private Node getNextLogicalSibling(Node n) {
+        Node next = n.getNextSibling();
+        // If "n" has no following sibling and its parent is an entity reference node we
+        // need to continue the search through the following siblings of the entity
+        // reference as these are logically siblings of the given node.
+        if (next == null) {
+            Node parent = n.getParentNode();
+            while (parent != null && parent.getNodeType() == Node.ENTITY_REFERENCE_NODE) {
+                next = parent.getNextSibling();
+                if (next != null) {
+                    break;
+                }
+                parent = parent.getParentNode();
+            }
+        }
+        return next;
+    } // getNextLogicalSibling(Node):Node
+
+    // Returns the previous logical sibling with respect to the given node.
+    private Node getPreviousLogicalSibling(Node n) {
+        Node prev = n.getPreviousSibling();
+        // If "n" has no previous sibling and its parent is an entity reference node we
+        // need to continue the search through the previous siblings of the entity
+        // reference as these are logically siblings of the given node.
+        if (prev == null) {
+            Node parent = n.getParentNode();
+            while (parent != null && parent.getNodeType() == Node.ENTITY_REFERENCE_NODE) {
+                prev = parent.getPreviousSibling();
+                if (prev != null) {
+                    break;
+                }
+                parent = parent.getParentNode();
+            }
+        }
+        return prev;
+    } // getPreviousLogicalSibling(Node):Node
 } // class ElementImpl
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/src/java.xml/share/classes/org/w3c/dom/ElementTraversal.java	Wed Jul 05 20:51:27 2017 +0200
@@ -0,0 +1,103 @@
+/*
+ * 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.
+ */
+/*
+ * Copyright (c) 2015 World Wide Web Consortium,
+ *
+ * (Massachusetts Institute of Technology, European Research Consortium for
+ * Informatics and Mathematics, Keio University, Beihang). All Rights Reserved.
+ * This work is distributed under the W3C(r) Software License [1] 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.
+ *
+ * [1] http://www.w3.org/Consortium/Legal/copyright-software
+ */
+
+package org.w3c.dom;
+
+/**
+ * The {@code ElementTraversal} interface is a set of read-only attributes
+ * which allow an author to easily navigate between elements in a document.
+ * <p>
+ * In conforming implementations of Element Traversal, all objects that
+ * implement {@link Element} must also implement the {@code ElementTraversal}
+ * interface. Four of the methods,
+ * {@link #getFirstElementChild}, {@link #getLastElementChild},
+ * {@link #getPreviousElementSibling}, and {@link #getNextElementSibling},
+ * each provides a live reference to another element with the defined
+ * relationship to the current element, if the related element exists. The
+ * fifth method, {@link #getChildElementCount}, exposes the number of child
+ * elements of an element, for preprocessing before navigation.
+ *
+ * @see
+ * <a href='http://www.w3.org/TR/ElementTraversal/'><cite>Element Traversal Specification</cite></a>.
+ *
+ * @since 9
+ */
+public interface ElementTraversal {
+
+    /**
+     * Returns a reference to the first child node of the element which is of
+     * the {@link Element} type.
+     *
+     * @return a reference to an element child, {@code null} if the element has
+     * no child of the {@link Element} type.
+     */
+    Element getFirstElementChild();
+
+    /**
+     * Returns a reference to the last child node of the element which is of
+     * the {@link Element} type.
+     *
+     * @return a reference to an element child, {@code null} if the element has
+     * no child of the {@link Element} type.
+     */
+    Element getLastElementChild();
+
+    /**
+     * Returns a reference to the sibling node of the element which most immediately
+     * precedes the element in document order, and which is of the {@link Element} type.
+     *
+     * @return a reference to an element child, {@code null} if the element has
+     * no sibling node of the {@link Element} type that comes before this one.
+     */
+    Element getPreviousElementSibling();
+
+    /**
+     * Returns a reference to the sibling node of the element which most immediately
+     * follows the element in document order, and which is of the {@link Element} type.
+     *
+     * @return a reference to an element child, {@code null} if the element has
+     * no sibling node of the {@link Element} type that comes after this one.
+     */
+    Element getNextElementSibling();
+
+    /**
+     * Returns the current number of child nodes of the element which are of
+     * the {@link Element} type.
+     *
+     * @return the number of element children, or {@code 0} if the element has
+     * no element children.
+     */
+    int getChildElementCount();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/dom/ElementTraversal.java	Wed Jul 05 20:51:27 2017 +0200
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package dom;
+
+import java.io.IOException;
+import java.io.InputStream;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import org.testng.Assert;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xml.sax.SAXException;
+
+/*
+ * @bug 8135283
+ * @summary Tests for the Element Traversal interface.
+ */
+
+public class ElementTraversal {
+    /*
+       Verifies the ElementTraversal interface by exercising all of its five
+       methods while reading through the xml document.
+     */
+    @Test(dataProvider = "doc")
+    public void test(Document doc) {
+        org.w3c.dom.ElementTraversal et = (org.w3c.dom.ElementTraversal)doc.getDocumentElement();
+        //4 toys are listed
+        Assert.assertEquals(et.getChildElementCount(), 4);
+
+        //The 1st is the Martian
+        Element toy1 = et.getFirstElementChild();
+        verify(toy1, "1", "The Martian");
+
+        //toy1 has no previous element
+        Element noE = ((org.w3c.dom.ElementTraversal)toy1).getPreviousElementSibling();
+        Assert.assertEquals(noE, null);
+
+        //The 1st toy's next element is toy2, the Doll
+        Element toy2 = ((org.w3c.dom.ElementTraversal)toy1).getNextElementSibling();
+        verify(toy2, "2", "The Doll");
+
+        //The last toy is toy4, the Spaceship
+        Element toy4 = et.getLastElementChild();
+        verify(toy4, "4", "The Spaceship");
+
+        //toy4 has no next element
+        noE = ((org.w3c.dom.ElementTraversal)toy4).getNextElementSibling();
+        Assert.assertEquals(noE, null);
+
+        //toy4's previous element is toy3, Transformer X
+        //toy3 is also an EntityReference
+        Element toy3 = ((org.w3c.dom.ElementTraversal)toy4).getPreviousElementSibling();
+        verify(toy3, "3", "Transformer X");
+    }
+
+    /**
+     * Verifies that the values matches the specified element.
+     * @param id the value of the id attribute
+     * @param name the value of its name element
+     */
+    void verify(Element e, String id, String name) {
+        Assert.assertEquals(e.getAttribute("id"), id);
+        Element toyName = ((org.w3c.dom.ElementTraversal)e).getFirstElementChild();
+        Assert.assertEquals(toyName.getTextContent(), name);
+    }
+
+
+    /*
+     * DataProvider: a Document object
+     */
+    @DataProvider(name = "doc")
+    Object[][] getXPath() {
+        return new Object[][]{{getDoc()}};
+    }
+    Document getDoc() {
+        InputStream xmlFile = getClass().getResourceAsStream("ElementTraversal.xml");
+        Document doc = null;
+        try {
+            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+            dbf.setExpandEntityReferences(false);
+            DocumentBuilder db = dbf.newDocumentBuilder();
+            doc = db.parse(xmlFile);
+        } catch (ParserConfigurationException | SAXException | IOException e) {
+            System.out.println("fail: " + e.getMessage());
+        }
+
+        return doc;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/dom/ElementTraversal.xml	Wed Jul 05 20:51:27 2017 +0200
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE toys [
+<!ENTITY toy3 "<name>Transformer X</name><price>519</price>">
+]>
+
+<toys>
+
+    <toy id="1">	
+        <name>The Martian</name>
+        <price>98470</price>
+    </toy>
+    <toy id="2">
+        <name>The Doll</name>
+        <price>345</price>
+    </toy>         
+    <toy id="3">
+        &toy3;
+    </toy>    
+    <toy id="4">
+        <name>The Spaceship</name>
+        <price>725</price>
+    </toy>         
+     
+</toys>
\ No newline at end of file
--- a/jdk/.hgtags	Sat Sep 26 09:22:24 2015 -0700
+++ b/jdk/.hgtags	Wed Jul 05 20:51:27 2017 +0200
@@ -325,3 +325,4 @@
 4947810137ae53abba3028cc366af953d90fa81a jdk9-b80
 fdc13a2d32867ca3c57b7fa2620c6b59c83168cb jdk9-b81
 b10b64263b563e21f055c881444f625ec618b826 jdk9-b82
+d11f25ce3c545823f53bb978d454a4d2901abac3 jdk9-b83
--- a/jdk/make/mapfiles/libjava/mapfile-vers	Sat Sep 26 09:22:24 2015 -0700
+++ b/jdk/make/mapfiles/libjava/mapfile-vers	Wed Jul 05 20:51:27 2017 +0200
@@ -157,7 +157,6 @@
 		Java_java_lang_StrictMath_cosh;
 		Java_java_lang_StrictMath_sinh;
 		Java_java_lang_StrictMath_tanh;
-		Java_java_lang_StrictMath_hypot;
 		Java_java_lang_StrictMath_log1p;
 		Java_java_lang_StrictMath_expm1;
 		Java_java_lang_Object_getClass;
--- a/jdk/src/java.base/share/classes/java/lang/FdLibm.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/FdLibm.java	Wed Jul 05 20:51:27 2017 +0200
@@ -26,7 +26,8 @@
 package java.lang;
 
 /**
- * Port of the "Freely Distributable Math Library", version 5.3, from C to Java.
+ * Port of the "Freely Distributable Math Library", version 5.3, from
+ * C to Java.
  *
  * <p>The C version of fdlibm relied on the idiom of pointer aliasing
  * a 64-bit double floating-point value as a two-element array of
@@ -37,7 +38,7 @@
  * operated on as integer values, the standard library methods for
  * bitwise floating-point to integer conversion,
  * Double.longBitsToDouble and Double.doubleToRawLongBits, are directly
- * or indirectly used .
+ * or indirectly used.
  *
  * <p>The C version of fdlibm also took some pains to signal the
  * correct IEEE 754 exceptional conditions divide by zero, invalid,
@@ -47,13 +48,21 @@
  * handling is not supported natively in the JVM, such coding patterns
  * have been omitted from this port. For example, rather than {@code
  * return huge * huge}, this port will use {@code return INFINITY}.
+ *
+ * <p>Various comparison and arithmetic operations in fdlibm could be
+ * done either based on the integer view of a value or directly on the
+ * floating-point representation. Which idiom is faster may depend on
+ * platform specific factors. However, for code clarity if no other
+ * reason, this port will favor expressing the semantics of those
+ * operations in terms of floating-point operations when convenient to
+ * do so.
  */
 class FdLibm {
     // Constants used by multiple algorithms
     private static final double INFINITY = Double.POSITIVE_INFINITY;
 
     private FdLibm() {
-        throw new UnsupportedOperationException("No instances for you.");
+        throw new UnsupportedOperationException("No FdLibm instances for you.");
     }
 
     /**
@@ -91,13 +100,146 @@
     }
 
     /**
+     * hypot(x,y)
+     *
+     * Method :
+     *      If (assume round-to-nearest) z = x*x + y*y
+     *      has error less than sqrt(2)/2 ulp, than
+     *      sqrt(z) has error less than 1 ulp (exercise).
+     *
+     *      So, compute sqrt(x*x + y*y) with some care as
+     *      follows to get the error below 1 ulp:
+     *
+     *      Assume x > y > 0;
+     *      (if possible, set rounding to round-to-nearest)
+     *      1. if x > 2y  use
+     *              x1*x1 + (y*y + (x2*(x + x1))) for x*x + y*y
+     *      where x1 = x with lower 32 bits cleared, x2 = x - x1; else
+     *      2. if x <= 2y use
+     *              t1*y1 + ((x-y) * (x-y) + (t1*y2 + t2*y))
+     *      where t1 = 2x with lower 32 bits cleared, t2 = 2x - t1,
+     *      y1= y with lower 32 bits chopped, y2 = y - y1.
+     *
+     *      NOTE: scaling may be necessary if some argument is too
+     *            large or too tiny
+     *
+     * Special cases:
+     *      hypot(x,y) is INF if x or y is +INF or -INF; else
+     *      hypot(x,y) is NAN if x or y is NAN.
+     *
+     * Accuracy:
+     *      hypot(x,y) returns sqrt(x^2 + y^2) with error less
+     *      than 1 ulp (unit in the last place)
+     */
+    public static class Hypot {
+        public static final double TWO_MINUS_600 = 0x1.0p-600;
+        public static final double TWO_PLUS_600  = 0x1.0p+600;
+
+        public static strictfp double compute(double x, double y) {
+            double a = Math.abs(x);
+            double b = Math.abs(y);
+
+            if (!Double.isFinite(a) || !Double.isFinite(b)) {
+                if (a == INFINITY || b == INFINITY)
+                    return INFINITY;
+                else
+                    return a + b; // Propagate NaN significand bits
+            }
+
+            if (b > a) {
+                double tmp = a;
+                a = b;
+                b = tmp;
+            }
+            assert a >= b;
+
+            // Doing bitwise conversion after screening for NaN allows
+            // the code to not worry about the possibility of
+            // "negative" NaN values.
+
+            // Note: the ha and hb variables are the high-order
+            // 32-bits of a and b stored as integer values. The ha and
+            // hb values are used first for a rough magnitude
+            // comparison of a and b and second for simulating higher
+            // precision by allowing a and b, respectively, to be
+            // decomposed into non-overlapping portions. Both of these
+            // uses could be eliminated. The magnitude comparison
+            // could be eliminated by extracting and comparing the
+            // exponents of a and b or just be performing a
+            // floating-point divide.  Splitting a floating-point
+            // number into non-overlapping portions can be
+            // accomplished by judicious use of multiplies and
+            // additions. For details see T. J. Dekker, A Floating
+            // Point Technique for Extending the Available Precision ,
+            // Numerische Mathematik, vol. 18, 1971, pp.224-242 and
+            // subsequent work.
+
+            int ha = __HI(a);        // high word of a
+            int hb = __HI(b);        // high word of b
+
+            if ((ha - hb) > 0x3c00000) {
+                return a + b;  // x / y > 2**60
+            }
+
+            int k = 0;
+            if (a > 0x1.0p500) {   // a > 2**500
+                // scale a and b by 2**-600
+                ha -= 0x25800000;
+                hb -= 0x25800000;
+                a = a * TWO_MINUS_600;
+                b = b * TWO_MINUS_600;
+                k += 600;
+            }
+            double t1, t2;
+            if (b < 0x1.0p-500) {   // b < 2**-500
+                if (b < Double.MIN_NORMAL) {      // subnormal b or 0 */
+                    if (b == 0.0)
+                        return a;
+                    t1 = 0x1.0p1022;   // t1 = 2^1022
+                    b *= t1;
+                    a *= t1;
+                    k -= 1022;
+                } else {            // scale a and b by 2^600
+                    ha += 0x25800000;       // a *= 2^600
+                    hb += 0x25800000;       // b *= 2^600
+                    a = a * TWO_PLUS_600;
+                    b = b * TWO_PLUS_600;
+                    k -= 600;
+                }
+            }
+            // medium size a and b
+            double w = a - b;
+            if (w > b) {
+                t1 = 0;
+                t1 = __HI(t1, ha);
+                t2 = a - t1;
+                w  = Math.sqrt(t1*t1 - (b*(-b) - t2 * (a + t1)));
+            } else {
+                double y1, y2;
+                a  = a + a;
+                y1 = 0;
+                y1 = __HI(y1, hb);
+                y2 = b - y1;
+                t1 = 0;
+                t1 = __HI(t1, ha + 0x00100000);
+                t2 = a - t1;
+                w  = Math.sqrt(t1*y1 - (w*(-w) - (t1*y2 + t2*b)));
+            }
+            if (k != 0) {
+                return Math.powerOfTwoD(k) * w;
+            } else
+                return w;
+        }
+    }
+
+    /**
      * Compute x**y
      *                    n
      * Method:  Let x =  2   * (1+f)
      *      1. Compute and return log2(x) in two pieces:
      *              log2(x) = w1 + w2,
      *         where w1 has 53 - 24 = 29 bit trailing zeros.
-     *      2. Perform y*log2(x) = n+y' by simulating muti-precision
+     *      2. Perform y*log2(x) = n+y' by simulating multi-precision
      *         arithmetic, where |y'| <= 0.5.
      *      3. Return x**y = 2**n*exp(y'*log2)
      *
--- a/jdk/src/java.base/share/classes/java/lang/Process.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/Process.java	Wed Jul 05 20:51:27 2017 +0200
@@ -500,7 +500,8 @@
 
     /**
      * Returns a snapshot of the direct children of the process.
-     * A process that is {@link #isAlive not alive} has zero children.
+     * The parent of a direct child process is the process.
+     * Typically, a process that is {@link #isAlive not alive} has no children.
      * <p>
      * <em>Note that processes are created and terminate asynchronously.
      * There is no guarantee that a process is {@link #isAlive alive}.
@@ -510,8 +511,8 @@
      * This implementation returns the direct children as:
      * {@link #toHandle toHandle().children()}.
      *
-     * @return a Stream of ProcessHandles for processes that are direct children
-     *         of the process
+     * @return a sequential Stream of ProcessHandles for processes that are
+     *         direct children of the process
      * @throws UnsupportedOperationException if the Process implementation
      *         does not support this operation
      * @throws SecurityException if a security manager has been installed and
@@ -524,7 +525,9 @@
 
     /**
      * Returns a snapshot of the direct and indirect children of the process.
-     * A process that is {@link #isAlive not alive} has zero children.
+     * An indirect child is one whose parent is either a direct child or
+     * another indirect child.
+     * Typically, a process that is {@link #isAlive not alive} has no children.
      * <p>
      * <em>Note that processes are created and terminate asynchronously.
      * There is no guarantee that a process is {@link #isAlive alive}.
@@ -534,8 +537,8 @@
      * This implementation returns all children as:
      * {@link #toHandle toHandle().allChildren()}.
      *
-     * @return a Stream of ProcessHandles for processes that are direct and
-     *         indirect children of the process
+     * @return a sequential Stream of ProcessHandles for processes that are
+     *         direct and indirect children of the process
      * @throws UnsupportedOperationException if the Process implementation
      *         does not support this operation
      * @throws SecurityException if a security manager has been installed and
--- a/jdk/src/java.base/share/classes/java/lang/ProcessBuilder.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/ProcessBuilder.java	Wed Jul 05 20:51:27 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -33,7 +33,8 @@
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
-
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 /**
  * This class is used to create operating system processes.
  *
@@ -445,6 +446,7 @@
      * <ul>
      * <li>the special value {@link #PIPE Redirect.PIPE}
      * <li>the special value {@link #INHERIT Redirect.INHERIT}
+     * <li>the special value {@link #DISCARD Redirect.DISCARD}
      * <li>a redirection to read from a file, created by an invocation of
      *     {@link Redirect#from Redirect.from(File)}
      * <li>a redirection to write to a file,  created by an invocation of
@@ -459,6 +461,13 @@
      * @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"));
+                }
+        );
+
         /**
          * The type of a {@link Redirect}.
          */
@@ -529,6 +538,28 @@
                 public Type type() { return Type.INHERIT; }
                 public String toString() { return type().toString(); }};
 
+
+        /**
+         * Indicates that subprocess output will be discarded.
+         * A typical implementation discards the output by writing to
+         * an operating system specific "null file".
+         *
+         * <p>It will always be true that
+         * <pre> {@code
+         * Redirect.DISCARD.file() the filename appropriate for the operating system
+         * and may be null &&
+         * Redirect.DISCARD.type() == Redirect.Type.WRITE &&
+         * Redirect.DISCARD.append() == false
+         * }</pre>
+         * @since 9
+         */
+        public static final Redirect DISCARD = new Redirect() {
+                public Type type() { return Type.WRITE; }
+                public String toString() { return type().toString(); }
+                public File file() { return NULL_FILE; }
+                boolean append() { return false; }
+        };
+
         /**
          * Returns the {@link File} source or destination associated
          * with this redirect, or {@code null} if there is no such file.
--- a/jdk/src/java.base/share/classes/java/lang/ProcessHandle.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/ProcessHandle.java	Wed Jul 05 20:51:27 2017 +0200
@@ -149,14 +149,15 @@
 
     /**
      * Returns a snapshot of the current direct children of the process.
-     * A process that is {@link #isAlive not alive} has zero children.
+     * The {@link #parent} of a direct child process is the process.
+     * Typically, a process that is {@link #isAlive not alive} has no children.
      * <p>
      * <em>Note that processes are created and terminate asynchronously.
      * There is no guarantee that a process is {@link #isAlive alive}.
      * </em>
      *
-     * @return a Stream of ProcessHandles for processes that are direct children
-     *         of the process
+     * @return a sequential Stream of ProcessHandles for processes that are
+     *         direct children of the process
      * @throws SecurityException if a security manager has been installed and
      *         it denies RuntimePermission("manageProcess")
      */
@@ -164,14 +165,16 @@
 
     /**
      * Returns a snapshot of the current direct and indirect children of the process.
-     * A process that is {@link #isAlive not alive} has zero children.
+     * An indirect child is one whose parent is either a direct child or
+     * another indirect child.
+     * Typically, a process that is {@link #isAlive not alive} has no children.
      * <p>
      * <em>Note that processes are created and terminate asynchronously.
      * There is no guarantee that a process is {@link #isAlive alive}.
      * </em>
      *
-     * @return a Stream of ProcessHandles for processes that are direct and
-     *         indirect children of the process
+     * @return a sequential Stream of ProcessHandles for processes that are
+     *         direct and indirect children of the process
      * @throws SecurityException if a security manager has been installed and
      *         it denies RuntimePermission("manageProcess")
      */
--- a/jdk/src/java.base/share/classes/java/lang/StrictMath.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/StrictMath.java	Wed Jul 05 20:51:27 2017 +0200
@@ -1329,7 +1329,9 @@
      * without intermediate overflow or underflow
      * @since 1.5
      */
-    public static native double hypot(double x, double y);
+    public static double hypot(double x, double y) {
+        return FdLibm.Hypot.compute(x, y);
+    }
 
     /**
      * Returns <i>e</i><sup>x</sup>&nbsp;-1.  Note that for values of
--- a/jdk/src/java.base/share/classes/java/lang/invoke/BoundMethodHandle.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/BoundMethodHandle.java	Wed Jul 05 20:51:27 2017 +0200
@@ -404,6 +404,14 @@
             d = lookupCache(types);
             // Class loading must have upgraded the cache.
             assert(d != null && !d.isPlaceholder());
+            if (OBSERVE_BMH_SPECIES_CREATION) {
+                if (d == null) {
+                    throw new IllegalStateException("d == null");
+                }
+                if (d.isPlaceholder()) {
+                    throw new IllegalStateException("d is place holder");
+                }
+            }
             return d;
         }
         static SpeciesData getForClass(String types, Class<? extends BoundMethodHandle> clazz) {
@@ -415,6 +423,9 @@
             if (d != null)  return d;
             d = new SpeciesData(types);
             assert(d.isPlaceholder());
+            if (OBSERVE_BMH_SPECIES_CREATION && !d.isPlaceholder()) {
+                throw new IllegalStateException("d is not place holder");
+            }
             CACHE.put(types, d);
             return d;
         }
@@ -422,6 +433,15 @@
             SpeciesData d2;
             assert((d2 = CACHE.get(types)) == null || d2.isPlaceholder());
             assert(!d.isPlaceholder());
+            if (OBSERVE_BMH_SPECIES_CREATION) {
+                d2 = CACHE.get(types);
+                if (d2 != null && !d2.isPlaceholder()) {
+                    throw new IllegalStateException("non-null d2 is not place holder");
+                }
+                if (d.isPlaceholder()) {
+                    throw new IllegalStateException("d is place holder");
+                }
+            }
             CACHE.put(types, d);
             return d;
         }
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleStatics.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleStatics.java	Wed Jul 05 20:51:27 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -51,8 +51,12 @@
     static final boolean PROFILE_GWT;
     static final int CUSTOMIZE_THRESHOLD;
 
+    // This is a temporary property added for improved error reporting; it will
+    // be removed once it has served its purpose.
+    static final boolean OBSERVE_BMH_SPECIES_CREATION;
+
     static {
-        final Object[] values = new Object[9];
+        final Object[] values = new Object[10];
         AccessController.doPrivileged(new PrivilegedAction<>() {
                 public Void run() {
                     values[0] = Boolean.getBoolean("java.lang.invoke.MethodHandle.DEBUG_NAMES");
@@ -64,6 +68,7 @@
                     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.getBoolean("java.lang.invoke.MethodHandle.OBSERVE_BMH_SPECIES_CREATION");
                     return null;
                 }
             });
@@ -77,6 +82,8 @@
         PROFILE_GWT               = (Boolean) values[7];
         CUSTOMIZE_THRESHOLD       = (Integer) values[8];
 
+        OBSERVE_BMH_SPECIES_CREATION = (Boolean) values[9];
+
         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/time/Month.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/jdk/src/java.base/share/classes/java/time/Month.java	Wed Jul 05 20:51:27 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -379,7 +379,7 @@
 
     //-----------------------------------------------------------------------
     /**
-     * Returns the month-of-year that is the specified number of quarters after this one.
+     * Returns the month-of-year that is the specified number of months after this one.
      * <p>
      * The calculation rolls around the end of the year from December to January.
      * The specified period may be negative.
--- a/jdk/src/java.base/share/classes/java/time/temporal/TemporalAdjusters.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/jdk/src/java.base/share/classes/java/time/temporal/TemporalAdjusters.java	Wed Jul 05 20:51:27 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -313,7 +313,7 @@
 
     /**
      * Returns the day-of-week in month adjuster, which returns a new date
-     * in the same month with the ordinal day-of-week.
+     * with the ordinal day-of-week based on the month.
      * This is used for expressions like the 'second Tuesday in March'.
      * <p>
      * The ISO calendar system behaves as follows:<br>
--- a/jdk/src/java.base/share/classes/java/util/Locale.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/jdk/src/java.base/share/classes/java/util/Locale.java	Wed Jul 05 20:51:27 2017 +0200
@@ -825,7 +825,7 @@
      * setDefault(Locale.Category, Locale) method.
      *
      * @param category - the specified category to get the default locale
-     * @throws NullPointerException - if category is null
+     * @throws NullPointerException if category is null
      * @return the default locale for the specified Category for this instance
      *     of the Java Virtual Machine
      * @see #setDefault(Locale.Category, Locale)
@@ -954,9 +954,9 @@
      *
      * @param category - the specified category to set the default locale
      * @param newLocale - the new default locale
-     * @throws SecurityException - if a security manager exists and its
+     * @throws SecurityException if a security manager exists and its
      *     checkPermission method doesn't allow the operation.
-     * @throws NullPointerException - if category and/or newLocale is null
+     * @throws NullPointerException if category and/or newLocale is null
      * @see SecurityManager#checkPermission(java.security.Permission)
      * @see PropertyPermission
      * @see #getDefault(Locale.Category)
--- a/jdk/src/java.base/share/classes/java/util/stream/Collectors.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/jdk/src/java.base/share/classes/java/util/stream/Collectors.java	Wed Jul 05 20:51:27 2017 +0200
@@ -504,7 +504,7 @@
      */
     public static <T> Collector<T, ?, Long>
     counting() {
-        return reducing(0L, e -> 1L, Long::sum);
+        return summingLong(e -> 1L);
     }
 
     /**
--- a/jdk/src/java.base/share/classes/sun/nio/ch/FileChannelImpl.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/FileChannelImpl.java	Wed Jul 05 20:51:27 2017 +0200
@@ -328,6 +328,7 @@
             int rv = -1;
             long p = -1;
             int ti = -1;
+            long rp = -1;
             try {
                 begin();
                 ti = threads.add();
@@ -363,8 +364,8 @@
                 if (p > newSize)
                     p = newSize;
                 do {
-                    rv = (int)position0(fd, p);
-                } while ((rv == IOStatus.INTERRUPTED) && isOpen());
+                    rp = position0(fd, p);
+                } while ((rp == IOStatus.INTERRUPTED) && isOpen());
                 return this;
             } finally {
                 threads.remove(ti);
--- a/jdk/src/java.base/share/classes/sun/reflect/generics/factory/CoreReflectionFactory.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/jdk/src/java.base/share/classes/sun/reflect/generics/factory/CoreReflectionFactory.java	Wed Jul 05 20:51:27 2017 +0200
@@ -70,20 +70,20 @@
 
     /**
      * Factory for this class. Returns an instance of
-     * <tt>CoreReflectionFactory</tt> for the declaration and scope
+     * {@code CoreReflectionFactory} for the declaration and scope
      * provided.
      * This factory will produce reflective objects of the appropriate
      * kind. Classes produced will be those that would be loaded by the
-     * defining class loader of the declaration <tt>d</tt> (if <tt>d</tt>
+     * defining class loader of the declaration {@code d} (if {@code d}
      * is a type declaration, or by the defining loader of the declaring
-     * class of <tt>d</tt> otherwise.
+     * class of {@code d} otherwise.
      * <p> Type variables will be created or lookup as necessary in the
-     * scope <tt> s</tt>.
+     * scope {@code s}.
      * @param d - the generic declaration (class, interface, method or
      * constructor) that this factory services
      * @param s  the scope in which the factory will allocate and search for
      * type variables
-     * @return an instance of <tt>CoreReflectionFactory</tt>
+     * @return an instance of {@code CoreReflectionFactory}
      */
     public static CoreReflectionFactory make(GenericDeclaration d, Scope s) {
         return new CoreReflectionFactory(d, s);
--- a/jdk/src/java.base/share/classes/sun/reflect/generics/factory/GenericsFactory.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/jdk/src/java.base/share/classes/sun/reflect/generics/factory/GenericsFactory.java	Wed Jul 05 20:51:27 2017 +0200
@@ -47,32 +47,32 @@
  */
 public interface GenericsFactory {
     /**
-     * Returns a new type variable declaration. Note that <tt>name</tt>
-     * may be empty (but not <tt>null</tt>). If <tt>bounds</tt> is
-     * empty, a bound of <tt>java.lang.Object</tt> is used.
+     * Returns a new type variable declaration. Note that {@code name}
+     * may be empty (but not {@code null}). If {@code bounds} is
+     * empty, a bound of {@code java.lang.Object} is used.
      * @param name The name of the type variable
      * @param bounds An array of abstract syntax trees representing
      * the upper bound(s) on the type variable being declared
      * @return a new type variable declaration
-     * @throws NullPointerException - if any of the actual parameters
-     * or any of the elements of <tt>bounds</tt> are <tt>null</tt>.
+     * @throws NullPointerException if any of the actual parameters
+     * or any of the elements of {@code bounds} are {@code null}.
      */
     TypeVariable<?> makeTypeVariable(String name,
                                      FieldTypeSignature[] bounds);
     /**
-     * Returns an instance of the <tt>ParameterizedType</tt> interface
+     * Returns an instance of the {@code ParameterizedType} interface
      * that corresponds to a generic type instantiation of the
-     * generic declaration <tt>declaration</tt> with actual type arguments
-     * <tt>typeArgs</tt>.
-     * If <tt>owner</tt> is <tt>null</tt>, the declaring class of
-     * <tt>declaration</tt> is used as the owner of this parameterized
+     * generic declaration {@code declaration} with actual type arguments
+     * {@code typeArgs}.
+     * If {@code owner} is {@code null}, the declaring class of
+     * {@code declaration} is used as the owner of this parameterized
      * type.
      * <p> This method throws a MalformedParameterizedTypeException
      * under the following circumstances:
      * If the type declaration does not represent a generic declaration
-     * (i.e., it is not an instance of <tt>GenericDeclaration</tt>).
+     * (i.e., it is not an instance of {@code GenericDeclaration}).
      * If the number of actual type arguments (i.e., the size of the
-     * array <tt>typeArgs</tt>) does not correspond to the number of
+     * array {@code typeArgs}) does not correspond to the number of
      * formal type arguments.
      * If any of the actual type arguments is not an instance of the
      * bounds on the corresponding formal.
@@ -81,39 +81,39 @@
      * @param typeArgs - the list of actual type arguments
      * @return - a parameterized type representing the instantiation
      * of the declaration with the actual type arguments
-     * @throws MalformedParameterizedTypeException - if the instantiation
+     * @throws MalformedParameterizedTypeException if the instantiation
      * is invalid
-     * @throws NullPointerException - if any of <tt>declaration</tt>
-     * , <tt>typeArgs</tt>
-     * or any of the elements of <tt>typeArgs</tt> are <tt>null</tt>
+     * @throws NullPointerException if any of {@code declaration},
+     * {@code typeArgs}
+     * or any of the elements of {@code typeArgs} are {@code null}
      */
     ParameterizedType makeParameterizedType(Type declaration,
                                             Type[] typeArgs,
                                             Type owner);
 
     /**
-     * Returns the type variable with name <tt>name</tt>, if such
+     * Returns the type variable with name {@code name}, if such
      * a type variable is declared in the
      * scope used to create this factory.
-     * Returns <tt>null</tt> otherwise.
+     * Returns {@code null} otherwise.
      * @param name - the name of the type variable to search for
-     * @return - the type variable with name <tt>name</tt>, or <tt>null</tt>
-     * @throws  NullPointerException - if any of actual parameters are
-     * <tt>null</tt>
+     * @return - the type variable with name {@code name}, or {@code null}
+     * @throws  NullPointerException if any of actual parameters are
+     * {@code null}
      */
     TypeVariable<?> findTypeVariable(String name);
 
     /**
      * Returns a new wildcard type variable. If
-     * <tt>ubs</tt> is empty, a bound of <tt>java.lang.Object</tt> is used.
+     * {@code ubs} is empty, a bound of {@code java.lang.Object} is used.
      * @param ubs An array of abstract syntax trees representing
      * the upper bound(s) on the type variable being declared
      * @param lbs An array of abstract syntax trees representing
      * the lower bound(s) on the type variable being declared
      * @return a new wildcard type variable
-     * @throws NullPointerException - if any of the actual parameters
-     * or any of the elements of <tt>ubs</tt> or <tt>lbs</tt>are
-     * <tt>null</tt>
+     * @throws NullPointerException if any of the actual parameters
+     * or any of the elements of {@code ubs} or {@code lbs} are
+     * {@code null}
      */
     WildcardType makeWildcard(FieldTypeSignature[] ubs,
                               FieldTypeSignature[] lbs);
@@ -127,64 +127,64 @@
      * a MalformedParameterizedTypeException is thrown.
      * @param componentType - the component type of the array
      * @return a (possibly generic) array type.
-     * @throws MalformedParameterizedTypeException if <tt>componentType</tt>
+     * @throws MalformedParameterizedTypeException if {@code componentType}
      * is a parameterized type with non-wildcard type arguments
-     * @throws NullPointerException - if any of the actual parameters
-     * are <tt>null</tt>
+     * @throws NullPointerException if any of the actual parameters
+     * are {@code null}
      */
     Type makeArrayType(Type componentType);
 
     /**
-     * Returns the reflective representation of type <tt>byte</tt>.
-     * @return the reflective representation of type <tt>byte</tt>.
+     * Returns the reflective representation of type {@code byte}.
+     * @return the reflective representation of type {@code byte}.
      */
     Type makeByte();
 
     /**
-     * Returns the reflective representation of type <tt>boolean</tt>.
-     * @return the reflective representation of type <tt>boolean</tt>.
+     * Returns the reflective representation of type {@code boolean}.
+     * @return the reflective representation of type {@code boolean}.
      */
     Type makeBool();
 
     /**
-     * Returns the reflective representation of type <tt>short</tt>.
-     * @return the reflective representation of type <tt>short</tt>.
+     * Returns the reflective representation of type {@code short}.
+     * @return the reflective representation of type {@code short}.
      */
     Type makeShort();
 
     /**
-     * Returns the reflective representation of type <tt>char</tt>.
-     * @return the reflective representation of type <tt>char</tt>.
+     * Returns the reflective representation of type {@code char}.
+     * @return the reflective representation of type {@code char}.
      */
     Type makeChar();
 
     /**
-     * Returns the reflective representation of type <tt>int</tt>.
-     * @return the reflective representation of type <tt>int</tt>.
+     * Returns the reflective representation of type {@code int}.
+     * @return the reflective representation of type {@code int}.
      */
     Type makeInt();
 
     /**
-     * Returns the reflective representation of type <tt>long</tt>.
-     * @return the reflective representation of type <tt>long</tt>.
+     * Returns the reflective representation of type {@code long}.
+     * @return the reflective representation of type {@code long}.
      */
     Type makeLong();
 
     /**
-     * Returns the reflective representation of type <tt>float</tt>.
-     * @return the reflective representation of type <tt>float</tt>.
+     * Returns the reflective representation of type {@code float}.
+     * @return the reflective representation of type {@code float}.
      */
     Type makeFloat();
 
     /**
-     * Returns the reflective representation of type <tt>double</tt>.
-     * @return the reflective representation of type <tt>double</tt>.
+     * Returns the reflective representation of type {@code double}.
+     * @return the reflective representation of type {@code double}.
      */
     Type makeDouble();
 
     /**
-     * Returns the reflective representation of <tt>void</tt>.
-     * @return the reflective representation of <tt>void</tt>.
+     * Returns the reflective representation of {@code void}.
+     * @return the reflective representation of {@code void}.
      */
     Type makeVoid();
 }
--- a/jdk/src/java.base/share/classes/sun/reflect/generics/parser/SignatureParser.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/jdk/src/java.base/share/classes/sun/reflect/generics/parser/SignatureParser.java	Wed Jul 05 20:51:27 2017 +0200
@@ -135,7 +135,7 @@
 
     /**
      * Static factory method. Produces a parser instance.
-     * @return an instance of <tt>SignatureParser</tt>
+     * @return an instance of {@code SignatureParser}
      */
     public static SignatureParser make() {
         return new SignatureParser();
--- a/jdk/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/GenericArrayTypeImpl.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/jdk/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/GenericArrayTypeImpl.java	Wed Jul 05 20:51:27 2017 +0200
@@ -53,10 +53,10 @@
 
 
     /**
-     * Returns a <tt>Type</tt> object representing the component type
+     * Returns a {@code Type} object representing the component type
      * of this array.
      *
-     * @return a <tt>Type</tt> object representing the component type
+     * @return a {@code Type} object representing the component type
      *     of this array
      * @since 1.5
      */
--- a/jdk/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/TypeVariableImpl.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/jdk/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/TypeVariableImpl.java	Wed Jul 05 20:51:27 2017 +0200
@@ -46,7 +46,7 @@
 import sun.reflect.misc.ReflectUtil;
 
 /**
- * Implementation of <tt>java.lang.reflect.TypeVariable</tt> interface
+ * Implementation of {@code java.lang.reflect.TypeVariable} interface
  * for core reflection.
  */
 public class TypeVariableImpl<D extends GenericDeclaration>
@@ -99,9 +99,9 @@
 
 
     /**
-     * Returns an array of <tt>Type</tt> objects representing the
+     * Returns an array of {@code Type} objects representing the
      * upper bound(s) of this type variable.  Note that if no upper bound is
-     * explicitly declared, the upper bound is <tt>Object</tt>.
+     * explicitly declared, the upper bound is {@code Object}.
      *
      * <p>For each upper bound B:
      * <ul>
@@ -111,9 +111,9 @@
      *  <li>Otherwise, B is resolved.
      * </ul>
      *
-     * @throws <tt>TypeNotPresentException</tt> if any of the
+     * @throws {@code TypeNotPresentException} if any of the
      *     bounds refers to a non-existent type declaration
-     * @throws <tt>MalformedParameterizedTypeException</tt> if any of the
+     * @throws {@code MalformedParameterizedTypeException} if any of the
      *     bounds refer to a parameterized type that cannot be instantiated
      *     for any reason
      * @return an array of Types representing the upper bound(s) of this
@@ -129,7 +129,7 @@
     }
 
     /**
-     * Returns the <tt>GenericDeclaration</tt> object representing the
+     * Returns the {@code GenericDeclaration} object representing the
      * generic declaration that declared this type variable.
      *
      * @return the generic declaration that declared this type variable.
--- a/jdk/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/WildcardTypeImpl.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/jdk/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/WildcardTypeImpl.java	Wed Jul 05 20:51:27 2017 +0200
@@ -78,9 +78,9 @@
     }
 
     /**
-     * Returns an array of <tt>Type</tt> objects representing the upper
+     * Returns an array of {@code Type} objects representing the upper
      * bound(s) of this type variable.  Note that if no upper bound is
-     * explicitly declared, the upper bound is <tt>Object</tt>.
+     * explicitly declared, the upper bound is {@code Object}.
      *
      * <p>For each upper bound B :
      * <ul>
@@ -92,9 +92,9 @@
      *
      * @return an array of Types representing the upper bound(s) of this
      *     type variable
-     * @throws <tt>TypeNotPresentException</tt> if any of the
+     * @throws {@code TypeNotPresentException} if any of the
      *     bounds refers to a non-existent type declaration
-     * @throws <tt>MalformedParameterizedTypeException</tt> if any of the
+     * @throws {@code MalformedParameterizedTypeException} if any of the
      *     bounds refer to a parameterized type that cannot be instantiated
      *     for any reason
      */
@@ -108,9 +108,9 @@
     }
 
     /**
-     * Returns an array of <tt>Type</tt> objects representing the
+     * Returns an array of {@code Type} objects representing the
      * lower bound(s) of this type variable.  Note that if no lower bound is
-     * explicitly declared, the lower bound is the type of <tt>null</tt>.
+     * explicitly declared, the lower bound is the type of {@code null}.
      * In this case, a zero length array is returned.
      *
      * <p>For each lower bound B :
@@ -123,9 +123,9 @@
      *
      * @return an array of Types representing the lower bound(s) of this
      *     type variable
-     * @throws <tt>TypeNotPresentException</tt> if any of the
+     * @throws {@code TypeNotPresentException} if any of the
      *     bounds refers to a non-existent type declaration
-     * @throws <tt>MalformedParameterizedTypeException</tt> if any of the
+     * @throws {@code MalformedParameterizedTypeException} if any of the
      *     bounds refer to a parameterized type that cannot be instantiated
      *     for any reason
      */
--- a/jdk/src/java.base/share/classes/sun/reflect/generics/repository/AbstractRepository.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/jdk/src/java.base/share/classes/sun/reflect/generics/repository/AbstractRepository.java	Wed Jul 05 20:51:27 2017 +0200
@@ -48,15 +48,15 @@
     private GenericsFactory getFactory() { return factory;}
 
     /**
-     * Accessor for <tt>tree</tt>.
+     * Accessor for {@code tree}.
      * @return the cached AST this repository holds
      */
     protected T getTree(){ return tree;}
 
     /**
-     * Returns a <tt>Reifier</tt> used to convert parts of the
+     * Returns a {@code Reifier} used to convert parts of the
      * AST into reflective objects.
-     * @return a <tt>Reifier</tt> used to convert parts of the
+     * @return a {@code Reifier} used to convert parts of the
      * AST into reflective objects
      */
     protected Reifier getReifier(){return Reifier.make(getFactory());}
--- a/jdk/src/java.base/share/classes/sun/reflect/generics/repository/ClassRepository.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/jdk/src/java.base/share/classes/sun/reflect/generics/repository/ClassRepository.java	Wed Jul 05 20:51:27 2017 +0200
@@ -63,8 +63,8 @@
      * that this repository is servicing
      * @param f - a factory that will provide instances of reflective
      * objects when this repository converts its AST
-     * @return a <tt>ClassRepository</tt> that manages the generic type
-     * information represented in the signature <tt>rawSig</tt>
+     * @return a {@code ClassRepository} that manages the generic type
+     * information represented in the signature {@code rawSig}
      */
     public static ClassRepository make(String rawSig, GenericsFactory f) {
         return new ClassRepository(rawSig, f);
--- a/jdk/src/java.base/share/classes/sun/reflect/generics/repository/ConstructorRepository.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/jdk/src/java.base/share/classes/sun/reflect/generics/repository/ConstructorRepository.java	Wed Jul 05 20:51:27 2017 +0200
@@ -64,8 +64,8 @@
      * that this repository is servicing
      * @param f - a factory that will provide instances of reflective
      * objects when this repository converts its AST
-     * @return a <tt>ConstructorRepository</tt> that manages the generic type
-     * information represented in the signature <tt>rawSig</tt>
+     * @return a {@code ConstructorRepository} that manages the generic type
+     * information represented in the signature {@code rawSig}
      */
     public static ConstructorRepository make(String rawSig, GenericsFactory f) {
         return new ConstructorRepository(rawSig, f);
--- a/jdk/src/java.base/share/classes/sun/reflect/generics/repository/FieldRepository.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/jdk/src/java.base/share/classes/sun/reflect/generics/repository/FieldRepository.java	Wed Jul 05 20:51:27 2017 +0200
@@ -59,8 +59,8 @@
      * that this repository is servicing
      * @param f - a factory that will provide instances of reflective
      * objects when this repository converts its AST
-     * @return a <tt>FieldRepository</tt> that manages the generic type
-     * information represented in the signature <tt>rawSig</tt>
+     * @return a {@code FieldRepository} that manages the generic type
+     * information represented in the signature {@code rawSig}
      */
     public static FieldRepository make(String rawSig, GenericsFactory f) {
         return new FieldRepository(rawSig, f);
--- a/jdk/src/java.base/share/classes/sun/reflect/generics/repository/MethodRepository.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/jdk/src/java.base/share/classes/sun/reflect/generics/repository/MethodRepository.java	Wed Jul 05 20:51:27 2017 +0200
@@ -53,8 +53,8 @@
      * that this repository is servicing
      * @param f - a factory that will provide instances of reflective
      * objects when this repository converts its AST
-     * @return a <tt>MethodRepository</tt> that manages the generic type
-     * information represented in the signature <tt>rawSig</tt>
+     * @return a {@code MethodRepository} that manages the generic type
+     * information represented in the signature {@code rawSig}
      */
     public static MethodRepository make(String rawSig, GenericsFactory f) {
         return new MethodRepository(rawSig, f);
--- a/jdk/src/java.base/share/classes/sun/reflect/generics/scope/AbstractScope.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/jdk/src/java.base/share/classes/sun/reflect/generics/scope/AbstractScope.java	Wed Jul 05 20:51:27 2017 +0200
@@ -32,10 +32,10 @@
 /**
  * Abstract superclass for lazy scope objects, used when building
  * factories for generic information repositories.
- * The type parameter <tt>D</tt> represents the type of reflective
+ * The type parameter {@code D} represents the type of reflective
  * object whose scope this class is representing.
  * <p> To subclass this, all one needs to do is implement
- * <tt>computeEnclosingScope</tt> and the subclass' constructor.
+ * {@code computeEnclosingScope} and the subclass' constructor.
  */
 public abstract class AbstractScope<D extends GenericDeclaration>
     implements Scope {
@@ -54,9 +54,9 @@
     protected AbstractScope(D decl){ recvr = decl;}
 
     /**
-     * Accessor for the receiver - the object whose scope this <tt>Scope</tt>
+     * Accessor for the receiver - the object whose scope this {@code Scope}
      * object represents.
-     * @return The object whose scope this <tt>Scope</tt> object represents
+     * @return The object whose scope this {@code Scope} object represents
      */
     protected D getRecvr() {return recvr;}
 
--- a/jdk/src/java.base/share/classes/sun/reflect/generics/scope/ClassScope.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/jdk/src/java.base/share/classes/sun/reflect/generics/scope/ClassScope.java	Wed Jul 05 20:51:27 2017 +0200
@@ -73,7 +73,7 @@
     }
 
     /**
-     * Factory method. Takes a <tt>Class</tt> object and creates a
+     * Factory method. Takes a {@code Class} object and creates a
      * scope for it.
      * @param c - a Class whose scope we want to obtain
      * @return The type-variable scope for the class c
--- a/jdk/src/java.base/share/classes/sun/reflect/generics/scope/DummyScope.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/jdk/src/java.base/share/classes/sun/reflect/generics/scope/DummyScope.java	Wed Jul 05 20:51:27 2017 +0200
@@ -29,9 +29,9 @@
 
 /**
  * This class is used to provide enclosing scopes for top level classes.
- * We cannot use <tt>null</tt> to represent such a scope, since the
+ * We cannot use {@code null} to represent such a scope, since the
  * enclosing scope is computed lazily, and so the field storing it is
- * null until it has been computed. Therefore, <tt>null</tt> is reserved
+ * null until it has been computed. Therefore, {@code null} is reserved
  * to represent an as-yet-uncomputed scope, and cannot be used for any
  * other kind of scope.
  */
@@ -53,7 +53,7 @@
 
     /**
      * Lookup a type variable in the scope, using its name. Always returns
-     * <tt>null</tt>.
+     * {@code null}.
      * @param name - the name of the type variable being looked up
      * @return  null
      */
--- a/jdk/src/java.base/share/classes/sun/reflect/generics/scope/MethodScope.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/jdk/src/java.base/share/classes/sun/reflect/generics/scope/MethodScope.java	Wed Jul 05 20:51:27 2017 +0200
@@ -56,7 +56,7 @@
     }
 
     /**
-     * Factory method. Takes a <tt>Method</tt> object and creates a
+     * Factory method. Takes a {@code Method} object and creates a
      * scope for it.
      * @param m - A Method whose scope we want to obtain
      * @return The type-variable scope for the method m
--- a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/TypeTree.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/TypeTree.java	Wed Jul 05 20:51:27 2017 +0200
@@ -33,7 +33,7 @@
 public interface TypeTree extends Tree {
     /**
      * Accept method for the visitor pattern.
-     * @param v - a <tt>TypeTreeVisitor</tt> that will process this
+     * @param v a {@code TypeTreeVisitor} that will process this
      * tree
      */
     void accept(TypeTreeVisitor<?> v);
--- a/jdk/src/java.base/share/classes/sun/reflect/generics/visitor/Reifier.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/jdk/src/java.base/share/classes/sun/reflect/generics/visitor/Reifier.java	Wed Jul 05 20:51:27 2017 +0200
@@ -50,7 +50,7 @@
     /**
      * Factory method. The resulting visitor will convert an AST
      * representing generic signatures into corresponding reflective
-     * objects, using the provided factory, <tt>f</tt>.
+     * objects, using the provided factory, {@code f}.
      * @param f - a factory that can be used to manufacture reflective
      * objects returned by this visitor
      * @return A visitor that can be used to reify ASTs representing
--- a/jdk/src/java.base/share/native/libfdlibm/e_hypot.c	Sat Sep 26 09:22:24 2015 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,128 +0,0 @@
-
-/*
- * Copyright (c) 1998, 2001, Oracle and/or its affiliates. All rights reserved.
- * 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.
- */
-
-/* __ieee754_hypot(x,y)
- *
- * Method :
- *      If (assume round-to-nearest) z=x*x+y*y
- *      has error less than sqrt(2)/2 ulp, than
- *      sqrt(z) has error less than 1 ulp (exercise).
- *
- *      So, compute sqrt(x*x+y*y) with some care as
- *      follows to get the error below 1 ulp:
- *
- *      Assume x>y>0;
- *      (if possible, set rounding to round-to-nearest)
- *      1. if x > 2y  use
- *              x1*x1+(y*y+(x2*(x+x1))) for x*x+y*y
- *      where x1 = x with lower 32 bits cleared, x2 = x-x1; else
- *      2. if x <= 2y use
- *              t1*y1+((x-y)*(x-y)+(t1*y2+t2*y))
- *      where t1 = 2x with lower 32 bits cleared, t2 = 2x-t1,
- *      y1= y with lower 32 bits chopped, y2 = y-y1.
- *
- *      NOTE: scaling may be necessary if some argument is too
- *            large or too tiny
- *
- * Special cases:
- *      hypot(x,y) is INF if x or y is +INF or -INF; else
- *      hypot(x,y) is NAN if x or y is NAN.
- *
- * Accuracy:
- *      hypot(x,y) returns sqrt(x^2+y^2) with error less
- *      than 1 ulps (units in the last place)
- */
-
-#include "fdlibm.h"
-
-#ifdef __STDC__
-        double __ieee754_hypot(double x, double y)
-#else
-        double __ieee754_hypot(x,y)
-        double x, y;
-#endif
-{
-        double a=x,b=y,t1,t2,y1,y2,w;
-        int j,k,ha,hb;
-
-        ha = __HI(x)&0x7fffffff;        /* high word of  x */
-        hb = __HI(y)&0x7fffffff;        /* high word of  y */
-        if(hb > ha) {a=y;b=x;j=ha; ha=hb;hb=j;} else {a=x;b=y;}
-        __HI(a) = ha;   /* a <- |a| */
-        __HI(b) = hb;   /* b <- |b| */
-        if((ha-hb)>0x3c00000) {return a+b;} /* x/y > 2**60 */
-        k=0;
-        if(ha > 0x5f300000) {   /* a>2**500 */
-           if(ha >= 0x7ff00000) {       /* Inf or NaN */
-               w = a+b;                 /* for sNaN */
-               if(((ha&0xfffff)|__LO(a))==0) w = a;
-               if(((hb^0x7ff00000)|__LO(b))==0) w = b;
-               return w;
-           }
-           /* scale a and b by 2**-600 */
-           ha -= 0x25800000; hb -= 0x25800000;  k += 600;
-           __HI(a) = ha;
-           __HI(b) = hb;
-        }
-        if(hb < 0x20b00000) {   /* b < 2**-500 */
-            if(hb <= 0x000fffff) {      /* subnormal b or 0 */
-                if((hb|(__LO(b)))==0) return a;
-                t1=0;
-                __HI(t1) = 0x7fd00000;  /* t1=2^1022 */
-                b *= t1;
-                a *= t1;
-                k -= 1022;
-            } else {            /* scale a and b by 2^600 */
-                ha += 0x25800000;       /* a *= 2^600 */
-                hb += 0x25800000;       /* b *= 2^600 */
-                k -= 600;
-                __HI(a) = ha;
-                __HI(b) = hb;
-            }
-        }
-    /* medium size a and b */
-        w = a-b;
-        if (w>b) {
-            t1 = 0;
-            __HI(t1) = ha;
-            t2 = a-t1;
-            w  = sqrt(t1*t1-(b*(-b)-t2*(a+t1)));
-        } else {
-            a  = a+a;
-            y1 = 0;
-            __HI(y1) = hb;
-            y2 = b - y1;
-            t1 = 0;
-            __HI(t1) = ha+0x00100000;
-            t2 = a - t1;
-            w  = sqrt(t1*y1-(w*(-w)-(t1*y2+t2*b)));
-        }
-        if(k!=0) {
-            t1 = 1.0;
-            __HI(t1) += (k<<20);
-            return t1*w;
-        } else return w;
-}
--- a/jdk/src/java.base/share/native/libfdlibm/w_hypot.c	Sat Sep 26 09:22:24 2015 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-
-/*
- * Copyright (c) 1998, 2001, Oracle and/or its affiliates. All rights reserved.
- * 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.
- */
-
-/*
- * wrapper hypot(x,y)
- */
-
-#include "fdlibm.h"
-
-
-#ifdef __STDC__
-        double hypot(double x, double y)/* wrapper hypot */
-#else
-        double hypot(x,y)               /* wrapper hypot */
-        double x,y;
-#endif
-{
-#ifdef _IEEE_LIBM
-        return __ieee754_hypot(x,y);
-#else
-        double z;
-        z = __ieee754_hypot(x,y);
-        if(_LIB_VERSION == _IEEE_) return z;
-        if((!finite(z))&&finite(x)&&finite(y))
-            return __kernel_standard(x,y,4); /* hypot overflow */
-        else
-            return z;
-#endif
-}
--- a/jdk/src/java.base/share/native/libjava/StrictMath.c	Sat Sep 26 09:22:24 2015 -0700
+++ b/jdk/src/java.base/share/native/libjava/StrictMath.c	Wed Jul 05 20:51:27 2017 +0200
@@ -127,14 +127,6 @@
 }
 
 JNIEXPORT jdouble JNICALL
-Java_java_lang_StrictMath_hypot(JNIEnv *env, jclass unused, jdouble x, jdouble y)
-{
-    return (jdouble) jhypot((double)x, (double)y);
-}
-
-
-
-JNIEXPORT jdouble JNICALL
 Java_java_lang_StrictMath_log1p(JNIEnv *env, jclass unused, jdouble d)
 {
     return (jdouble) jlog1p((double)d);
--- a/jdk/src/java.base/share/native/libjimage/ImageNativeSubstrate.cpp	Sat Sep 26 09:22:24 2015 -0700
+++ b/jdk/src/java.base/share/native/libjimage/ImageNativeSubstrate.cpp	Wed Jul 05 20:51:27 2017 +0200
@@ -4,7 +4,9 @@
  *
  * 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.
+ * 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
@@ -19,7 +21,6 @@
  * 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 <string.h>
--- a/jdk/src/java.base/share/native/libjimage/endian.cpp	Sat Sep 26 09:22:24 2015 -0700
+++ b/jdk/src/java.base/share/native/libjimage/endian.cpp	Wed Jul 05 20:51:27 2017 +0200
@@ -4,11 +4,13 @@
  *
  * 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.
+ * 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
+ * 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).
  *
@@ -19,7 +21,6 @@
  * 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 "endian.hpp"
@@ -27,20 +28,20 @@
 
 // Most modern compilers optimize the bswap routines to native instructions.
 inline static u2 bswap_16(u2 x) {
-  return ((x & 0xFF) << 8) |
-         ((x >> 8) & 0xFF);
+    return ((x & 0xFF) << 8) |
+           ((x >> 8) & 0xFF);
 }
 
 inline static u4 bswap_32(u4 x) {
-  return ((x & 0xFF) << 24) |
-       ((x & 0xFF00) << 8) |
-       ((x >> 8) & 0xFF00) |
-       ((x >> 24) & 0xFF);
+    return ((x & 0xFF) << 24) |
+           ((x & 0xFF00) << 8) |
+           ((x >> 8) & 0xFF00) |
+           ((x >> 24) & 0xFF);
 }
 
 inline static u8 bswap_64(u8 x) {
-  return (u8)bswap_32((u4)x) << 32 |
-         (u8)bswap_32((u4)(x >> 32));
+    return (u8)bswap_32((u4)x) << 32 |
+           (u8)bswap_32((u4)(x >> 32));
 }
 
 u2 NativeEndian::get(u2 x) { return x; }
@@ -76,27 +77,27 @@
 SwappingEndian SwappingEndian::_swapping;
 
 Endian* Endian::get_handler(bool big_endian) {
-  // If requesting little endian on a little endian machine or
-  // big endian on a big endian machine use native handler
-  if (big_endian == is_big_endian()) {
-    return NativeEndian::get_native();
-  } else {
-    // Use swapping handler.
-    return SwappingEndian::get_swapping();
-  }
+    // If requesting little endian on a little endian machine or
+    // big endian on a big endian machine use native handler
+    if (big_endian == is_big_endian()) {
+        return NativeEndian::get_native();
+    } else {
+        // Use swapping handler.
+        return SwappingEndian::get_swapping();
+    }
 }
 
 // Return a platform u2 from an array in which Big Endian is applied.
 u2 Endian::get_java(u1* x) {
-  return (u2) (x[0]<<8 | x[1]);
+    return (u2) (x[0]<<8 | x[1]);
 }
 
 // Add a platform u2 to the array as a Big Endian u2
 void Endian::set_java(u1* p, u2 x) {
-  p[0] = (x >> 8) & 0xff;
-  p[1] = x & 0xff;
+    p[0] = (x >> 8) & 0xff;
+    p[1] = x & 0xff;
 }
 
 Endian* Endian::get_native_handler() {
-  return NativeEndian::get_native();
+    return NativeEndian::get_native();
 }
--- a/jdk/src/java.base/share/native/libjimage/endian.hpp	Sat Sep 26 09:22:24 2015 -0700
+++ b/jdk/src/java.base/share/native/libjimage/endian.hpp	Wed Jul 05 20:51:27 2017 +0200
@@ -4,11 +4,13 @@
  *
  * 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.
+ * 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
+ * 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).
  *
@@ -19,7 +21,6 @@
  * 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 LIBJIMAGE_ENDIAN_HPP
@@ -36,89 +37,89 @@
 // To retrieve a value using the approprate endian, use one of the overloaded
 // calls to get. To set a value, then use one of the overloaded set calls.
 // Ex.
-//      s4 value; // Imported value;
-//      ...
-//      Endian* endian = Endian::get_handler(true);  // Use big endian
-//      s4 corrected = endian->get(value);
-//      endian->set(value, 1);
+//          s4 value; // Imported value;
+//          ...
+//          Endian* endian = Endian::get_handler(true);  // Use big endian
+//          s4 corrected = endian->get(value);
+//          endian->set(value, 1);
 //
 class Endian {
 public:
-  virtual u2 get(u2 x) = 0;
-  virtual u4 get(u4 x) = 0;
-  virtual u8 get(u8 x) = 0;
-  virtual s2 get(s2 x) = 0;
-  virtual s4 get(s4 x) = 0;
-  virtual s8 get(s8 x) = 0;
+    virtual u2 get(u2 x) = 0;
+    virtual u4 get(u4 x) = 0;
+    virtual u8 get(u8 x) = 0;
+    virtual s2 get(s2 x) = 0;
+    virtual s4 get(s4 x) = 0;
+    virtual s8 get(s8 x) = 0;
 
-  virtual void set(u2& x, u2 y) = 0;
-  virtual void set(u4& x, u4 y) = 0;
-  virtual void set(u8& x, u8 y) = 0;
-  virtual void set(s2& x, s2 y) = 0;
-  virtual void set(s4& x, s4 y) = 0;
-  virtual void set(s8& x, s8 y) = 0;
+    virtual void set(u2& x, u2 y) = 0;
+    virtual void set(u4& x, u4 y) = 0;
+    virtual void set(u8& x, u8 y) = 0;
+    virtual void set(s2& x, s2 y) = 0;
+    virtual void set(s4& x, s4 y) = 0;
+    virtual void set(s8& x, s8 y) = 0;
 
-  // Quick little endian test.
-  static bool is_little_endian() {  u4 x = 1; return *(u1 *)&x != 0; }
+    // Quick little endian test.
+    static bool is_little_endian() { u4 x = 1; return *(u1 *)&x != 0; }
 
-  // Quick big endian test.
-  static bool is_big_endian() { return !is_little_endian(); }
+    // Quick big endian test.
+    static bool is_big_endian() { return !is_little_endian(); }
 
-  // Select an appropriate endian handler.
-  static Endian* get_handler(bool big_endian);
+    // Select an appropriate endian handler.
+    static Endian* get_handler(bool big_endian);
 
-  // Return the native endian handler.
-  static Endian* get_native_handler();
+    // Return the native endian handler.
+    static Endian* get_native_handler();
 
-  // get platform u2 from Java Big endian
-  static u2 get_java(u1* x);
-  // set platform u2 to Java Big endian
-  static void set_java(u1* p, u2 x);
+    // get platform u2 from Java Big endian
+    static u2 get_java(u1* x);
+    // set platform u2 to Java Big endian
+    static void set_java(u1* p, u2 x);
 };
 
 // Normal endian handling.
 class NativeEndian : public Endian {
 private:
-  static NativeEndian _native;
+    static NativeEndian _native;
 
 public:
-  u2 get(u2 x);
-  u4 get(u4 x);
-  u8 get(u8 x);
-  s2 get(s2 x);
-  s4 get(s4 x);
-  s8 get(s8 x);
+    u2 get(u2 x);
+    u4 get(u4 x);
+    u8 get(u8 x);
+    s2 get(s2 x);
+    s4 get(s4 x);
+    s8 get(s8 x);
 
-  void set(u2& x, u2 y);
-  void set(u4& x, u4 y);
-  void set(u8& x, u8 y);
-  void set(s2& x, s2 y);
-  void set(s4& x, s4 y);
-  void set(s8& x, s8 y);
+    void set(u2& x, u2 y);
+    void set(u4& x, u4 y);
+    void set(u8& x, u8 y);
+    void set(s2& x, s2 y);
+    void set(s4& x, s4 y);
+    void set(s8& x, s8 y);
 
-  static Endian* get_native() { return &_native; }
+    static Endian* get_native() { return &_native; }
 };
 
 // Swapping endian handling.
 class SwappingEndian : public Endian {
 private:
-  static SwappingEndian _swapping;
+    static SwappingEndian _swapping;
 
 public:
-  u2 get(u2 x);
-  u4 get(u4 x);
-  u8 get(u8 x);
-  s2 get(s2 x);
-  s4 get(s4 x);
-  s8 get(s8 x);
+    u2 get(u2 x);
+    u4 get(u4 x);
+    u8 get(u8 x);
+    s2 get(s2 x);
+    s4 get(s4 x);
+    s8 get(s8 x);
 
-  void set(u2& x, u2 y);
-  void set(u4& x, u4 y);
-  void set(u8& x, u8 y);
-  void set(s2& x, s2 y);
-  void set(s4& x, s4 y);
-  void set(s8& x, s8 y);
+    void set(u2& x, u2 y);
+    void set(u4& x, u4 y);
+    void set(u8& x, u8 y);
+    void set(s2& x, s2 y);
+    void set(s4& x, s4 y);
+    void set(s8& x, s8 y);
 
-  static Endian* get_swapping() { return &_swapping; }
+    static Endian* get_swapping() { return &_swapping; }
 };
 #endif // LIBJIMAGE_ENDIAN_HPP
--- a/jdk/src/java.base/share/native/libjimage/imageDecompressor.cpp	Sat Sep 26 09:22:24 2015 -0700
+++ b/jdk/src/java.base/share/native/libjimage/imageDecompressor.cpp	Wed Jul 05 20:51:27 2017 +0200
@@ -4,11 +4,13 @@
  *
  * 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.
+ * 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
+ * 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).
  *
@@ -19,10 +21,8 @@
  * 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"
 #include "imageDecompressor.hpp"
 #include "endian.hpp"
@@ -32,16 +32,17 @@
 #include <dlfcn.h>
 #endif
 
-typedef jboolean (JNICALL *ZipInflateFully_t)(void *inBuf, jlong inLen, void *outBuf, jlong outLen, char **pmsg);
-static ZipInflateFully_t ZipInflateFully    = NULL;
+typedef jboolean (JNICALL *ZipInflateFully_t)(void *inBuf, jlong inLen,
+                                              void *outBuf, jlong outLen, char **pmsg);
+static ZipInflateFully_t ZipInflateFully        = NULL;
 
 #ifndef WIN32
-  #define JNI_LIB_PREFIX "lib"
-  #ifdef __APPLE__
-    #define JNI_LIB_SUFFIX ".dylib"
-  #else
-    #define JNI_LIB_SUFFIX ".so"
-  #endif
+    #define JNI_LIB_PREFIX "lib"
+    #ifdef __APPLE__
+        #define JNI_LIB_SUFFIX ".dylib"
+    #else
+        #define JNI_LIB_SUFFIX ".so"
+    #endif
 #endif
 
 /**
@@ -50,21 +51,21 @@
  * @return the address of the entry point or NULL
  */
 static void* findEntry(const char* name) {
-  void *addr = NULL;
+    void *addr = NULL;
 #ifdef WIN32
-  HMODULE handle = GetModuleHandle("zip.dll");
-  if (handle == NULL) {
-    return NULL;
-  }
-  addr = (void*) GetProcAddress(handle, name);
-  return addr;
+    HMODULE handle = GetModuleHandle("zip.dll");
+    if (handle == NULL) {
+        return NULL;
+    }
+    addr = (void*) GetProcAddress(handle, name);
+    return addr;
 #else
-  addr = dlopen(JNI_LIB_PREFIX "zip" JNI_LIB_SUFFIX, RTLD_GLOBAL|RTLD_LAZY);
-  if (addr == NULL) {
-    return NULL;
-  }
-  addr = dlsym(addr, name);
-  return addr;
+    addr = dlopen(JNI_LIB_PREFIX "zip" JNI_LIB_SUFFIX, RTLD_GLOBAL|RTLD_LAZY);
+    if (addr == NULL) {
+        return NULL;
+    }
+    addr = dlsym(addr, name);
+    return addr;
 #endif
 }
 
@@ -74,87 +75,87 @@
 int ImageDecompressor::_decompressors_num = 0;
 ImageDecompressor** ImageDecompressor::_decompressors = NULL;
 void ImageDecompressor::image_decompressor_init() {
-  if (_decompressors == NULL) {
-    ZipInflateFully = (ZipInflateFully_t) findEntry("ZIP_InflateFully");
-   assert(ZipInflateFully != NULL && "ZIP decompressor not found.");
-    _decompressors_num = 2;
-    _decompressors = new ImageDecompressor*[_decompressors_num];
-    _decompressors[0] = new ZipDecompressor("zip");
-    _decompressors[1] = new SharedStringDecompressor("compact-cp");
-  }
+    if (_decompressors == NULL) {
+        ZipInflateFully = (ZipInflateFully_t) findEntry("ZIP_InflateFully");
+     assert(ZipInflateFully != NULL && "ZIP decompressor not found.");
+        _decompressors_num = 2;
+        _decompressors = new ImageDecompressor*[_decompressors_num];
+        _decompressors[0] = new ZipDecompressor("zip");
+        _decompressors[1] = new SharedStringDecompressor("compact-cp");
+    }
 }
 
 void ImageDecompressor::image_decompressor_close() {
-  delete _decompressors;
+    delete _decompressors;
 }
 
 /*
  * Locate decompressor.
  */
 ImageDecompressor* ImageDecompressor::get_decompressor(const char * decompressor_name) {
-  image_decompressor_init();
-  for (int i = 0; i < _decompressors_num; i++) {
-    ImageDecompressor* decompressor = _decompressors[i];
-    assert(decompressor != NULL && "Decompressors not initialized.");
-    if (strcmp(decompressor->get_name(), decompressor_name) == 0) {
-      return decompressor;
+    image_decompressor_init();
+    for (int i = 0; i < _decompressors_num; i++) {
+        ImageDecompressor* decompressor = _decompressors[i];
+        assert(decompressor != NULL && "Decompressors not initialized.");
+        if (strcmp(decompressor->get_name(), decompressor_name) == 0) {
+            return decompressor;
+        }
     }
-  }
-  assert(false && "No decompressor found.");
-  return NULL;
+    assert(false && "No decompressor found.");
+    return NULL;
 }
 
 /*
  * Decompression entry point. Called from ImageFileReader::get_resource.
  */
 void ImageDecompressor::decompress_resource(u1* compressed, u1* uncompressed,
-        u4 uncompressed_size, const ImageStrings* strings) {
-  bool has_header = false;
-  u1* decompressed_resource = compressed;
-  u1* compressed_resource = compressed;
+                u4 uncompressed_size, const ImageStrings* strings) {
+    bool has_header = false;
+    u1* decompressed_resource = compressed;
+    u1* compressed_resource = compressed;
 
-  // Resource could have been transformed by a stack of decompressors.
-  // Iterate and decompress resources until there is no more header.
-  do {
-    ResourceHeader _header;
-    memcpy(&_header, compressed_resource, sizeof (ResourceHeader));
-    has_header = _header._magic == ResourceHeader::resource_header_magic;
-    if (has_header) {
-      // decompressed_resource array contains the result of decompression
-      decompressed_resource = new u1[_header._uncompressed_size];
-      // Retrieve the decompressor name
-      const char* decompressor_name = strings->get(_header._decompressor_name_offset);
-      assert(decompressor_name && "image decompressor not found");
-      // Retrieve the decompressor instance
-      ImageDecompressor* decompressor = get_decompressor(decompressor_name);
-      assert(decompressor && "image decompressor not found");
-      u1* compressed_resource_base = compressed_resource;
-      compressed_resource += ResourceHeader::resource_header_length;
-      // Ask the decompressor to decompress the compressed content
-      decompressor->decompress_resource(compressed_resource, decompressed_resource,
-        &_header, strings);
-      if (compressed_resource_base != compressed) {
-        delete compressed_resource_base;
-      }
-      compressed_resource = decompressed_resource;
-    }
-  } while (has_header);
-  memcpy(uncompressed, decompressed_resource, uncompressed_size);
-  delete decompressed_resource;
+    // Resource could have been transformed by a stack of decompressors.
+    // Iterate and decompress resources until there is no more header.
+    do {
+        ResourceHeader _header;
+        memcpy(&_header, compressed_resource, sizeof (ResourceHeader));
+        has_header = _header._magic == ResourceHeader::resource_header_magic;
+        if (has_header) {
+            // decompressed_resource array contains the result of decompression
+            decompressed_resource = new u1[_header._uncompressed_size];
+            // Retrieve the decompressor name
+            const char* decompressor_name = strings->get(_header._decompressor_name_offset);
+            assert(decompressor_name && "image decompressor not found");
+            // Retrieve the decompressor instance
+            ImageDecompressor* decompressor = get_decompressor(decompressor_name);
+            assert(decompressor && "image decompressor not found");
+            u1* compressed_resource_base = compressed_resource;
+            compressed_resource += ResourceHeader::resource_header_length;
+            // Ask the decompressor to decompress the compressed content
+            decompressor->decompress_resource(compressed_resource, decompressed_resource,
+                &_header, strings);
+            if (compressed_resource_base != compressed) {
+                delete compressed_resource_base;
+            }
+            compressed_resource = decompressed_resource;
+        }
+    } while (has_header);
+    memcpy(uncompressed, decompressed_resource, uncompressed_size);
+    delete decompressed_resource;
 }
 
 // Zip decompressor
 
 void ZipDecompressor::decompress_resource(u1* data, u1* uncompressed,
-        ResourceHeader* header, const ImageStrings* strings) {
-  char* msg = NULL;
-  jboolean res = ZipDecompressor::decompress(data, header->_size, uncompressed,
-          header->_uncompressed_size, &msg);
-  assert(res && "decompression failed");
+                ResourceHeader* header, const ImageStrings* strings) {
+    char* msg = NULL;
+    jboolean res = ZipDecompressor::decompress(data, header->_size, uncompressed,
+                    header->_uncompressed_size, &msg);
+    assert(res && "decompression failed");
 }
 
 jboolean ZipDecompressor::decompress(void *in, u8 inSize, void *out, u8 outSize, char **pmsg) {
-  return (*ZipInflateFully)(in, inSize, out, outSize, pmsg);
+    return (*ZipInflateFully)(in, inSize, out, outSize, pmsg);
 }
 
 // END Zip Decompressor
@@ -163,141 +164,143 @@
 
 // array index is the constant pool tag. value is size.
 // eg: array[5]  = 8; means size of long is 8 bytes.
-const u1 SharedStringDecompressor::sizes[] = {0, 0, 0, 4, 4, 8, 8, 2, 2, 4, 4, 4, 4, 0, 0, 3, 2, 0, 4};
+const u1 SharedStringDecompressor::sizes[] = {
+    0, 0, 0, 4, 4, 8, 8, 2, 2, 4, 4, 4, 4, 0, 0, 3, 2, 0, 4
+};
 /**
  * Recreate the class by reconstructing the constant pool.
  */
 void SharedStringDecompressor::decompress_resource(u1* data,
-        u1* uncompressed_resource,
-        ResourceHeader* header, const ImageStrings* strings) {
-  u1* uncompressed_base = uncompressed_resource;
-  u1* data_base = data;
-  int header_size = 8; // magic + major + minor
-  memcpy(uncompressed_resource, data, header_size + 2); //+ cp count
-  uncompressed_resource += header_size + 2;
-  data += header_size;
-  u2 cp_count = Endian::get_java(data);
-  data += 2;
-  for (int i = 1; i < cp_count; i++) {
-    u1 tag = *data;
-    data += 1;
-    switch (tag) {
+                u1* uncompressed_resource,
+                ResourceHeader* header, const ImageStrings* strings) {
+    u1* uncompressed_base = uncompressed_resource;
+    u1* data_base = data;
+    int header_size = 8; // magic + major + minor
+    memcpy(uncompressed_resource, data, header_size + 2); //+ cp count
+    uncompressed_resource += header_size + 2;
+    data += header_size;
+    u2 cp_count = Endian::get_java(data);
+    data += 2;
+    for (int i = 1; i < cp_count; i++) {
+        u1 tag = *data;
+        data += 1;
+        switch (tag) {
 
-      case externalized_string:
-      { // String in Strings table
-        *uncompressed_resource = 1;
-        uncompressed_resource += 1;
-        int i = decompress_int(data);
-        const char * string = strings->get(i);
-        int str_length = (int) strlen(string);
-        Endian::set_java(uncompressed_resource, str_length);
-        uncompressed_resource += 2;
-        memcpy(uncompressed_resource, string, str_length);
-        uncompressed_resource += str_length;
-        break;
-      }
-      // Descriptor String has been split and types added to Strings table
-      case externalized_string_descriptor:
-      {
-        *uncompressed_resource = 1;
-        uncompressed_resource += 1;
-        int descriptor_index = decompress_int(data);
-        int indexes_length = decompress_int(data);
-        u1* length_address = uncompressed_resource;
-        uncompressed_resource += 2;
-        int desc_length = 0;
-        const char * desc_string = strings->get(descriptor_index);
-        if (indexes_length > 0) {
-          u1* indexes_base = data;
-          data += indexes_length;
-          char c = *desc_string;
-          do {
-            *uncompressed_resource = c;
-            uncompressed_resource++;
-            desc_length += 1;
-            /*
-             * Every L character is the marker we are looking at in order
-             * to reconstruct the descriptor. Each time an L is found, then
-             * we retrieve the couple token/token at the current index and
-             * add it to the descriptor.
-             * "(L;I)V" and "java/lang","String" couple of tokens,
-             * this becomes "(Ljava/lang/String;I)V"
-             */
-            if (c == 'L') {
-              int index = decompress_int(indexes_base);
-              const char * pkg = strings->get(index);
-              int str_length = (int) strlen(pkg);
-              // the case where we have a package.
-              // reconstruct the type full name
-              if (str_length > 0) {
-                int len = str_length + 1;
-                char* fullpkg = new char[len];
-                char* pkg_base = fullpkg;
-                memcpy(fullpkg, pkg, str_length);
-                fullpkg += str_length;
-                *fullpkg = '/';
-                memcpy(uncompressed_resource, pkg_base, len);
+            case externalized_string:
+            { // String in Strings table
+                *uncompressed_resource = 1;
+                uncompressed_resource += 1;
+                int i = decompress_int(data);
+                const char * string = strings->get(i);
+                int str_length = (int) strlen(string);
+                Endian::set_java(uncompressed_resource, str_length);
+                uncompressed_resource += 2;
+                memcpy(uncompressed_resource, string, str_length);
+                uncompressed_resource += str_length;
+                break;
+            }
+            // Descriptor String has been split and types added to Strings table
+            case externalized_string_descriptor:
+            {
+                *uncompressed_resource = 1;
+                uncompressed_resource += 1;
+                int descriptor_index = decompress_int(data);
+                int indexes_length = decompress_int(data);
+                u1* length_address = uncompressed_resource;
+                uncompressed_resource += 2;
+                int desc_length = 0;
+                const char * desc_string = strings->get(descriptor_index);
+                if (indexes_length > 0) {
+                    u1* indexes_base = data;
+                    data += indexes_length;
+                    char c = *desc_string;
+                    do {
+                        *uncompressed_resource = c;
+                        uncompressed_resource++;
+                        desc_length += 1;
+                        /*
+                         * Every L character is the marker we are looking at in order
+                         * to reconstruct the descriptor. Each time an L is found, then
+                         * we retrieve the couple token/token at the current index and
+                         * add it to the descriptor.
+                         * "(L;I)V" and "java/lang","String" couple of tokens,
+                         * this becomes "(Ljava/lang/String;I)V"
+                         */
+                        if (c == 'L') {
+                            int index = decompress_int(indexes_base);
+                            const char * pkg = strings->get(index);
+                            int str_length = (int) strlen(pkg);
+                            // the case where we have a package.
+                            // reconstruct the type full name
+                            if (str_length > 0) {
+                                int len = str_length + 1;
+                                char* fullpkg = new char[len];
+                                char* pkg_base = fullpkg;
+                                memcpy(fullpkg, pkg, str_length);
+                                fullpkg += str_length;
+                                *fullpkg = '/';
+                                memcpy(uncompressed_resource, pkg_base, len);
+                                uncompressed_resource += len;
+                                delete pkg_base;
+                                desc_length += len;
+                            } else { // Empty package
+                                // Nothing to do.
+                            }
+                            int classIndex = decompress_int(indexes_base);
+                            const char * clazz = strings->get(classIndex);
+                            int clazz_length = (int) strlen(clazz);
+                            memcpy(uncompressed_resource, clazz, clazz_length);
+                            uncompressed_resource += clazz_length;
+                            desc_length += clazz_length;
+                        }
+                        desc_string += 1;
+                        c = *desc_string;
+                    } while (c != '\0');
+                } else {
+                        desc_length = (int) strlen(desc_string);
+                        memcpy(uncompressed_resource, desc_string, desc_length);
+                        uncompressed_resource += desc_length;
+                }
+                Endian::set_java(length_address, desc_length);
+                break;
+            }
+
+            case constant_utf8:
+            { // UTF-8
+                *uncompressed_resource = tag;
+                uncompressed_resource += 1;
+                u2 str_length = Endian::get_java(data);
+                int len = str_length + 2;
+                memcpy(uncompressed_resource, data, len);
                 uncompressed_resource += len;
-                delete pkg_base;
-                desc_length += len;
-              } else { // Empty package
-                // Nothing to do.
-              }
-              int classIndex = decompress_int(indexes_base);
-              const char * clazz = strings->get(classIndex);
-              int clazz_length = (int) strlen(clazz);
-              memcpy(uncompressed_resource, clazz, clazz_length);
-              uncompressed_resource += clazz_length;
-              desc_length += clazz_length;
+                data += len;
+                break;
             }
-            desc_string += 1;
-            c = *desc_string;
-          } while (c != '\0');
-        } else {
-            desc_length = (int) strlen(desc_string);
-            memcpy(uncompressed_resource, desc_string, desc_length);
-            uncompressed_resource += desc_length;
-        }
-        Endian::set_java(length_address, desc_length);
-        break;
-      }
 
-      case constant_utf8:
-      { // UTF-8
-        *uncompressed_resource = tag;
-        uncompressed_resource += 1;
-        u2 str_length = Endian::get_java(data);
-        int len = str_length + 2;
-        memcpy(uncompressed_resource, data, len);
-        uncompressed_resource += len;
-        data += len;
-        break;
-      }
-
-      case constant_long:
-      case constant_double:
-      {
-        i++;
-      }
-      default:
-      {
-        *uncompressed_resource = tag;
-        uncompressed_resource += 1;
-        int size = sizes[tag];
-        memcpy(uncompressed_resource, data, size);
-        uncompressed_resource += size;
-        data += size;
-      }
+            case constant_long:
+            case constant_double:
+            {
+                i++;
+            }
+            default:
+            {
+                *uncompressed_resource = tag;
+                uncompressed_resource += 1;
+                int size = sizes[tag];
+                memcpy(uncompressed_resource, data, size);
+                uncompressed_resource += size;
+                data += size;
+            }
+        }
     }
-  }
-  u4 remain = header->_size - (int)(data - data_base);
-  u4 computed = (u4)(uncompressed_resource - uncompressed_base) + remain;
-  if (header->_uncompressed_size != computed)
-    printf("Failure, expecting %d but getting %d\n", header->_uncompressed_size,
-        computed);
-  assert(header->_uncompressed_size == computed &&
-        "Constant Pool reconstruction failed");
-  memcpy(uncompressed_resource, data, remain);
+    u4 remain = header->_size - (int)(data - data_base);
+    u4 computed = (u4)(uncompressed_resource - uncompressed_base) + remain;
+    if (header->_uncompressed_size != computed)
+        printf("Failure, expecting %d but getting %d\n", header->_uncompressed_size,
+                computed);
+    assert(header->_uncompressed_size == computed &&
+                "Constant Pool reconstruction failed");
+    memcpy(uncompressed_resource, data, remain);
 }
 
 /*
@@ -308,25 +311,25 @@
  * Example of compression: 1 is compressed on 1 byte: 10100001
  */
 int SharedStringDecompressor::decompress_int(unsigned char*& value) {
-  int len = 4;
-  int res = 0;
-  char b1 = *value;
-  if (is_compressed((signed char)b1)) { // compressed
-    len = get_compressed_length(b1);
-    char clearedValue = b1 &= 0x1F;
-    if (len == 1) {
-      res = clearedValue;
+    int len = 4;
+    int res = 0;
+    char b1 = *value;
+    if (is_compressed((signed char)b1)) { // compressed
+        len = get_compressed_length(b1);
+        char clearedValue = b1 &= 0x1F;
+        if (len == 1) {
+            res = clearedValue;
+        } else {
+            res = (clearedValue & 0xFF) << 8 * (len - 1);
+            for (int i = 1; i < len; i++) {
+                res |= (value[i]&0xFF) << 8 * (len - i - 1);
+            }
+        }
     } else {
-      res = (clearedValue & 0xFF) << 8 * (len - 1);
-      for (int i = 1; i < len; i++) {
-        res |= (value[i]&0xFF) << 8 * (len - i - 1);
-      }
+        res = (value[0] & 0xFF) << 24 | (value[1]&0xFF) << 16 |
+                    (value[2]&0xFF) << 8 | (value[3]&0xFF);
     }
-  } else {
-    res = (value[0] & 0xFF) << 24 | (value[1]&0xFF) << 16 |
-          (value[2]&0xFF) << 8 | (value[3]&0xFF);
-  }
-  value += len;
-  return res;
+    value += len;
+    return res;
 }
 // END Shared String decompressor
--- a/jdk/src/java.base/share/native/libjimage/imageDecompressor.hpp	Sat Sep 26 09:22:24 2015 -0700
+++ b/jdk/src/java.base/share/native/libjimage/imageDecompressor.hpp	Wed Jul 05 20:51:27 2017 +0200
@@ -4,11 +4,13 @@
  *
  * 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.
+ * 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
+ * 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).
  *
@@ -19,7 +21,6 @@
  * 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 LIBJIMAGE_IMAGEDECOMPRESSOR_HPP
@@ -47,16 +48,16 @@
  *   have been used to compress the resource.
  */
 struct ResourceHeader {
-  /* Length of header, needed to retrieve content offset */
-  static const u1 resource_header_length = 21;
-  /* magic bytes that identifies a compressed resource header*/
-  static const u4 resource_header_magic = 0xCAFEFAFA;
-  u4 _magic; // Resource header
-  u4 _size;  // Resource size
-  u4 _uncompressed_size;  // Expected uncompressed size
-  u4 _decompressor_name_offset;  // Strings table decompressor offset
-  u4 _decompressor_config_offset; // Strings table config offset
-  u1 _is_terminal; // Last decompressor 1, otherwise 0.
+    /* Length of header, needed to retrieve content offset */
+    static const u1 resource_header_length = 21;
+    /* magic bytes that identifies a compressed resource header*/
+    static const u4 resource_header_magic = 0xCAFEFAFA;
+    u4 _magic; // Resource header
+    u4 _size;    // Resource size
+    u4 _uncompressed_size;  // Expected uncompressed size
+    u4 _decompressor_name_offset;    // Strings table decompressor offset
+    u4 _decompressor_config_offset; // Strings table config offset
+    u1 _is_terminal; // Last decompressor 1, otherwise 0.
 };
 
 /*
@@ -77,36 +78,36 @@
 class ImageDecompressor {
 
 private:
-  const char* _name;
+    const char* _name;
 
-  /*
-   * Array of concrete decompressors. This array is used to retrieve the decompressor
-   * that can handle resource decompression.
-   */
-  static ImageDecompressor** _decompressors;
-  /**
-   * Num of decompressors
-   */
-  static int _decompressors_num;
-  /*
-   * Identifier of a decompressor. This name is the identification key to retrieve
-   * decompressor from a resource header.
-   */
-  inline const char* get_name() const { return _name; }
+    /*
+     * Array of concrete decompressors. This array is used to retrieve the decompressor
+     * that can handle resource decompression.
+     */
+    static ImageDecompressor** _decompressors;
+    /**
+     * Num of decompressors
+     */
+    static int _decompressors_num;
+    /*
+     * Identifier of a decompressor. This name is the identification key to retrieve
+     * decompressor from a resource header.
+     */
+    inline const char* get_name() const { return _name; }
 
 
 protected:
-  ImageDecompressor(const char* name) : _name(name) {
-  }
-  virtual void decompress_resource(u1* data, u1* uncompressed,
-    ResourceHeader* header, const ImageStrings* strings) = 0;
+    ImageDecompressor(const char* name) : _name(name) {
+    }
+    virtual void decompress_resource(u1* data, u1* uncompressed,
+        ResourceHeader* header, const ImageStrings* strings) = 0;
 
 public:
-  static void image_decompressor_init();
-  static void image_decompressor_close();
-  static ImageDecompressor* get_decompressor(const char * decompressor_name) ;
-  static void decompress_resource(u1* compressed, u1* uncompressed,
-    u4 uncompressed_size, const ImageStrings* strings);
+    static void image_decompressor_init();
+    static void image_decompressor_close();
+    static ImageDecompressor* get_decompressor(const char * decompressor_name) ;
+    static void decompress_resource(u1* compressed, u1* uncompressed,
+        u4 uncompressed_size, const ImageStrings* strings);
 };
 
 /**
@@ -114,10 +115,10 @@
  */
 class ZipDecompressor : public ImageDecompressor {
 public:
-  ZipDecompressor(const char* sym) : ImageDecompressor(sym) { }
-  void decompress_resource(u1* data, u1* uncompressed, ResourceHeader* header,
-    const ImageStrings* strings);
-  static jboolean decompress(void *in, u8 inSize, void *out, u8 outSize, char **pmsg);
+    ZipDecompressor(const char* sym) : ImageDecompressor(sym) { }
+    void decompress_resource(u1* data, u1* uncompressed, ResourceHeader* header,
+        const ImageStrings* strings);
+    static jboolean decompress(void *in, u8 inSize, void *out, u8 outSize, char **pmsg);
 };
 
 /*
@@ -131,32 +132,34 @@
  */
 class SharedStringDecompressor : public ImageDecompressor {
 private:
-  // the constant pool tag for UTF8 string located in strings table
-  static const int externalized_string = 23;
-  // the constant pool tag for UTF8 descriptors string located in strings table
-  static const int externalized_string_descriptor = 25;
-  // the constant pool tag for UTF8
-  static const int constant_utf8 = 1;
-  // the constant pool tag for long
-  static const int constant_long = 5;
-  // the constant pool tag for double
-  static const int constant_double = 6;
-  // array index is the constant pool tag. value is size.
-  // eg: array[5]  = 8; means size of long is 8 bytes.
-  static const u1 sizes[];
-  // bit 5 and 6 are used to store the length of the compressed integer.
-  // size can be 1 (01), 2 (10), 3 (11).
-  // 0x60 ==> 0110000
-  static const int compressed_index_size_mask = 0x60;
-  /*
-   * mask the length bits (5 and 6) and move to the right 5 bits.
-   */
-  inline static int get_compressed_length(char c) { return ((char) (c & compressed_index_size_mask) >> 5); }
-  inline static bool is_compressed(signed char b1) { return b1 < 0; }
-  static int decompress_int(unsigned char*& value);
+    // the constant pool tag for UTF8 string located in strings table
+    static const int externalized_string = 23;
+    // the constant pool tag for UTF8 descriptors string located in strings table
+    static const int externalized_string_descriptor = 25;
+    // the constant pool tag for UTF8
+    static const int constant_utf8 = 1;
+    // the constant pool tag for long
+    static const int constant_long = 5;
+    // the constant pool tag for double
+    static const int constant_double = 6;
+    // array index is the constant pool tag. value is size.
+    // eg: array[5]  = 8; means size of long is 8 bytes.
+    static const u1 sizes[];
+    // bit 5 and 6 are used to store the length of the compressed integer.
+    // size can be 1 (01), 2 (10), 3 (11).
+    // 0x60 ==> 0110000
+    static const int compressed_index_size_mask = 0x60;
+    /*
+     * mask the length bits (5 and 6) and move to the right 5 bits.
+     */
+    inline static int get_compressed_length(char c) {
+        return ((char) (c & compressed_index_size_mask) >> 5);
+    }
+    inline static bool is_compressed(signed char b1) { return b1 < 0; }
+    static int decompress_int(unsigned char*& value);
 public:
-  SharedStringDecompressor(const char* sym) : ImageDecompressor(sym){}
-  void decompress_resource(u1* data, u1* uncompressed, ResourceHeader* header,
-  const ImageStrings* strings);
+    SharedStringDecompressor(const char* sym) : ImageDecompressor(sym){}
+    void decompress_resource(u1* data, u1* uncompressed, ResourceHeader* header,
+    const ImageStrings* strings);
 };
 #endif // LIBJIMAGE_IMAGEDECOMPRESSOR_HPP
--- a/jdk/src/java.base/share/native/libjimage/imageFile.cpp	Sat Sep 26 09:22:24 2015 -0700
+++ b/jdk/src/java.base/share/native/libjimage/imageFile.cpp	Wed Jul 05 20:51:27 2017 +0200
@@ -4,11 +4,13 @@
  *
  * 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.
+ * 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
+ * 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).
  *
@@ -19,7 +21,6 @@
  * 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 <assert.h>
@@ -50,268 +51,268 @@
 
 // Compute the Perfect Hashing hash code for the supplied UTF-8 string.
 s4 ImageStrings::hash_code(const char* string, s4 seed) {
-  // Access bytes as unsigned.
-  u1* bytes = (u1*)string;
-  // Compute hash code.
-  for (u1 byte = *bytes++; byte; byte = *bytes++) {
-    seed = (seed * HASH_MULTIPLIER) ^ byte;
-  }
-  // Ensure the result is not signed.
-  return seed & 0x7FFFFFFF;
+    // Access bytes as unsigned.
+    u1* bytes = (u1*)string;
+    // Compute hash code.
+    for (u1 byte = *bytes++; byte; byte = *bytes++) {
+        seed = (seed * HASH_MULTIPLIER) ^ byte;
+    }
+    // Ensure the result is not signed.
+    return seed & 0x7FFFFFFF;
 }
 
 // Match up a string in a perfect hash table.
 // Returns the index where the name should be.
 // Result still needs validation for precise match (false positive.)
 s4 ImageStrings::find(Endian* endian, const char* name, s4* redirect, u4 length) {
-  // If the table is empty, then short cut.
-  if (!redirect || !length) {
+    // If the table is empty, then short cut.
+    if (!redirect || !length) {
+        return NOT_FOUND;
+    }
+    // Compute the basic perfect hash for name.
+    s4 hash_code = ImageStrings::hash_code(name);
+    // Modulo table size.
+    s4 index = hash_code % length;
+    // Get redirect entry.
+    //   value == 0 then not found
+    //   value < 0 then -1 - value is true index
+    //   value > 0 then value is seed for recomputing hash.
+    s4 value = endian->get(redirect[index]);
+    // if recompute is required.
+    if (value > 0 ) {
+        // Entry collision value, need to recompute hash.
+        hash_code = ImageStrings::hash_code(name, value);
+        // Modulo table size.
+        return hash_code % length;
+    } else if (value < 0) {
+        // Compute direct index.
+        return -1 - value;
+    }
+    // No entry found.
     return NOT_FOUND;
-  }
-  // Compute the basic perfect hash for name.
-  s4 hash_code = ImageStrings::hash_code(name);
-  // Modulo table size.
-  s4 index = hash_code % length;
-  // Get redirect entry.
-  //   value == 0 then not found
-  //   value < 0 then -1 - value is true index
-  //   value > 0 then value is seed for recomputing hash.
-  s4 value = endian->get(redirect[index]);
-  // if recompute is required.
-  if (value > 0 ) {
-    // Entry collision value, need to recompute hash.
-    hash_code = ImageStrings::hash_code(name, value);
-    // Modulo table size.
-    return hash_code % length;
-  } else if (value < 0) {
-    // Compute direct index.
-    return -1 - value;
-  }
-  // No entry found.
-  return NOT_FOUND;
 }
 
 // Test to see if UTF-8 string begins with the start UTF-8 string.  If so,
 // return non-NULL address of remaining portion of string.  Otherwise, return
-// NULL.  Used to test sections of a path without copying from image string
+// NULL.    Used to test sections of a path without copying from image string
 // table.
 const char* ImageStrings::starts_with(const char* string, const char* start) {
-  char ch1, ch2;
-  // Match up the strings the best we can.
-  while ((ch1 = *string) && (ch2 = *start)) {
-    if (ch1 != ch2) {
-      // Mismatch, return NULL.
-      return NULL;
+    char ch1, ch2;
+    // Match up the strings the best we can.
+    while ((ch1 = *string) && (ch2 = *start)) {
+        if (ch1 != ch2) {
+            // Mismatch, return NULL.
+            return NULL;
+        }
+        // Next characters.
+        string++, start++;
     }
-    // Next characters.
-    string++, start++;
-  }
-  // Return remainder of string.
-  return string;
+    // Return remainder of string.
+    return string;
 }
 
 // Inflates the attribute stream into individual values stored in the long
 // array _attributes. This allows an attribute value to be quickly accessed by
 // direct indexing.  Unspecified values default to zero (from constructor.)
 void ImageLocation::set_data(u1* data) {
-  // Deflate the attribute stream into an array of attributes.
-  u1 byte;
-  // Repeat until end header is found.
-  while ((byte = *data)) {
-    // Extract kind from header byte.
-    u1 kind = attribute_kind(byte);
-    assert(kind < ATTRIBUTE_COUNT && "invalid image location attribute");
-    // Extract length of data (in bytes).
-    u1 n = attribute_length(byte);
-    // Read value (most significant first.)
-    _attributes[kind] = attribute_value(data + 1, n);
-    // Position to next attribute by skipping attribute header and data bytes.
-    data += n + 1;
-  }
+    // Deflate the attribute stream into an array of attributes.
+    u1 byte;
+    // Repeat until end header is found.
+    while ((byte = *data)) {
+        // Extract kind from header byte.
+        u1 kind = attribute_kind(byte);
+        assert(kind < ATTRIBUTE_COUNT && "invalid image location attribute");
+        // Extract length of data (in bytes).
+        u1 n = attribute_length(byte);
+        // Read value (most significant first.)
+        _attributes[kind] = attribute_value(data + 1, n);
+        // Position to next attribute by skipping attribute header and data bytes.
+        data += n + 1;
+    }
 }
 
 // Zero all attribute values.
 void ImageLocation::clear_data() {
-  // Set defaults to zero.
-  memset(_attributes, 0, sizeof(_attributes));
+    // Set defaults to zero.
+    memset(_attributes, 0, sizeof(_attributes));
 }
 
 // ImageModuleData constructor maps out sub-tables for faster access.
 ImageModuleData::ImageModuleData(const ImageFileReader* image_file,
-        const char* module_data_name) :
-    _image_file(image_file),
-    _endian(image_file->endian()),
-    _strings(image_file->get_strings()) {
-  // Retrieve the resource containing the module data for the image file.
-  ImageLocation location;
-  bool found = image_file->find_location(module_data_name, location);
-  if (found) {
-    u8 data_size = location.get_attribute(ImageLocation::ATTRIBUTE_UNCOMPRESSED);
-    _data = new u1[(size_t)data_size];
-    _image_file->get_resource(location, _data);
-    // Map out the header.
-    _header = (Header*)_data;
-    // Get the package to module entry count.
-    u4 ptm_count = _header->ptm_count(_endian);
-    // Get the module to package entry count.
-    u4 mtp_count = _header->mtp_count(_endian);
-    // Compute the offset of the package to module perfect hash redirect.
-    u4 ptm_redirect_offset = sizeof(Header);
-    // Compute the offset of the package to module data.
-    u4 ptm_data_offset = ptm_redirect_offset + ptm_count * sizeof(s4);
-    // Compute the offset of the module to package perfect hash redirect.
-    u4 mtp_redirect_offset = ptm_data_offset + ptm_count * sizeof(PTMData);
-    // Compute the offset of the module to package data.
-    u4 mtp_data_offset = mtp_redirect_offset + mtp_count * sizeof(s4);
-    // Compute the offset of the module to package tables.
-    u4 mtp_packages_offset = mtp_data_offset + mtp_count * sizeof(MTPData);
-    // Compute the address of the package to module perfect hash redirect.
-    _ptm_redirect = (s4*)(_data + ptm_redirect_offset);
-    // Compute the address of the package to module data.
-    _ptm_data = (PTMData*)(_data + ptm_data_offset);
-    // Compute the address of the module to package perfect hash redirect.
-    _mtp_redirect = (s4*)(_data + mtp_redirect_offset);
-    // Compute the address of the module to package data.
-    _mtp_data = (MTPData*)(_data + mtp_data_offset);
-    // Compute the address of the module to package tables.
-    _mtp_packages = (s4*)(_data + mtp_packages_offset);
-  } else {
-    // No module data present.
-    _data = NULL;
-    _header = NULL;
-    _ptm_redirect = NULL;
-    _ptm_data = NULL;
-    _mtp_redirect = NULL;
-    _mtp_data = NULL;
-    _mtp_packages = NULL;
-  }
+                const char* module_data_name) :
+        _image_file(image_file),
+        _endian(image_file->endian()),
+        _strings(image_file->get_strings()) {
+    // Retrieve the resource containing the module data for the image file.
+    ImageLocation location;
+    bool found = image_file->find_location(module_data_name, location);
+    if (found) {
+        u8 data_size = location.get_attribute(ImageLocation::ATTRIBUTE_UNCOMPRESSED);
+        _data = new u1[(size_t)data_size];
+        _image_file->get_resource(location, _data);
+        // Map out the header.
+        _header = (Header*)_data;
+        // Get the package to module entry count.
+        u4 ptm_count = _header->ptm_count(_endian);
+        // Get the module to package entry count.
+        u4 mtp_count = _header->mtp_count(_endian);
+        // Compute the offset of the package to module perfect hash redirect.
+        u4 ptm_redirect_offset = sizeof(Header);
+        // Compute the offset of the package to module data.
+        u4 ptm_data_offset = ptm_redirect_offset + ptm_count * sizeof(s4);
+        // Compute the offset of the module to package perfect hash redirect.
+        u4 mtp_redirect_offset = ptm_data_offset + ptm_count * sizeof(PTMData);
+        // Compute the offset of the module to package data.
+        u4 mtp_data_offset = mtp_redirect_offset + mtp_count * sizeof(s4);
+        // Compute the offset of the module to package tables.
+        u4 mtp_packages_offset = mtp_data_offset + mtp_count * sizeof(MTPData);
+        // Compute the address of the package to module perfect hash redirect.
+        _ptm_redirect = (s4*)(_data + ptm_redirect_offset);
+        // Compute the address of the package to module data.
+        _ptm_data = (PTMData*)(_data + ptm_data_offset);
+        // Compute the address of the module to package perfect hash redirect.
+        _mtp_redirect = (s4*)(_data + mtp_redirect_offset);
+        // Compute the address of the module to package data.
+        _mtp_data = (MTPData*)(_data + mtp_data_offset);
+        // Compute the address of the module to package tables.
+        _mtp_packages = (s4*)(_data + mtp_packages_offset);
+    } else {
+        // No module data present.
+        _data = NULL;
+        _header = NULL;
+        _ptm_redirect = NULL;
+        _ptm_data = NULL;
+        _mtp_redirect = NULL;
+        _mtp_data = NULL;
+        _mtp_packages = NULL;
+    }
 }
 
 // Release module data resource.
 ImageModuleData::~ImageModuleData() {
-  if (_data) {
-    delete _data;
-  }
+    if (_data) {
+        delete _data;
+    }
 }
 
 // Return the name of the module data resource.  Ex. "./lib/modules/file.jimage"
 // yields "file.jdata"
 void ImageModuleData::module_data_name(char* buffer, const char* image_file_name) {
-  // Locate the last slash in the file name path.
-  const char* slash = strrchr(image_file_name, FileSeparator);
-  // Trim the path to name and extension.
-  const char* name = slash ? slash + 1 : (char *)image_file_name;
-  // Locate the extension period.
-  const char* dot = strrchr(name, '.');
-  assert(dot && "missing extension on jimage name");
-  // Trim to only base name.
-  int length = (int)(dot - name);
-  strncpy(buffer, name, length);
-  buffer[length] = '\0';
-  // Append extension.
-  strcat(buffer, ".jdata");
+    // Locate the last slash in the file name path.
+    const char* slash = strrchr(image_file_name, FileSeparator);
+    // Trim the path to name and extension.
+    const char* name = slash ? slash + 1 : (char *)image_file_name;
+    // Locate the extension period.
+    const char* dot = strrchr(name, '.');
+    assert(dot && "missing extension on jimage name");
+    // Trim to only base name.
+    int length = (int)(dot - name);
+    strncpy(buffer, name, length);
+    buffer[length] = '\0';
+    // Append extension.
+    strcat(buffer, ".jdata");
 }
 
-// Return the module in which a package resides.  Returns NULL if not found.
+// Return the module in which a package resides.    Returns NULL if not found.
 const char* ImageModuleData::package_to_module(const char* package_name) {
-  // Test files may contain no module data.
-  if (_data != NULL) {
-    // Search the package to module table.
-    s4 index = ImageStrings::find(_endian, package_name, _ptm_redirect,
-                                    _header->ptm_count(_endian));
-    // If entry is found.
-    if (index != ImageStrings::NOT_FOUND) {
-      // Retrieve the package to module entry.
-      PTMData* data = _ptm_data + index;
-      // Verify that it is the correct data.
-      if (strcmp(package_name, get_string(data->name_offset(_endian))) != 0) {
-        return NULL;
-      }
-      // Return the module name.
-      return get_string(data->module_name_offset(_endian));
+    // Test files may contain no module data.
+    if (_data != NULL) {
+        // Search the package to module table.
+        s4 index = ImageStrings::find(_endian, package_name, _ptm_redirect,
+                                      _header->ptm_count(_endian));
+        // If entry is found.
+        if (index != ImageStrings::NOT_FOUND) {
+            // Retrieve the package to module entry.
+            PTMData* data = _ptm_data + index;
+            // Verify that it is the correct data.
+            if (strcmp(package_name, get_string(data->name_offset(_endian))) != 0) {
+                return NULL;
+            }
+            // Return the module name.
+            return get_string(data->module_name_offset(_endian));
+        }
     }
-  }
-  return NULL;
+    return NULL;
 }
 
 // Returns all the package names in a module in a NULL terminated array.
 // Returns NULL if module not found.
 const char** ImageModuleData::module_to_packages(const char* module_name) {
-  // Test files may contain no module data.
-  if (_data != NULL) {
-    // Search the module to package table.
-    s4 index = ImageStrings::find(_endian, module_name, _mtp_redirect,
-                                    _header->mtp_count(_endian));
-    // If entry is found.
-    if (index != ImageStrings::NOT_FOUND) {
-      // Retrieve the module to package entry.
-      MTPData* data = _mtp_data + index;
-      // Verify that it is the correct data.
-      if (strcmp(module_name, get_string(data->name_offset(_endian))) != 0) {
-        return NULL;
-      }
-      // Construct an array of all the package entries.
-      u4 count = data->package_count(_endian);
-      const char** packages = new const char*[count + 1];
-      s4 package_offset = data->package_offset(_endian);
-      for (u4 i = 0; i < count; i++) {
-        u4 package_name_offset = mtp_package(package_offset + i);
-        const char* package_name = get_string(package_name_offset);
-        packages[i] = package_name;
-      }
-      packages[count] = NULL;
-      return packages;
+    // Test files may contain no module data.
+    if (_data != NULL) {
+        // Search the module to package table.
+        s4 index = ImageStrings::find(_endian, module_name, _mtp_redirect,
+                                      _header->mtp_count(_endian));
+        // If entry is found.
+        if (index != ImageStrings::NOT_FOUND) {
+            // Retrieve the module to package entry.
+            MTPData* data = _mtp_data + index;
+            // Verify that it is the correct data.
+            if (strcmp(module_name, get_string(data->name_offset(_endian))) != 0) {
+                return NULL;
+            }
+            // Construct an array of all the package entries.
+            u4 count = data->package_count(_endian);
+            const char** packages = new const char*[count + 1];
+            s4 package_offset = data->package_offset(_endian);
+            for (u4 i = 0; i < count; i++) {
+                u4 package_name_offset = mtp_package(package_offset + i);
+                const char* package_name = get_string(package_name_offset);
+                packages[i] = package_name;
+            }
+            packages[count] = NULL;
+            return packages;
+        }
     }
-  }
-  return NULL;
+    return NULL;
 }
 
 // Manage a table of open image files.  This table allows multiple access points
 // to share an open image.
 ImageFileReaderTable::ImageFileReaderTable() : _count(0), _max(_growth) {
-  _table = new ImageFileReader*[_max];
+    _table = new ImageFileReader*[_max];
 }
 
 ImageFileReaderTable::~ImageFileReaderTable() {
-  delete _table;
+    delete _table;
 }
 
 // Add a new image entry to the table.
 void ImageFileReaderTable::add(ImageFileReader* image) {
-  if (_count == _max) {
-    _max += _growth;
-    _table = static_cast<ImageFileReader**>(realloc(_table, _max * sizeof(ImageFileReader*)));
-  }
-  _table[_count++] = image;
+    if (_count == _max) {
+        _max += _growth;
+        _table = static_cast<ImageFileReader**>(realloc(_table, _max * sizeof(ImageFileReader*)));
+    }
+    _table[_count++] = image;
 }
 
 // Remove an image entry from the table.
 void ImageFileReaderTable::remove(ImageFileReader* image) {
-  s4 last = _count - 1;
-  for (s4 i = 0; _count; i++) {
-    if (_table[i] == image) {
-      if (i != last) {
-        _table[i] = _table[last];
-        _count = last;
-      }
-      break;
+    s4 last = _count - 1;
+    for (s4 i = 0; _count; i++) {
+        if (_table[i] == image) {
+            if (i != last) {
+                _table[i] = _table[last];
+                _count = last;
+            }
+            break;
+        }
     }
-  }
 
-  if (_count != 0 && _count == _max - _growth) {
-    _max -= _growth;
-    _table = static_cast<ImageFileReader**>(realloc(_table, _max * sizeof(ImageFileReader*)));
-  }
+    if (_count != 0 && _count == _max - _growth) {
+        _max -= _growth;
+        _table = static_cast<ImageFileReader**>(realloc(_table, _max * sizeof(ImageFileReader*)));
+    }
 }
 
 // Determine if image entry is in table.
 bool ImageFileReaderTable::contains(ImageFileReader* image) {
-  for (s4 i = 0; _count; i++) {
-    if (_table[i] == image) {
-      return true;
+    for (s4 i = 0; _count; i++) {
+        if (_table[i] == image) {
+            return true;
+        }
     }
-  }
-  return false;
+    return false;
 }
 
 // Table to manage multiple opens of an image file.
@@ -321,362 +322,362 @@
 
 // Open an image file, reuse structure if file already open.
 ImageFileReader* ImageFileReader::open(const char* name, bool big_endian) {
-  {
-    // Lock out _reader_table.
+    {
+        // Lock out _reader_table.
+        SimpleCriticalSectionLock cs(&_reader_table_lock);
+        // Search for an exist image file.
+        for (u4 i = 0; i < _reader_table.count(); i++) {
+            // Retrieve table entry.
+            ImageFileReader* reader = _reader_table.get(i);
+            // If name matches, then reuse (bump up use count.)
+            if (strcmp(reader->name(), name) == 0) {
+                reader->inc_use();
+                return reader;
+            }
+        }
+    } // Unlock the mutex
+
+    // Need a new image reader.
+    ImageFileReader* reader = new ImageFileReader(name, big_endian);
+    bool opened = reader->open();
+    // If failed to open.
+    if (!opened) {
+        delete reader;
+        return NULL;
+    }
+
+    // Lock to update
     SimpleCriticalSectionLock cs(&_reader_table_lock);
     // Search for an exist image file.
     for (u4 i = 0; i < _reader_table.count(); i++) {
-      // Retrieve table entry.
-      ImageFileReader* reader = _reader_table.get(i);
-      // If name matches, then reuse (bump up use count.)
-      if (strcmp(reader->name(), name) == 0) {
-        reader->inc_use();
-        return reader;
-      }
+        // Retrieve table entry.
+        ImageFileReader* existing_reader = _reader_table.get(i);
+        // If name matches, then reuse (bump up use count.)
+        if (strcmp(existing_reader->name(), name) == 0) {
+            existing_reader->inc_use();
+            reader->close();
+            delete reader;
+            return existing_reader;
+        }
     }
-  } // Unlock the mutex
-
-  // Need a new image reader.
-  ImageFileReader* reader = new ImageFileReader(name, big_endian);
-  bool opened = reader->open();
-  // If failed to open.
-  if (!opened) {
-    delete reader;
-    return NULL;
-  }
-
-  // Lock to update
-  SimpleCriticalSectionLock cs(&_reader_table_lock);
-  // Search for an exist image file.
-  for (u4 i = 0; i < _reader_table.count(); i++) {
-    // Retrieve table entry.
-    ImageFileReader* existing_reader = _reader_table.get(i);
-    // If name matches, then reuse (bump up use count.)
-    if (strcmp(existing_reader->name(), name) == 0) {
-      existing_reader->inc_use();
-      reader->close();
-      delete reader;
-      return existing_reader;
-    }
-  }
-  // Bump use count and add to table.
-  reader->inc_use();
-  _reader_table.add(reader);
-  return reader;
+    // Bump use count and add to table.
+    reader->inc_use();
+    _reader_table.add(reader);
+    return reader;
 }
 
 // Close an image file if the file is not in use elsewhere.
 void ImageFileReader::close(ImageFileReader *reader) {
-  // Lock out _reader_table.
-  SimpleCriticalSectionLock cs(&_reader_table_lock);
-  // If last use then remove from table and then close.
-  if (reader->dec_use()) {
-    _reader_table.remove(reader);
-    delete reader;
-  }
+    // Lock out _reader_table.
+    SimpleCriticalSectionLock cs(&_reader_table_lock);
+    // If last use then remove from table and then close.
+    if (reader->dec_use()) {
+        _reader_table.remove(reader);
+        delete reader;
+    }
 }
 
 // Return an id for the specifed ImageFileReader.
 u8 ImageFileReader::readerToID(ImageFileReader *reader) {
-  // ID is just the cloaked reader address.
-  return (u8)reader;
+    // ID is just the cloaked reader address.
+    return (u8)reader;
 }
 
 // Validate the image id.
 bool ImageFileReader::idCheck(u8 id) {
-  // Make sure the ID is a managed (_reader_table) reader.
-  SimpleCriticalSectionLock cs(&_reader_table_lock);
-  return _reader_table.contains((ImageFileReader*)id);
+    // Make sure the ID is a managed (_reader_table) reader.
+    SimpleCriticalSectionLock cs(&_reader_table_lock);
+    return _reader_table.contains((ImageFileReader*)id);
 }
 
 // Return an id for the specifed ImageFileReader.
 ImageFileReader* ImageFileReader::idToReader(u8 id) {
-  assert(idCheck(id) && "invalid image id");
-  return (ImageFileReader*)id;
+    assert(idCheck(id) && "invalid image id");
+    return (ImageFileReader*)id;
 }
 
 // Constructor intializes to a closed state.
 ImageFileReader::ImageFileReader(const char* name, bool big_endian) {
-  // Copy the image file name.
-   int len = (int) strlen(name) + 1;
-  _name = new char[len];
-  strncpy(_name, name, len);
-  // Initialize for a closed file.
-  _fd = -1;
-  _endian = Endian::get_handler(big_endian);
-  _index_data = NULL;
+    // Copy the image file name.
+     int len = (int) strlen(name) + 1;
+    _name = new char[len];
+    strncpy(_name, name, len);
+    // Initialize for a closed file.
+    _fd = -1;
+    _endian = Endian::get_handler(big_endian);
+    _index_data = NULL;
 }
 
 // Close image and free up data structures.
 ImageFileReader::~ImageFileReader() {
-  // Ensure file is closed.
-  close();
-  // Free up name.
-  if (_name) {
-    delete _name;
-    _name = NULL;
-  }
+    // Ensure file is closed.
+    close();
+    // Free up name.
+    if (_name) {
+        delete _name;
+        _name = NULL;
+    }
 }
 
 // Open image file for read access.
 bool ImageFileReader::open() {
-  char buffer[IMAGE_MAX_PATH];
+    char buffer[IMAGE_MAX_PATH];
 
-  // If file exists open for reading.
-  _fd = osSupport::openReadOnly(_name);
-  if (_fd == -1) {
-    return false;
-  }
-  // Retrieve the file size.
-  _file_size = osSupport::size(_name);
-  // Read image file header and verify it has a valid header.
-  size_t header_size = sizeof(ImageHeader);
-  if (_file_size < header_size ||
-    !read_at((u1*)&_header, header_size, 0) ||
-    _header.magic(_endian) != IMAGE_MAGIC ||
-    _header.major_version(_endian) != MAJOR_VERSION ||
-    _header.minor_version(_endian) != MINOR_VERSION) {
-    close();
-    return false;
-  }
-  // Size of image index.
-  _index_size = index_size();
-  // Make sure file is large enough to contain the index.
-  if (_file_size < _index_size) {
-    return false;
-  }
-  // Determine how much of the image is memory mapped.
-  size_t map_size = (size_t)(MemoryMapImage ? _file_size : _index_size);
-  // Memory map image (minimally the index.)
-  _index_data = (u1*)osSupport::map_memory(_fd, _name, 0, map_size);
-  assert(_index_data && "image file not memory mapped");
-  // Retrieve length of index perfect hash table.
-  u4 length = table_length();
-  // Compute offset of the perfect hash table redirect table.
-  u4 redirect_table_offset = (u4)header_size;
-  // Compute offset of index attribute offsets.
-  u4 offsets_table_offset = redirect_table_offset + length * sizeof(s4);
-  // Compute offset of index location attribute data.
-  u4 location_bytes_offset = offsets_table_offset + length * sizeof(u4);
-  // Compute offset of index string table.
-  u4 string_bytes_offset = location_bytes_offset + locations_size();
-  // Compute address of the perfect hash table redirect table.
-  _redirect_table = (s4*)(_index_data + redirect_table_offset);
-  // Compute address of index attribute offsets.
-  _offsets_table = (u4*)(_index_data + offsets_table_offset);
-  // Compute address of index location attribute data.
-  _location_bytes = _index_data + location_bytes_offset;
-  // Compute address of index string table.
-  _string_bytes = _index_data + string_bytes_offset;
+    // If file exists open for reading.
+    _fd = osSupport::openReadOnly(_name);
+    if (_fd == -1) {
+        return false;
+    }
+    // Retrieve the file size.
+    _file_size = osSupport::size(_name);
+    // Read image file header and verify it has a valid header.
+    size_t header_size = sizeof(ImageHeader);
+    if (_file_size < header_size ||
+        !read_at((u1*)&_header, header_size, 0) ||
+        _header.magic(_endian) != IMAGE_MAGIC ||
+        _header.major_version(_endian) != MAJOR_VERSION ||
+        _header.minor_version(_endian) != MINOR_VERSION) {
+        close();
+        return false;
+    }
+    // Size of image index.
+    _index_size = index_size();
+    // Make sure file is large enough to contain the index.
+    if (_file_size < _index_size) {
+        return false;
+    }
+    // Determine how much of the image is memory mapped.
+    size_t map_size = (size_t)(MemoryMapImage ? _file_size : _index_size);
+    // Memory map image (minimally the index.)
+    _index_data = (u1*)osSupport::map_memory(_fd, _name, 0, map_size);
+    assert(_index_data && "image file not memory mapped");
+    // Retrieve length of index perfect hash table.
+    u4 length = table_length();
+    // Compute offset of the perfect hash table redirect table.
+    u4 redirect_table_offset = (u4)header_size;
+    // Compute offset of index attribute offsets.
+    u4 offsets_table_offset = redirect_table_offset + length * sizeof(s4);
+    // Compute offset of index location attribute data.
+    u4 location_bytes_offset = offsets_table_offset + length * sizeof(u4);
+    // Compute offset of index string table.
+    u4 string_bytes_offset = location_bytes_offset + locations_size();
+    // Compute address of the perfect hash table redirect table.
+    _redirect_table = (s4*)(_index_data + redirect_table_offset);
+    // Compute address of index attribute offsets.
+    _offsets_table = (u4*)(_index_data + offsets_table_offset);
+    // Compute address of index location attribute data.
+    _location_bytes = _index_data + location_bytes_offset;
+    // Compute address of index string table.
+    _string_bytes = _index_data + string_bytes_offset;
 
-  // Initialize the module data
-  ImageModuleData::module_data_name(buffer, _name);
-  module_data = new ImageModuleData(this, buffer);
-  // Successful open.
-  return true;
+    // Initialize the module data
+    ImageModuleData::module_data_name(buffer, _name);
+    module_data = new ImageModuleData(this, buffer);
+    // Successful open.
+    return true;
 }
 
 // Close image file.
 void ImageFileReader::close() {
-  // Deallocate the index.
-  if (_index_data) {
-    osSupport::unmap_memory((char*)_index_data, _index_size);
-    _index_data = NULL;
-  }
-  // Close file.
-  if (_fd != -1) {
-    osSupport::close(_fd);
-    _fd = -1;
-  }
+    // Deallocate the index.
+    if (_index_data) {
+        osSupport::unmap_memory((char*)_index_data, _index_size);
+        _index_data = NULL;
+    }
+    // Close file.
+    if (_fd != -1) {
+        osSupport::close(_fd);
+        _fd = -1;
+    }
 }
 
 // Read directly from the file.
 bool ImageFileReader::read_at(u1* data, u8 size, u8 offset) const {
-  return (u8)osSupport::read(_fd, (char*)data, size, offset) == size;
+    return (u8)osSupport::read(_fd, (char*)data, size, offset) == size;
 }
 
-// Find the location attributes associated with the path.  Returns true if
+// Find the location attributes associated with the path.    Returns true if
 // the location is found, false otherwise.
 bool ImageFileReader::find_location(const char* path, ImageLocation& location) const {
-  // Locate the entry in the index perfect hash table.
-  s4 index = ImageStrings::find(_endian, path, _redirect_table, table_length());
-  // If is found.
-  if (index != ImageStrings::NOT_FOUND) {
-    // Get address of first byte of location attribute stream.
-    u1* data = get_location_data(index);
-    // Expand location attributes.
-    location.set_data(data);
-    // Make sure result is not a false positive.
-    return verify_location(location, path);
-  }
-  return false;
+    // Locate the entry in the index perfect hash table.
+    s4 index = ImageStrings::find(_endian, path, _redirect_table, table_length());
+    // If is found.
+    if (index != ImageStrings::NOT_FOUND) {
+        // Get address of first byte of location attribute stream.
+        u1* data = get_location_data(index);
+        // Expand location attributes.
+        location.set_data(data);
+        // Make sure result is not a false positive.
+        return verify_location(location, path);
+    }
+    return false;
 }
 
 // Find the location index and size associated with the path.
 // Returns the location index and size if the location is found, 0 otherwise.
 u4 ImageFileReader::find_location_index(const char* path, u8 *size) const {
-  // Locate the entry in the index perfect hash table.
-  s4 index = ImageStrings::find(_endian, path, _redirect_table, table_length());
-  // If found.
-  if (index != ImageStrings::NOT_FOUND) {
-    // Get address of first byte of location attribute stream.
-    u4 offset = get_location_offset(index);
-    u1* data = get_location_offset_data(offset);
-    // Expand location attributes.
-    ImageLocation location(data);
-    // Make sure result is not a false positive.
-    if (verify_location(location, path)) {
-        *size = (jlong)location.get_attribute(ImageLocation::ATTRIBUTE_UNCOMPRESSED);
-        return offset;
+    // Locate the entry in the index perfect hash table.
+    s4 index = ImageStrings::find(_endian, path, _redirect_table, table_length());
+    // If found.
+    if (index != ImageStrings::NOT_FOUND) {
+        // Get address of first byte of location attribute stream.
+        u4 offset = get_location_offset(index);
+        u1* data = get_location_offset_data(offset);
+        // Expand location attributes.
+        ImageLocation location(data);
+        // Make sure result is not a false positive.
+        if (verify_location(location, path)) {
+                *size = (jlong)location.get_attribute(ImageLocation::ATTRIBUTE_UNCOMPRESSED);
+                return offset;
+        }
     }
-  }
-  return 0;      // not found
+    return 0;            // not found
 }
 
 // Assemble the location path from the string fragments indicated in the location attributes.
 void ImageFileReader::location_path(ImageLocation& location, char* path, size_t max) const {
-  // Manage the image string table.
-  ImageStrings strings(_string_bytes, _header.strings_size(_endian));
-  // Position to first character of the path buffer.
-  char* next = path;
-  // Temp for string length.
-  size_t length;
-  // Get module string.
-  const char* module = location.get_attribute(ImageLocation::ATTRIBUTE_MODULE, strings);
-  // If module string is not empty string.
-  if (*module != '\0') {
-    // Get length of module name.
-    length = strlen(module);
-    // Make sure there is no buffer overflow.
-    assert(next - path + length + 2 < max && "buffer overflow");
-    // Append '/module/'.
-    *next++ = '/';
-    strncpy(next, module, length); next += length;
-    *next++ = '/';
-  }
-  // Get parent (package) string.
-  const char* parent = location.get_attribute(ImageLocation::ATTRIBUTE_PARENT, strings);
-  // If parent string is not empty string.
-  if (*parent != '\0') {
-    // Get length of module string.
-    length = strlen(parent);
+    // Manage the image string table.
+    ImageStrings strings(_string_bytes, _header.strings_size(_endian));
+    // Position to first character of the path buffer.
+    char* next = path;
+    // Temp for string length.
+    size_t length;
+    // Get module string.
+    const char* module = location.get_attribute(ImageLocation::ATTRIBUTE_MODULE, strings);
+    // If module string is not empty string.
+    if (*module != '\0') {
+        // Get length of module name.
+        length = strlen(module);
+        // Make sure there is no buffer overflow.
+        assert(next - path + length + 2 < max && "buffer overflow");
+        // Append '/module/'.
+        *next++ = '/';
+        strncpy(next, module, length); next += length;
+        *next++ = '/';
+    }
+    // Get parent (package) string.
+    const char* parent = location.get_attribute(ImageLocation::ATTRIBUTE_PARENT, strings);
+    // If parent string is not empty string.
+    if (*parent != '\0') {
+        // Get length of module string.
+        length = strlen(parent);
+        // Make sure there is no buffer overflow.
+        assert(next - path + length + 1 < max && "buffer overflow");
+        // Append 'patent/' .
+        strncpy(next, parent, length); next += length;
+        *next++ = '/';
+    }
+    // Get base name string.
+    const char* base = location.get_attribute(ImageLocation::ATTRIBUTE_BASE, strings);
+    // Get length of base name.
+    length = strlen(base);
     // Make sure there is no buffer overflow.
-    assert(next - path + length + 1 < max && "buffer overflow");
-    // Append 'patent/' .
-    strncpy(next, parent, length); next += length;
-    *next++ = '/';
-  }
-  // Get base name string.
-  const char* base = location.get_attribute(ImageLocation::ATTRIBUTE_BASE, strings);
-  // Get length of base name.
-  length = strlen(base);
-  // Make sure there is no buffer overflow.
-  assert(next - path + length < max && "buffer overflow");
-  // Append base name.
-  strncpy(next, base, length); next += length;
-  // Get extension string.
-  const char* extension = location.get_attribute(ImageLocation::ATTRIBUTE_EXTENSION, strings);
-  // If extension string is not empty string.
-  if (*extension != '\0') {
-    // Get length of extension string.
-    length = strlen(extension);
+    assert(next - path + length < max && "buffer overflow");
+    // Append base name.
+    strncpy(next, base, length); next += length;
+    // Get extension string.
+    const char* extension = location.get_attribute(ImageLocation::ATTRIBUTE_EXTENSION, strings);
+    // If extension string is not empty string.
+    if (*extension != '\0') {
+        // Get length of extension string.
+        length = strlen(extension);
+        // Make sure there is no buffer overflow.
+        assert(next - path + length + 1 < max && "buffer overflow");
+        // Append '.extension' .
+        *next++ = '.';
+        strncpy(next, extension, length); next += length;
+    }
     // Make sure there is no buffer overflow.
-    assert(next - path + length + 1 < max && "buffer overflow");
-    // Append '.extension' .
-    *next++ = '.';
-    strncpy(next, extension, length); next += length;
-  }
-  // Make sure there is no buffer overflow.
-  assert((size_t)(next - path) < max && "buffer overflow");
-  // Terminate string.
-  *next = '\0';
+    assert((size_t)(next - path) < max && "buffer overflow");
+    // Terminate string.
+    *next = '\0';
 }
 
 // Verify that a found location matches the supplied path (without copying.)
 bool ImageFileReader::verify_location(ImageLocation& location, const char* path) const {
-  // Manage the image string table.
-  ImageStrings strings(_string_bytes, _header.strings_size(_endian));
-  // Position to first character of the path string.
-  const char* next = path;
-  // Get module name string.
-  const char* module = location.get_attribute(ImageLocation::ATTRIBUTE_MODULE, strings);
-  // If module string is not empty.
-  if (*module != '\0') {
-    // Compare '/module/' .
-    if (*next++ != '/') return false;
-    if (!(next = ImageStrings::starts_with(next, module))) return false;
-    if (*next++ != '/') return false;
-  }
-  // Get parent (package) string
-  const char* parent = location.get_attribute(ImageLocation::ATTRIBUTE_PARENT, strings);
-  // If parent string is not empty string.
-  if (*parent != '\0') {
-    // Compare 'parent/' .
-    if (!(next = ImageStrings::starts_with(next, parent))) return false;
-    if (*next++ != '/') return false;
-  }
-  // Get base name string.
-  const char* base = location.get_attribute(ImageLocation::ATTRIBUTE_BASE, strings);
-  // Compare with basne name.
-  if (!(next = ImageStrings::starts_with(next, base))) return false;
-  // Get extension string.
-  const char* extension = location.get_attribute(ImageLocation::ATTRIBUTE_EXTENSION, strings);
-  // If extension is not empty.
-  if (*extension != '\0') {
-    // Compare '.extension' .
-    if (*next++ != '.') return false;
-    if (!(next = ImageStrings::starts_with(next, extension))) return false;
-  }
-  // True only if complete match and no more characters.
-  return *next == '\0';
+    // Manage the image string table.
+    ImageStrings strings(_string_bytes, _header.strings_size(_endian));
+    // Position to first character of the path string.
+    const char* next = path;
+    // Get module name string.
+    const char* module = location.get_attribute(ImageLocation::ATTRIBUTE_MODULE, strings);
+    // If module string is not empty.
+    if (*module != '\0') {
+        // Compare '/module/' .
+        if (*next++ != '/') return false;
+        if (!(next = ImageStrings::starts_with(next, module))) return false;
+        if (*next++ != '/') return false;
+    }
+    // Get parent (package) string
+    const char* parent = location.get_attribute(ImageLocation::ATTRIBUTE_PARENT, strings);
+    // If parent string is not empty string.
+    if (*parent != '\0') {
+        // Compare 'parent/' .
+        if (!(next = ImageStrings::starts_with(next, parent))) return false;
+        if (*next++ != '/') return false;
+    }
+    // Get base name string.
+    const char* base = location.get_attribute(ImageLocation::ATTRIBUTE_BASE, strings);
+    // Compare with basne name.
+    if (!(next = ImageStrings::starts_with(next, base))) return false;
+    // Get extension string.
+    const char* extension = location.get_attribute(ImageLocation::ATTRIBUTE_EXTENSION, strings);
+    // If extension is not empty.
+    if (*extension != '\0') {
+        // Compare '.extension' .
+        if (*next++ != '.') return false;
+        if (!(next = ImageStrings::starts_with(next, extension))) return false;
+    }
+    // True only if complete match and no more characters.
+    return *next == '\0';
 }
 
 // Return the resource for the supplied location offset.
 void ImageFileReader::get_resource(u4 offset, u1* uncompressed_data) const {
-    // Get address of first byte of location attribute stream.
-    u1* data = get_location_offset_data(offset);
-    // Expand location attributes.
-    ImageLocation location(data);
-    // Read the data
-    get_resource(location, uncompressed_data);
+        // Get address of first byte of location attribute stream.
+        u1* data = get_location_offset_data(offset);
+        // Expand location attributes.
+        ImageLocation location(data);
+        // Read the data
+        get_resource(location, uncompressed_data);
 }
 
 // Return the resource for the supplied location.
 void ImageFileReader::get_resource(ImageLocation& location, u1* uncompressed_data) const {
-  // Retrieve the byte offset and size of the resource.
-  u8 offset = location.get_attribute(ImageLocation::ATTRIBUTE_OFFSET);
-  u8 uncompressed_size = location.get_attribute(ImageLocation::ATTRIBUTE_UNCOMPRESSED);
-  u8 compressed_size = location.get_attribute(ImageLocation::ATTRIBUTE_COMPRESSED);
-  // If the resource is compressed.
-  if (compressed_size != 0) {
-    u1* compressed_data;
-    // If not memory mapped read in bytes.
-    if (!MemoryMapImage) {
-      // Allocate buffer for compression.
-      compressed_data = new u1[(u4)compressed_size];
-      // Read bytes from offset beyond the image index.
-      bool is_read = read_at(compressed_data, compressed_size, _index_size + offset);
-      assert(is_read && "error reading from image or short read");
+    // Retrieve the byte offset and size of the resource.
+    u8 offset = location.get_attribute(ImageLocation::ATTRIBUTE_OFFSET);
+    u8 uncompressed_size = location.get_attribute(ImageLocation::ATTRIBUTE_UNCOMPRESSED);
+    u8 compressed_size = location.get_attribute(ImageLocation::ATTRIBUTE_COMPRESSED);
+    // If the resource is compressed.
+    if (compressed_size != 0) {
+        u1* compressed_data;
+        // If not memory mapped read in bytes.
+        if (!MemoryMapImage) {
+            // Allocate buffer for compression.
+            compressed_data = new u1[(u4)compressed_size];
+            // Read bytes from offset beyond the image index.
+            bool is_read = read_at(compressed_data, compressed_size, _index_size + offset);
+            assert(is_read && "error reading from image or short read");
+        } else {
+            compressed_data = get_data_address() + offset;
+        }
+        // Get image string table.
+        const ImageStrings strings = get_strings();
+        // Decompress resource.
+        ImageDecompressor::decompress_resource(compressed_data, uncompressed_data, (u4)uncompressed_size,
+                        &strings);
+        // If not memory mapped then release temporary buffer.
+        if (!MemoryMapImage) {
+                delete compressed_data;
+        }
     } else {
-      compressed_data = get_data_address() + offset;
+        // Read bytes from offset beyond the image index.
+        bool is_read = read_at(uncompressed_data, uncompressed_size, _index_size + offset);
+        assert(is_read && "error reading from image or short read");
     }
-    // Get image string table.
-    const ImageStrings strings = get_strings();
-    // Decompress resource.
-    ImageDecompressor::decompress_resource(compressed_data, uncompressed_data, (u4)uncompressed_size,
-            &strings);
-    // If not memory mapped then release temporary buffer.
-    if (!MemoryMapImage) {
-        delete compressed_data;
-    }
-  } else {
-    // Read bytes from offset beyond the image index.
-    bool is_read = read_at(uncompressed_data, uncompressed_size, _index_size + offset);
-    assert(is_read && "error reading from image or short read");
-  }
 }
 
 // Return the ImageModuleData for this image
 ImageModuleData * ImageFileReader::get_image_module_data() {
-    return module_data;
+        return module_data;
 }
--- a/jdk/src/java.base/share/native/libjimage/imageFile.hpp	Sat Sep 26 09:22:24 2015 -0700
+++ b/jdk/src/java.base/share/native/libjimage/imageFile.hpp	Wed Jul 05 20:51:27 2017 +0200
@@ -1,14 +1,16 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * 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.
+ * 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
+ * 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).
  *
@@ -19,7 +21,6 @@
  * 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 LIBJIMAGE_IMAGEFILE_HPP
@@ -145,52 +146,52 @@
 // Manage image file string table.
 class ImageStrings {
 private:
-  u1* _data; // Data bytes for strings.
-  u4 _size; // Number of bytes in the string table.
+    u1* _data; // Data bytes for strings.
+    u4 _size;  // Number of bytes in the string table.
 public:
-  enum {
-    // Not found result from find routine.
-    NOT_FOUND = -1,
-    // Prime used to generate hash for Perfect Hashing.
-    HASH_MULTIPLIER = 0x01000193
-  };
+    enum {
+        // Not found result from find routine.
+        NOT_FOUND = -1,
+        // Prime used to generate hash for Perfect Hashing.
+        HASH_MULTIPLIER = 0x01000193
+    };
 
-  ImageStrings(u1* data, u4 size) : _data(data), _size(size) {}
+    ImageStrings(u1* data, u4 size) : _data(data), _size(size) {}
 
-  // Return the UTF-8 string beginning at offset.
-  inline const char* get(u4 offset) const {
-    assert(offset < _size && "offset exceeds string table size");
-    return (const char*)(_data + offset);
-  }
+    // Return the UTF-8 string beginning at offset.
+    inline const char* get(u4 offset) const {
+        assert(offset < _size && "offset exceeds string table size");
+        return (const char*)(_data + offset);
+    }
 
-  // Compute the Perfect Hashing hash code for the supplied UTF-8 string.
-  inline static u4 hash_code(const char* string) {
-    return hash_code(string, HASH_MULTIPLIER);
-  }
+    // Compute the Perfect Hashing hash code for the supplied UTF-8 string.
+    inline static u4 hash_code(const char* string) {
+        return hash_code(string, HASH_MULTIPLIER);
+    }
 
-  // Compute the Perfect Hashing hash code for the supplied string, starting at seed.
-  static s4 hash_code(const char* string, s4 seed);
+    // Compute the Perfect Hashing hash code for the supplied string, starting at seed.
+    static s4 hash_code(const char* string, s4 seed);
 
-  // Match up a string in a perfect hash table.  Result still needs validation
-  // for precise match.
-  static s4 find(Endian* endian, const char* name, s4* redirect, u4 length);
+    // Match up a string in a perfect hash table.    Result still needs validation
+    // for precise match.
+    static s4 find(Endian* endian, const char* name, s4* redirect, u4 length);
 
-  // Test to see if UTF-8 string begins with the start UTF-8 string.  If so,
-  // return non-NULL address of remaining portion of string.  Otherwise, return
-  // NULL.  Used to test sections of a path without copying from image string
-  // table.
-  static const char* starts_with(const char* string, const char* start);
+    // Test to see if UTF-8 string begins with the start UTF-8 string.  If so,
+    // return non-NULL address of remaining portion of string.  Otherwise, return
+    // NULL.    Used to test sections of a path without copying from image string
+    // table.
+    static const char* starts_with(const char* string, const char* start);
 
-  // Test to see if UTF-8 string begins with start char.  If so, return non-NULL
-  // address of remaining portion of string.  Otherwise, return NULL.  Used
-  // to test a character of a path without copying.
-  inline static const char* starts_with(const char* string, const char ch) {
-    return *string == ch ? string + 1 : NULL;
-  }
+    // Test to see if UTF-8 string begins with start char.  If so, return non-NULL
+    // address of remaining portion of string.  Otherwise, return NULL.  Used
+    // to test a character of a path without copying.
+    inline static const char* starts_with(const char* string, const char ch) {
+        return *string == ch ? string + 1 : NULL;
+    }
 };
 
-// Manage image file location attribute data.  Within an image, a location's
-// attributes are compressed into a stream of bytes.  An attribute stream is
+// Manage image file location attribute data.    Within an image, a location's
+// attributes are compressed into a stream of bytes.    An attribute stream is
 // composed of individual attribute sequences.  Each attribute sequence begins with
 // a header byte containing the attribute 'kind' (upper 5 bits of header) and the
 // 'length' less 1 (lower 3 bits of header) of bytes that follow containing the
@@ -208,91 +209,91 @@
 //
 // Notes:
 //  - Even though ATTRIBUTE_END is used to mark the end of the attribute stream,
-//    streams will contain zero byte values to represent lesser significant bits.
-//    Thus, detecting a zero byte is not sufficient to detect the end of an attribute
-//    stream.
+//      streams will contain zero byte values to represent lesser significant bits.
+//      Thus, detecting a zero byte is not sufficient to detect the end of an attribute
+//      stream.
 //  - ATTRIBUTE_OFFSET represents the number of bytes from the beginning of the region
-//    storing the resources.  Thus, in an image this represents the number of bytes
-//    after the index.
+//      storing the resources.  Thus, in an image this represents the number of bytes
+//      after the index.
 //  - Currently, compressed resources are represented by having a non-zero
-//    ATTRIBUTE_COMPRESSED value.  This represents the number of bytes stored in the
-//    image, and the value of ATTRIBUTE_UNCOMPRESSED represents number of bytes of the
-//    inflated resource in memory. If the ATTRIBUTE_COMPRESSED is zero then the value
-//    of ATTRIBUTE_UNCOMPRESSED represents both the number of bytes in the image and
-//    in memory.  In the future, additional compression techniques will be used and
-//    represented differently.
+//      ATTRIBUTE_COMPRESSED value.  This represents the number of bytes stored in the
+//      image, and the value of ATTRIBUTE_UNCOMPRESSED represents number of bytes of the
+//      inflated resource in memory. If the ATTRIBUTE_COMPRESSED is zero then the value
+//      of ATTRIBUTE_UNCOMPRESSED represents both the number of bytes in the image and
+//      in memory.  In the future, additional compression techniques will be used and
+//      represented differently.
 //  - Package strings include trailing slash and extensions include prefix period.
 //
 class ImageLocation {
 public:
-  enum {
-    ATTRIBUTE_END,          // End of attribute stream marker
-    ATTRIBUTE_MODULE,       // String table offset of module name
-    ATTRIBUTE_PARENT,       // String table offset of resource path parent
-    ATTRIBUTE_BASE,         // String table offset of resource path base
-    ATTRIBUTE_EXTENSION,    // String table offset of resource path extension
-    ATTRIBUTE_OFFSET,       // Container byte offset of resource
-    ATTRIBUTE_COMPRESSED,   // In image byte size of the compressed resource
-    ATTRIBUTE_UNCOMPRESSED, // In memory byte size of the uncompressed resource
-    ATTRIBUTE_COUNT         // Number of attribute kinds
-  };
+    enum {
+        ATTRIBUTE_END,                  // End of attribute stream marker
+        ATTRIBUTE_MODULE,               // String table offset of module name
+        ATTRIBUTE_PARENT,               // String table offset of resource path parent
+        ATTRIBUTE_BASE,                 // String table offset of resource path base
+        ATTRIBUTE_EXTENSION,        // String table offset of resource path extension
+        ATTRIBUTE_OFFSET,               // Container byte offset of resource
+        ATTRIBUTE_COMPRESSED,       // In image byte size of the compressed resource
+        ATTRIBUTE_UNCOMPRESSED, // In memory byte size of the uncompressed resource
+        ATTRIBUTE_COUNT                 // Number of attribute kinds
+    };
 
 private:
-  // Values of inflated attributes.
-  u8 _attributes[ATTRIBUTE_COUNT];
+    // Values of inflated attributes.
+    u8 _attributes[ATTRIBUTE_COUNT];
 
-  // Return the attribute value number of bytes.
-  inline static u1 attribute_length(u1 data) {
-    return (data & 0x7) + 1;
-  }
+    // Return the attribute value number of bytes.
+    inline static u1 attribute_length(u1 data) {
+        return (data & 0x7) + 1;
+    }
 
-  // Return the attribute kind.
-  inline static u1 attribute_kind(u1 data) {
-    u1 kind = data >> 3;
-    assert(kind < ATTRIBUTE_COUNT && "invalid attribute kind");
-    return kind;
-  }
+    // Return the attribute kind.
+    inline static u1 attribute_kind(u1 data) {
+        u1 kind = data >> 3;
+        assert(kind < ATTRIBUTE_COUNT && "invalid attribute kind");
+        return kind;
+    }
 
-  // Return the attribute length.
-  inline static u8 attribute_value(u1* data, u1 n) {
-    assert(0 < n && n <= 8 && "invalid attribute value length");
-    u8 value = 0;
-    // Most significant bytes first.
-    for (u1 i = 0; i < n; i++) {
-      value <<= 8;
-      value |= data[i];
+    // Return the attribute length.
+    inline static u8 attribute_value(u1* data, u1 n) {
+        assert(0 < n && n <= 8 && "invalid attribute value length");
+        u8 value = 0;
+        // Most significant bytes first.
+        for (u1 i = 0; i < n; i++) {
+            value <<= 8;
+            value |= data[i];
+        }
+        return value;
     }
-    return value;
-  }
 
 public:
-  ImageLocation() {
-    clear_data();
-  }
+    ImageLocation() {
+        clear_data();
+    }
 
-  ImageLocation(u1* data) {
-    clear_data();
-    set_data(data);
-  }
+    ImageLocation(u1* data) {
+        clear_data();
+        set_data(data);
+    }
 
-  // Inflates the attribute stream into individual values stored in the long
-  // array _attributes. This allows an attribute value to be quickly accessed by
-  // direct indexing. Unspecified values default to zero.
-  void set_data(u1* data);
+    // Inflates the attribute stream into individual values stored in the long
+    // array _attributes. This allows an attribute value to be quickly accessed by
+    // direct indexing. Unspecified values default to zero.
+    void set_data(u1* data);
 
-  // Zero all attribute values.
-  void clear_data();
+    // Zero all attribute values.
+    void clear_data();
 
-  // Retrieve an attribute value from the inflated array.
-  inline u8 get_attribute(u1 kind) const {
-    assert(ATTRIBUTE_END < kind && kind < ATTRIBUTE_COUNT && "invalid attribute kind");
-    return _attributes[kind];
-  }
+    // Retrieve an attribute value from the inflated array.
+    inline u8 get_attribute(u1 kind) const {
+        assert(ATTRIBUTE_END < kind && kind < ATTRIBUTE_COUNT && "invalid attribute kind");
+        return _attributes[kind];
+    }
 
-  // Retrieve an attribute string value from the inflated array.
-  inline const char* get_attribute(u4 kind, const ImageStrings& strings) const {
-    return strings.get((u4)get_attribute(kind));
-  }
+    // Retrieve an attribute string value from the inflated array.
+    inline const char* get_attribute(u4 kind, const ImageStrings& strings) const {
+        return strings.get((u4)get_attribute(kind));
+    }
 };
 
 //
@@ -306,133 +307,133 @@
 // padding for hash table lookup.)
 //
 // Format:
-//    Count of package to module entries
-//    Count of module to package entries
-//    Perfect Hash redirect table[Count of package to module entries]
-//    Package to module entries[Count of package to module entries]
-//        Offset to package name in string table
-//        Offset to module name in string table
-//    Perfect Hash redirect table[Count of module to package entries]
-//    Module to package entries[Count of module to package entries]
-//        Offset to module name in string table
-//        Count of packages in module
-//        Offset to first package in packages table
-//    Packages[]
-//        Offset to package name in string table
+//      Count of package to module entries
+//      Count of module to package entries
+//      Perfect Hash redirect table[Count of package to module entries]
+//      Package to module entries[Count of package to module entries]
+//          Offset to package name in string table
+//          Offset to module name in string table
+//      Perfect Hash redirect table[Count of module to package entries]
+//      Module to package entries[Count of module to package entries]
+//          Offset to module name in string table
+//          Count of packages in module
+//          Offset to first package in packages table
+//      Packages[]
+//          Offset to package name in string table
 //
 // Manage the image module meta data.
 class ImageModuleData {
-  class Header {
-  private:
-    u4 _ptm_count;      // Count of package to module entries
-    u4 _mtp_count;      // Count of module to package entries
-  public:
-    inline u4 ptm_count(Endian* endian) const { return endian->get(_ptm_count); }
-    inline u4 mtp_count(Endian* endian) const { return endian->get(_mtp_count); }
-  };
+    class Header {
+    private:
+        u4 _ptm_count;          // Count of package to module entries
+        u4 _mtp_count;          // Count of module to package entries
+    public:
+        inline u4 ptm_count(Endian* endian) const { return endian->get(_ptm_count); }
+        inline u4 mtp_count(Endian* endian) const { return endian->get(_mtp_count); }
+    };
 
-  // Hashtable entry
-  class HashData {
-  private:
-    u4 _name_offset;    // Name offset in string table
-  public:
-    inline s4 name_offset(Endian* endian) const { return endian->get(_name_offset); }
-  };
+    // Hashtable entry
+    class HashData {
+    private:
+        u4 _name_offset;        // Name offset in string table
+    public:
+        inline s4 name_offset(Endian* endian) const { return endian->get(_name_offset); }
+    };
 
-  // Package to module hashtable entry
-  class PTMData : public HashData {
-  private:
-    u4 _module_name_offset; // Module name offset in string table
-  public:
-    inline s4 module_name_offset(Endian* endian) const { return endian->get(_module_name_offset); }
-  };
+    // Package to module hashtable entry
+    class PTMData : public HashData {
+    private:
+        u4 _module_name_offset; // Module name offset in string table
+    public:
+        inline s4 module_name_offset(Endian* endian) const { return endian->get(_module_name_offset); }
+    };
 
-  // Module to package hashtable entry
-  class MTPData : public HashData {
-  private:
-    u4 _package_count;     // Number of packages in module
-    u4 _package_offset;    // Offset in package list
-  public:
-    inline u4 package_count(Endian* endian)  const { return endian->get(_package_count); }
-    inline u4 package_offset(Endian* endian) const { return endian->get(_package_offset); }
-  };
+    // Module to package hashtable entry
+    class MTPData : public HashData {
+    private:
+        u4 _package_count;       // Number of packages in module
+        u4 _package_offset;      // Offset in package list
+    public:
+        inline u4 package_count(Endian* endian)  const { return endian->get(_package_count); }
+        inline u4 package_offset(Endian* endian) const { return endian->get(_package_offset); }
+    };
 
-  const ImageFileReader* _image_file; // Source image file
-  Endian* _endian;                    // Endian handler
-  ImageStrings _strings;              // Image file strings
-  u1* _data;                          // Module data resource data
-  u8 _data_size;                      // Size of resource data
-  Header* _header;                    // Module data header
-  s4* _ptm_redirect;                  // Package to module hashtable redirect
-  PTMData* _ptm_data;                 // Package to module data
-  s4* _mtp_redirect;                  // Module to packages hashtable redirect
-  MTPData* _mtp_data;                 // Module to packages data
-  s4* _mtp_packages;                  // Package data (name offsets)
+    const ImageFileReader* _image_file; // Source image file
+    Endian* _endian;       // Endian handler
+    ImageStrings _strings; // Image file strings
+    u1* _data;             // Module data resource data
+    u8 _data_size;         // Size of resource data
+    Header* _header;       // Module data header
+    s4* _ptm_redirect;     // Package to module hashtable redirect
+    PTMData* _ptm_data;    // Package to module data
+    s4* _mtp_redirect;     // Module to packages hashtable redirect
+    MTPData* _mtp_data;    // Module to packages data
+    s4* _mtp_packages;     // Package data (name offsets)
 
-  // Return a string from the string table.
-  inline const char* get_string(u4 offset) {
-    return _strings.get(offset);
-  }
+    // Return a string from the string table.
+    inline const char* get_string(u4 offset) {
+        return _strings.get(offset);
+    }
 
-  inline u4 mtp_package(u4 index) {
-    return _endian->get(_mtp_packages[index]);
-  }
+    inline u4 mtp_package(u4 index) {
+        return _endian->get(_mtp_packages[index]);
+    }
 
 public:
-  ImageModuleData(const ImageFileReader* image_file, const char* module_data_name);
-  ~ImageModuleData();
+    ImageModuleData(const ImageFileReader* image_file, const char* module_data_name);
+    ~ImageModuleData();
 
-  // Return the name of the module data resource.
-  static void module_data_name(char* buffer, const char* image_file_name);
+    // Return the name of the module data resource.
+    static void module_data_name(char* buffer, const char* image_file_name);
 
-  // Return the module in which a package resides.  Returns NULL if not found.
-  const char* package_to_module(const char* package_name);
+    // Return the module in which a package resides.    Returns NULL if not found.
+    const char* package_to_module(const char* package_name);
 
-  // Returns all the package names in a module in a NULL terminated array.
-  // Returns NULL if module not found.
-  const char** module_to_packages(const char* module_name);
+    // Returns all the package names in a module in a NULL terminated array.
+    // Returns NULL if module not found.
+    const char** module_to_packages(const char* module_name);
 };
 
 // Image file header, starting at offset 0.
 class ImageHeader {
 private:
-  u4 _magic;           // Image file marker
-  u4 _version;         // Image file major version number
-  u4 _flags;           // Image file flags
-  u4 _resource_count;  // Number of resources in file
-  u4 _table_length;    // Number of slots in index tables
-  u4 _locations_size;  // Number of bytes in attribute table
-  u4 _strings_size;    // Number of bytes in string table
+    u4 _magic;          // Image file marker
+    u4 _version;        // Image file major version number
+    u4 _flags;          // Image file flags
+    u4 _resource_count; // Number of resources in file
+    u4 _table_length;   // Number of slots in index tables
+    u4 _locations_size; // Number of bytes in attribute table
+    u4 _strings_size;   // Number of bytes in string table
 
 public:
-  u4 magic() const { return _magic; }
-  u4 magic(Endian* endian) const { return endian->get(_magic); }
-  void set_magic(Endian* endian, u4 magic) { return endian->set(_magic, magic); }
+    u4 magic() const { return _magic; }
+    u4 magic(Endian* endian) const { return endian->get(_magic); }
+    void set_magic(Endian* endian, u4 magic) { return endian->set(_magic, magic); }
 
-  u4 major_version(Endian* endian) const { return endian->get(_version) >> 16; }
-  u4 minor_version(Endian* endian) const { return endian->get(_version) & 0xFFFF; }
-  void set_version(Endian* endian, u4 major_version, u4 minor_version) {
-    return endian->set(_version, major_version << 16 | minor_version);
-  }
+    u4 major_version(Endian* endian) const { return endian->get(_version) >> 16; }
+    u4 minor_version(Endian* endian) const { return endian->get(_version) & 0xFFFF; }
+    void set_version(Endian* endian, u4 major_version, u4 minor_version) {
+        return endian->set(_version, major_version << 16 | minor_version);
+    }
 
-  u4 flags(Endian* endian) const { return endian->get(_flags); }
-  void set_flags(Endian* endian, u4 value) { return endian->set(_flags, value); }
+    u4 flags(Endian* endian) const { return endian->get(_flags); }
+    void set_flags(Endian* endian, u4 value) { return endian->set(_flags, value); }
 
-  u4 resource_count(Endian* endian) const { return endian->get(_resource_count); }
-  void set_resource_count(Endian* endian, u4 count) { return endian->set(_resource_count, count); }
+    u4 resource_count(Endian* endian) const { return endian->get(_resource_count); }
+    void set_resource_count(Endian* endian, u4 count) { return endian->set(_resource_count, count); }
 
-  u4 table_length(Endian* endian) const { return endian->get(_table_length); }
-  void set_table_length(Endian* endian, u4 count) { return endian->set(_table_length, count); }
+    u4 table_length(Endian* endian) const { return endian->get(_table_length); }
+    void set_table_length(Endian* endian, u4 count) { return endian->set(_table_length, count); }
 
-  u4 locations_size(Endian* endian) const { return endian->get(_locations_size); }
-  void set_locations_size(Endian* endian, u4 size) { return endian->set(_locations_size, size); }
+    u4 locations_size(Endian* endian) const { return endian->get(_locations_size); }
+    void set_locations_size(Endian* endian, u4 size) { return endian->set(_locations_size, size); }
 
-  u4 strings_size(Endian* endian) const { return endian->get(_strings_size); }
-  void set_strings_size(Endian* endian, u4 size) { return endian->set(_strings_size, size); }
+    u4 strings_size(Endian* endian) const { return endian->get(_strings_size); }
+    void set_strings_size(Endian* endian, u4 size) { return endian->set(_strings_size, size); }
 };
 
-// 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.
+// 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.
 #define IMAGE_MAX_PATH 4096
 
 class ImageFileReader;
@@ -441,29 +442,29 @@
 // to share an open image.
 class ImageFileReaderTable {
 private:
-  const static u4 _growth = 8;   // Growth rate of the table
-  u4 _count;                     // Number of entries in the table
-  u4 _max;                       // Maximum number of entries allocated
-  ImageFileReader** _table;      // Growable array of entries
+    const static u4 _growth = 8; // Growth rate of the table
+    u4 _count;                   // Number of entries in the table
+    u4 _max;                     // Maximum number of entries allocated
+    ImageFileReader** _table;    // Growable array of entries
 
 public:
-  ImageFileReaderTable();
-  ~ImageFileReaderTable();
+    ImageFileReaderTable();
+    ~ImageFileReaderTable();
 
-  // Return the number of entries.
-  inline u4 count() { return _count; }
+    // Return the number of entries.
+    inline u4 count() { return _count; }
 
-  // Return the ith entry from the table.
-  inline ImageFileReader* get(u4 i) { return _table[i]; }
+    // Return the ith entry from the table.
+    inline ImageFileReader* get(u4 i) { return _table[i]; }
 
-  // Add a new image entry to the table.
-  void add(ImageFileReader* image);
+    // Add a new image entry to the table.
+    void add(ImageFileReader* image);
 
-  // Remove an image entry from the table.
-  void remove(ImageFileReader* image);
+    // Remove an image entry from the table.
+    void remove(ImageFileReader* image);
 
-  // Determine if image entry is in table.
-  bool contains(ImageFileReader* image);
+    // Determine if image entry is in table.
+    bool contains(ImageFileReader* image);
 };
 
 // Manage the image file.
@@ -473,176 +474,176 @@
 // index is then memory mapped to allow load on demand and sharing.  The
 // -XX:+MemoryMapImage flag determines if the entire file is loaded (server use.)
 // An image can be used by Hotspot and multiple reference points in the JDK, thus
-// it is desirable to share a reader.  To accomodate sharing, a share table is
+// it is desirable to share a reader.    To accomodate sharing, a share table is
 // defined (see ImageFileReaderTable in imageFile.cpp)  To track the number of
 // uses, ImageFileReader keeps a use count (_use).  Use is incremented when
-// 'opened' by reference point and decremented when 'closed'.  Use of zero
+// 'opened' by reference point and decremented when 'closed'.    Use of zero
 // leads the ImageFileReader to be actually closed and discarded.
 class ImageFileReader {
 private:
-  // Manage a number of image files such that an image can be shared across
-  // multiple uses (ex. loader.)
-  static ImageFileReaderTable _reader_table;
+    // Manage a number of image files such that an image can be shared across
+    // multiple uses (ex. loader.)
+    static ImageFileReaderTable _reader_table;
 
-  char* _name;         // Name of image
-  s4 _use;             // Use count
-  int _fd;             // File descriptor
-  Endian* _endian;     // Endian handler
-  u8 _file_size;       // File size in bytes
-  ImageHeader _header; // Image header
-  size_t _index_size;  // Total size of index
-  u1* _index_data;     // Raw index data
-  s4* _redirect_table; // Perfect hash redirect table
-  u4* _offsets_table;  // Location offset table
-  u1* _location_bytes; // Location attributes
-  u1* _string_bytes;   // String table
-  ImageModuleData *module_data;   // The ImageModuleData for this image
+    char* _name;         // Name of image
+    s4 _use;             // Use count
+    int _fd;             // File descriptor
+    Endian* _endian;     // Endian handler
+    u8 _file_size;       // File size in bytes
+    ImageHeader _header; // Image header
+    size_t _index_size;  // Total size of index
+    u1* _index_data;     // Raw index data
+    s4* _redirect_table; // Perfect hash redirect table
+    u4* _offsets_table;  // Location offset table
+    u1* _location_bytes; // Location attributes
+    u1* _string_bytes;   // String table
+    ImageModuleData *module_data;       // The ImageModuleData for this image
 
-  ImageFileReader(const char* name, bool big_endian);
-  ~ImageFileReader();
+    ImageFileReader(const char* name, bool big_endian);
+    ~ImageFileReader();
 
-  // Compute number of bytes in image file index.
-  inline size_t index_size() {
-    return sizeof(ImageHeader) +
-      table_length() * sizeof(u4) * 2 + locations_size() + strings_size();
-  }
+    // Compute number of bytes in image file index.
+    inline size_t index_size() {
+        return sizeof(ImageHeader) +
+            table_length() * sizeof(u4) * 2 + locations_size() + strings_size();
+    }
 
 public:
-  enum {
-    // Image file marker.
-    IMAGE_MAGIC = 0xCAFEDADA,
-    // Endian inverted Image file marker.
-    IMAGE_MAGIC_INVERT = 0xDADAFECA,
-    // Image file major version number.
-    MAJOR_VERSION = 1,
-    // Image file minor version number.
-    MINOR_VERSION = 0
-  };
+    enum {
+        // Image file marker.
+        IMAGE_MAGIC = 0xCAFEDADA,
+        // Endian inverted Image file marker.
+        IMAGE_MAGIC_INVERT = 0xDADAFECA,
+        // Image file major version number.
+        MAJOR_VERSION = 1,
+        // Image file minor version number.
+        MINOR_VERSION = 0
+    };
 
-  // Open an image file, reuse structure if file already open.
-  static ImageFileReader* open(const char* name, bool big_endian = Endian::is_big_endian());
+    // Open an image file, reuse structure if file already open.
+    static ImageFileReader* open(const char* name, bool big_endian = Endian::is_big_endian());
 
-  // Close an image file if the file is not in use elsewhere.
-  static void close(ImageFileReader *reader);
+    // Close an image file if the file is not in use elsewhere.
+    static void close(ImageFileReader *reader);
 
-  // Return an id for the specifed ImageFileReader.
-  static u8 readerToID(ImageFileReader *reader);
+    // Return an id for the specifed ImageFileReader.
+    static u8 readerToID(ImageFileReader *reader);
 
-  // Validate the image id.
-  static bool idCheck(u8 id);
+    // Validate the image id.
+    static bool idCheck(u8 id);
 
-  // Return an id for the specifed ImageFileReader.
-  static ImageFileReader* idToReader(u8 id);
+    // Return an id for the specifed ImageFileReader.
+    static ImageFileReader* idToReader(u8 id);
 
-  // Open image file for read access.
-  bool open();
+    // Open image file for read access.
+    bool open();
 
-  // Close image file.
-  void close();
+    // Close image file.
+    void close();
 
-  // Read directly from the file.
-  bool read_at(u1* data, u8 size, u8 offset) const;
+    // Read directly from the file.
+    bool read_at(u1* data, u8 size, u8 offset) const;
 
-  inline Endian* endian() const { return _endian; }
+    inline Endian* endian() const { return _endian; }
 
-  // Retrieve name of image file.
-  inline const char* name() const {
-    return _name;
-  }
+    // Retrieve name of image file.
+    inline const char* name() const {
+        return _name;
+    }
 
-  // Retrieve size of image file.
-  inline u8 file_size() const {
-    return _file_size;
-  }
+    // Retrieve size of image file.
+    inline u8 file_size() const {
+        return _file_size;
+    }
 
-  // Return first address of index data.
-  inline u1* get_index_address() const {
-    return _index_data;
-  }
+    // Return first address of index data.
+    inline u1* get_index_address() const {
+        return _index_data;
+    }
 
-  // Return first address of resource data.
-  inline u1* get_data_address() const {
-    return _index_data + _index_size;
-  }
+    // Return first address of resource data.
+    inline u1* get_data_address() const {
+        return _index_data + _index_size;
+    }
 
-  // Get the size of the index data.
-  size_t get_index_size() const {
-    return _index_size;
-  }
+    // Get the size of the index data.
+    size_t get_index_size() const {
+        return _index_size;
+    }
 
-  inline u4 table_length() const {
-    return _header.table_length(_endian);
-  }
+    inline u4 table_length() const {
+        return _header.table_length(_endian);
+    }
 
-  inline u4 locations_size() const {
-    return _header.locations_size(_endian);
-  }
+    inline u4 locations_size() const {
+        return _header.locations_size(_endian);
+    }
 
-  inline u4 strings_size()const  {
-    return _header.strings_size(_endian);
-  }
+    inline u4 strings_size()const    {
+        return _header.strings_size(_endian);
+    }
 
-  inline u4* offsets_table() const {
-    return _offsets_table;
-  }
+    inline u4* offsets_table() const {
+        return _offsets_table;
+    }
 
-  // Increment use count.
-  inline void inc_use() {
-    _use++;
-  }
+    // Increment use count.
+    inline void inc_use() {
+        _use++;
+    }
 
-  // Decrement use count.
-  inline bool dec_use() {
-    return --_use == 0;
-  }
+    // Decrement use count.
+    inline bool dec_use() {
+        return --_use == 0;
+    }
 
-  // Return a string table accessor.
-  inline const ImageStrings get_strings() const {
-    return ImageStrings(_string_bytes, _header.strings_size(_endian));
-  }
+    // Return a string table accessor.
+    inline const ImageStrings get_strings() const {
+        return ImageStrings(_string_bytes, _header.strings_size(_endian));
+    }
 
-  // Return location attribute stream at offset.
-  inline u1* get_location_offset_data(u4 offset) const {
-    assert((u4)offset < _header.locations_size(_endian) &&
-              "offset exceeds location attributes size");
-    return offset != 0 ? _location_bytes + offset : NULL;
-  }
+    // Return location attribute stream at offset.
+    inline u1* get_location_offset_data(u4 offset) const {
+        assert((u4)offset < _header.locations_size(_endian) &&
+                            "offset exceeds location attributes size");
+        return offset != 0 ? _location_bytes + offset : NULL;
+    }
 
-  // Return location attribute stream for location i.
-  inline u1* get_location_data(u4 index) const {
-    return get_location_offset_data(get_location_offset(index));
-  }
+    // Return location attribute stream for location i.
+    inline u1* get_location_data(u4 index) const {
+        return get_location_offset_data(get_location_offset(index));
+    }
 
-  // Return the location offset for index.
-  inline u4 get_location_offset(u4 index) const {
-    assert((u4)index < _header.table_length(_endian) &&
-              "index exceeds location count");
-    return _endian->get(_offsets_table[index]);
-  }
+    // Return the location offset for index.
+    inline u4 get_location_offset(u4 index) const {
+        assert((u4)index < _header.table_length(_endian) &&
+                            "index exceeds location count");
+        return _endian->get(_offsets_table[index]);
+    }
 
-  // Find the location attributes associated with the path.  Returns true if
-  // the location is found, false otherwise.
-  bool find_location(const char* path, ImageLocation& location) const;
+    // Find the location attributes associated with the path.    Returns true if
+    // the location is found, false otherwise.
+    bool find_location(const char* path, ImageLocation& location) const;
 
-  // Find the location index and size associated with the path.
-  // Returns the location index and size if the location is found,
-  // ImageFileReader::NOT_FOUND otherwise.
-  u4 find_location_index(const char* path, u8 *size) const;
+    // Find the location index and size associated with the path.
+    // Returns the location index and size if the location is found,
+    // ImageFileReader::NOT_FOUND otherwise.
+    u4 find_location_index(const char* path, u8 *size) const;
 
-  // Assemble the location path.
-  void location_path(ImageLocation& location, char* path, size_t max) const;
+    // Assemble the location path.
+    void location_path(ImageLocation& location, char* path, size_t max) const;
 
-  // Verify that a found location matches the supplied path.
-  bool verify_location(ImageLocation& location, const char* path) const;
+    // Verify that a found location matches the supplied path.
+    bool verify_location(ImageLocation& location, const char* path) const;
 
-  // Return the resource for the supplied location index.
-  void get_resource(u4 index, u1* uncompressed_data) const;
+    // Return the resource for the supplied location index.
+    void get_resource(u4 index, u1* uncompressed_data) const;
 
-  // Return the resource for the supplied path.
-  void get_resource(ImageLocation& location, u1* uncompressed_data) const;
+    // Return the resource for the supplied path.
+    void get_resource(ImageLocation& location, u1* uncompressed_data) const;
 
-  // Return the ImageModuleData for this image
-  ImageModuleData * get_image_module_data();
+    // Return the ImageModuleData for this image
+    ImageModuleData * get_image_module_data();
 
 };
 #endif // LIBJIMAGE_IMAGEFILE_HPP
--- a/jdk/src/java.base/share/native/libjimage/inttypes.hpp	Sat Sep 26 09:22:24 2015 -0700
+++ b/jdk/src/java.base/share/native/libjimage/inttypes.hpp	Wed Jul 05 20:51:27 2017 +0200
@@ -4,7 +4,9 @@
  *
  * 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.
+ * 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
@@ -19,7 +21,6 @@
  * 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 LIBJIMAGE_INTTYPES_HPP
--- a/jdk/src/java.base/share/native/libjimage/jimage.cpp	Sat Sep 26 09:22:24 2015 -0700
+++ b/jdk/src/java.base/share/native/libjimage/jimage.cpp	Wed Jul 05 20:51:27 2017 +0200
@@ -1,10 +1,12 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * 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.
+ * 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
@@ -19,7 +21,6 @@
  * 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 <string.h>
@@ -97,7 +98,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* image,
         const char* module_name, const char* version, const char* name,
@@ -129,7 +131,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);
  */
@@ -148,7 +151,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();
--- a/jdk/src/java.base/share/native/libjimage/jimage.hpp	Sat Sep 26 09:22:24 2015 -0700
+++ b/jdk/src/java.base/share/native/libjimage/jimage.hpp	Wed Jul 05 20:51:27 2017 +0200
@@ -4,7 +4,9 @@
  *
  * 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.
+ * 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
@@ -19,7 +21,6 @@
  * 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"
@@ -111,7 +112,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,
@@ -132,7 +134,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);
  */
@@ -152,7 +155,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();
--- a/jdk/src/java.base/share/native/libjimage/osSupport.hpp	Sat Sep 26 09:22:24 2015 -0700
+++ b/jdk/src/java.base/share/native/libjimage/osSupport.hpp	Wed Jul 05 20:51:27 2017 +0200
@@ -4,7 +4,9 @@
  *
  * 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.
+ * 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
@@ -19,7 +21,6 @@
  * 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 LIBJIMAGE_OSSUPPORT_HPP
--- a/jdk/src/java.base/unix/native/libjimage/osSupport_unix.cpp	Sat Sep 26 09:22:24 2015 -0700
+++ b/jdk/src/java.base/unix/native/libjimage/osSupport_unix.cpp	Wed Jul 05 20:51:27 2017 +0200
@@ -4,7 +4,9 @@
  *
  * 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.
+ * 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
@@ -19,10 +21,8 @@
  * 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 <sys/types.h>
 #include <sys/stat.h>
 #include <sys/mman.h>
--- a/jdk/src/java.base/windows/native/libjimage/osSupport_windows.cpp	Sat Sep 26 09:22:24 2015 -0700
+++ b/jdk/src/java.base/windows/native/libjimage/osSupport_windows.cpp	Wed Jul 05 20:51:27 2017 +0200
@@ -4,7 +4,9 @@
  *
  * 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.
+ * 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
@@ -19,7 +21,6 @@
  * 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 <windows.h>
--- a/jdk/src/java.scripting/share/classes/javax/script/Bindings.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/jdk/src/java.scripting/share/classes/javax/script/Bindings.java	Wed Jul 05 20:51:27 2017 +0200
@@ -28,7 +28,7 @@
 
 /**
  * A mapping of key/value pairs, all of whose keys are
- * <code>Strings</code>.
+ * {@code Strings}.
  *
  * @author Mike Grogan
  * @since 1.6
@@ -49,8 +49,8 @@
     public Object put(String name, Object value);
 
     /**
-     * Adds all the mappings in a given <code>Map</code> to this <code>Bindings</code>.
-     * @param toMerge The <code>Map</code> to merge with this one.
+     * Adds all the mappings in a given {@code Map} to this {@code Bindings}.
+     * @param toMerge The {@code Map} to merge with this one.
      *
      * @throws NullPointerException
      *         if toMerge map is null or if some key in the map is null.
@@ -60,14 +60,14 @@
     public void putAll(Map<? extends String, ? extends Object> toMerge);
 
     /**
-     * Returns <tt>true</tt> if this map contains a mapping for the specified
-     * key.  More formally, returns <tt>true</tt> if and only if
-     * this map contains a mapping for a key <tt>k</tt> such that
-     * <tt>(key==null ? k==null : key.equals(k))</tt>.  (There can be
+     * Returns {@code true} if this map contains a mapping for the specified
+     * key.  More formally, returns {@code true} if and only if
+     * this map contains a mapping for a key {@code k} such that
+     * {@code (key==null ? k==null : key.equals(k))}.  (There can be
      * at most one such mapping.)
      *
      * @param key key whose presence in this map is to be tested.
-     * @return <tt>true</tt> if this map contains a mapping for the specified
+     * @return {@code true} if this map contains a mapping for the specified
      *         key.
      *
      * @throws NullPointerException if key is null
@@ -78,20 +78,21 @@
 
     /**
      * Returns the value to which this map maps the specified key.  Returns
-     * <tt>null</tt> if the map contains no mapping for this key.  A return
-     * value of <tt>null</tt> does not <i>necessarily</i> indicate that the
+     * {@code null} if the map contains no mapping for this key.  A return
+     * value of {@code null} does not <i>necessarily</i> indicate that the
      * map contains no mapping for the key; it's also possible that the map
-     * explicitly maps the key to <tt>null</tt>.  The <tt>containsKey</tt>
+     * explicitly maps the key to {@code null}.  The {@code containsKey}
      * operation may be used to distinguish these two cases.
      *
      * <p>More formally, if this map contains a mapping from a key
-     * <tt>k</tt> to a value <tt>v</tt> such that <tt>(key==null ? k==null :
-     * key.equals(k))</tt>, then this method returns <tt>v</tt>; otherwise
-     * it returns <tt>null</tt>.  (There can be at most one such mapping.)
+     * {@code k} to a value {@code v} such that
+     * {@code (key==null ? k==null : key.equals(k))},
+     * then this method returns {@code v}; otherwise
+     * it returns {@code null}.  (There can be at most one such mapping.)
      *
      * @param key key whose associated value is to be returned.
      * @return the value to which this map maps the specified key, or
-     *         <tt>null</tt> if the map contains no mapping for this key.
+     *         {@code null} if the map contains no mapping for this key.
      *
      * @throws NullPointerException if key is null
      * @throws ClassCastException if key is not String
@@ -102,19 +103,19 @@
     /**
      * Removes the mapping for this key from this map if it is present
      * (optional operation).   More formally, if this map contains a mapping
-     * from key <tt>k</tt> to value <tt>v</tt> such that
-     * <code>(key==null ?  k==null : key.equals(k))</code>, that mapping
+     * from key {@code k} to value {@code v} such that
+     * {@code (key==null ?  k==null : key.equals(k))}, that mapping
      * is removed.  (The map can contain at most one such mapping.)
      *
      * <p>Returns the value to which the map previously associated the key, or
-     * <tt>null</tt> if the map contained no mapping for this key.  (A
-     * <tt>null</tt> return can also indicate that the map previously
-     * associated <tt>null</tt> with the specified key if the implementation
-     * supports <tt>null</tt> values.)  The map will not contain a mapping for
+     * {@code null} if the map contained no mapping for this key.  (A
+     * {@code null} return can also indicate that the map previously
+     * associated {@code null} with the specified key if the implementation
+     * supports {@code null} values.)  The map will not contain a mapping for
      * the specified  key once the call returns.
      *
      * @param key key whose mapping is to be removed from the map.
-     * @return previous value associated with specified key, or <tt>null</tt>
+     * @return previous value associated with specified key, or {@code null}
      *         if there was no mapping for key.
      *
      * @throws NullPointerException if key is null
--- a/jdk/src/java.scripting/share/classes/javax/script/SimpleBindings.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/jdk/src/java.scripting/share/classes/javax/script/SimpleBindings.java	Wed Jul 05 20:51:27 2017 +0200
@@ -32,7 +32,7 @@
 
 /**
  * A simple implementation of Bindings backed by
- * a <code>HashMap</code> or some other specified <code>Map</code>.
+ * a {@code HashMap} or some other specified {@code Map}.
  *
  * @author Mike Grogan
  * @since 1.6
@@ -40,13 +40,13 @@
 public class SimpleBindings implements Bindings {
 
     /**
-     * The <code>Map</code> field stores the attributes.
+     * The {@code Map} field stores the attributes.
      */
     private Map<String,Object> map;
 
     /**
-     * Constructor uses an existing <code>Map</code> to store the values.
-     * @param m The <code>Map</code> backing this <code>SimpleBindings</code>.
+     * Constructor uses an existing {@code Map} to store the values.
+     * @param m The {@code Map} backing this {@code SimpleBindings}.
      * @throws NullPointerException if m is null
      */
     public SimpleBindings(Map<String,Object> m) {
@@ -57,14 +57,14 @@
     }
 
     /**
-     * Default constructor uses a <code>HashMap</code>.
+     * Default constructor uses a {@code HashMap}.
      */
     public SimpleBindings() {
         this(new HashMap<String,Object>());
     }
 
     /**
-     * Sets the specified key/value in the underlying <code>map</code> field.
+     * Sets the specified key/value in the underlying {@code map} field.
      *
      * @param name Name of value
      * @param value Value to set.
@@ -81,9 +81,9 @@
     }
 
     /**
-     * <code>putAll</code> is implemented using <code>Map.putAll</code>.
+     * {@code putAll} is implemented using {@code Map.putAll}.
      *
-     * @param toMerge The <code>Map</code> of values to add.
+     * @param toMerge The {@code Map} of values to add.
      *
      * @throws NullPointerException
      *         if toMerge map is null or if some key in the map is null.
@@ -107,14 +107,14 @@
     }
 
     /**
-     * Returns <tt>true</tt> if this map contains a mapping for the specified
-     * key.  More formally, returns <tt>true</tt> if and only if
-     * this map contains a mapping for a key <tt>k</tt> such that
-     * <tt>(key==null ? k==null : key.equals(k))</tt>.  (There can be
+     * Returns {@code true} if this map contains a mapping for the specified
+     * key.  More formally, returns {@code true} if and only if
+     * this map contains a mapping for a key {@code k} such that
+     * {@code (key==null ? k==null : key.equals(k))}.  (There can be
      * at most one such mapping.)
      *
      * @param key key whose presence in this map is to be tested.
-     * @return <tt>true</tt> if this map contains a mapping for the specified
+     * @return {@code true} if this map contains a mapping for the specified
      *         key.
      *
      * @throws NullPointerException if key is null
@@ -138,20 +138,21 @@
 
     /**
      * Returns the value to which this map maps the specified key.  Returns
-     * <tt>null</tt> if the map contains no mapping for this key.  A return
-     * value of <tt>null</tt> does not <i>necessarily</i> indicate that the
+     * {@code null} if the map contains no mapping for this key.  A return
+     * value of {@code null} does not <i>necessarily</i> indicate that the
      * map contains no mapping for the key; it's also possible that the map
-     * explicitly maps the key to <tt>null</tt>.  The <tt>containsKey</tt>
+     * explicitly maps the key to {@code null}.  The {@code containsKey}
      * operation may be used to distinguish these two cases.
      *
      * <p>More formally, if this map contains a mapping from a key
-     * <tt>k</tt> to a value <tt>v</tt> such that <tt>(key==null ? k==null :
-     * key.equals(k))</tt>, then this method returns <tt>v</tt>; otherwise
-     * it returns <tt>null</tt>.  (There can be at most one such mapping.)
+     * {@code k} to a value {@code v} such that
+     * {@code (key==null ? k==null : key.equals(k))},
+     * then this method returns {@code v}; otherwise
+     * it returns {@code null}.  (There can be at most one such mapping.)
      *
      * @param key key whose associated value is to be returned.
      * @return the value to which this map maps the specified key, or
-     *         <tt>null</tt> if the map contains no mapping for this key.
+     *         {@code null} if the map contains no mapping for this key.
      *
      * @throws NullPointerException if key is null
      * @throws ClassCastException if key is not String
@@ -175,19 +176,19 @@
     /**
      * Removes the mapping for this key from this map if it is present
      * (optional operation).   More formally, if this map contains a mapping
-     * from key <tt>k</tt> to value <tt>v</tt> such that
-     * <code>(key==null ?  k==null : key.equals(k))</code>, that mapping
+     * from key {@code k} to value {@code v} such that
+     * {@code (key==null ?  k==null : key.equals(k))}, that mapping
      * is removed.  (The map can contain at most one such mapping.)
      *
      * <p>Returns the value to which the map previously associated the key, or
-     * <tt>null</tt> if the map contained no mapping for this key.  (A
-     * <tt>null</tt> return can also indicate that the map previously
-     * associated <tt>null</tt> with the specified key if the implementation
-     * supports <tt>null</tt> values.)  The map will not contain a mapping for
+     * {@code null} if the map contained no mapping for this key.  (A
+     * {@code null} return can also indicate that the map previously
+     * associated {@code null} with the specified key if the implementation
+     * supports {@code null} values.)  The map will not contain a mapping for
      * the specified  key once the call returns.
      *
      * @param key key whose mapping is to be removed from the map.
-     * @return previous value associated with specified key, or <tt>null</tt>
+     * @return previous value associated with specified key, or {@code null}
      *         if there was no mapping for key.
      *
      * @throws NullPointerException if key is null
--- a/jdk/src/jdk.jconsole/share/classes/com/sun/tools/jconsole/JConsolePlugin.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/jdk/src/jdk.jconsole/share/classes/com/sun/tools/jconsole/JConsolePlugin.java	Wed Jul 05 20:51:27 2017 +0200
@@ -54,7 +54,7 @@
  * <blockquote><pre>
  * jconsole -pluginpath &lt;plugin-path&gt; </pre></blockquote>
  *
- * <p> where <tt>&lt;plugin-path&gt;</tt> specifies the paths of JConsole
+ * <p> where {@code <plugin-path>} specifies the paths of JConsole
  * plugins to look up which can be a directory or a jar file. Multiple
  * paths are separated by the path separator character of the platform.
  *
@@ -106,7 +106,7 @@
 
     /**
      * Returns the {@link JConsoleContext JConsoleContext} object representing
-     * the connection to an application.  This method may return <tt>null</tt>
+     * the connection to an application.  This method may return {@code null}
      * if it is called before the {@link #setContext context} is initialized.
      *
      * @return the {@link JConsoleContext JConsoleContext} object representing
@@ -146,24 +146,24 @@
      * method to schedule the returned {@code SwingWorker} for execution
      * if:
      * <ul>
-     *   <li> the <tt>SwingWorker</tt> object has not been executed
+     *   <li> the {@code SwingWorker} object has not been executed
      *        (i.e. the {@link SwingWorker#getState} method
      *        returns {@link javax.swing.SwingWorker.StateValue#PENDING PENDING}
      *        state); and</li>
-     *   <li> the <tt>SwingWorker</tt> object returned in the previous
-     *        update has completed the task if it was not <tt>null</tt>
+     *   <li> the {@code SwingWorker} object returned in the previous
+     *        update has completed the task if it was not {@code null}
      *        (i.e. the {@link SwingWorker#isDone SwingWorker.isDone} method
-     *        returns <tt>true</tt>).</li>
+     *        returns {@code true}).</li>
      * </ul>
      * <br>
-     * Otherwise, <tt>SwingWorker</tt> object will not be scheduled to work.
+     * Otherwise, {@code SwingWorker} object will not be scheduled to work.
      *
      * <p>
      * A plugin can schedule its own GUI update and this method
-     * will return <tt>null</tt>.
+     * will return {@code null}.
      *
-     * @return a <tt>SwingWorker</tt> to perform the GUI update; or
-     *         <tt>null</tt>.
+     * @return a {@code SwingWorker} to perform the GUI update; or
+     *         {@code null}.
      */
     public abstract SwingWorker<?,?> newSwingWorker();
 
--- a/jdk/src/jdk.jconsole/share/classes/sun/tools/jconsole/ProxyClient.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/jdk/src/jdk.jconsole/share/classes/sun/tools/jconsole/ProxyClient.java	Wed Jul 05 20:51:27 2017 +0200
@@ -581,7 +581,7 @@
 
     /**
      * Returns a map of MBeans with ObjectName as the key and MBeanInfo value
-     * of a given domain.  If domain is <tt>null</tt>, all MBeans
+     * of a given domain.  If domain is {@code null}, all MBeans
      * are returned.  If no MBean found, an empty map is returned.
      *
      */
--- a/jdk/src/jdk.rmic/share/classes/sun/tools/java/ClassDefinition.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/jdk/src/jdk.rmic/share/classes/sun/tools/java/ClassDefinition.java	Wed Jul 05 20:51:27 2017 +0200
@@ -259,7 +259,7 @@
      * Tell if the class is inner.
      * This predicate also returns true for top-level nested types.
      * To test for a true inner class as seen by the programmer,
-     * use <tt>!isTopLevel()</tt>.
+     * use {@code !isTopLevel()}.
      */
     public final boolean isInnerClass() {
         return outerClass != null;
@@ -911,7 +911,7 @@
     }
 
     /**
-     * Note that this class is being used somehow by <tt>ref</tt>.
+     * Note that this class is being used somehow by {@code ref}.
      * Report deprecation errors, etc.
      */
     public void noteUsedBy(ClassDefinition ref, long where, Environment env) {
--- a/jdk/src/jdk.rmic/share/classes/sun/tools/java/Identifier.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/jdk/src/jdk.rmic/share/classes/sun/tools/java/Identifier.java	Wed Jul 05 20:51:27 2017 +0200
@@ -200,7 +200,7 @@
     /** A space character, which precedes the first inner class
      *  name in a qualified name, and thus marks the qualification
      *  as involving inner classes, instead of merely packages.<p>
-     *  Ex:  <tt>java.util.Vector. Enumerator</tt>.
+     *  Ex:  {@code java.util.Vector. Enumerator}.
      */
     public static final char INNERCLASS_PREFIX = ' ';
 
@@ -229,7 +229,7 @@
      * and with any nesting flattened into a new qualfication structure.
      * If the original identifier is inner,
      * the result will be qualified, and can be further
-     * decomposed by means of <tt>getQualifier</tt> and <tt>getName</tt>.
+     * decomposed by means of {@code getQualifier} and {@code getName}.
      * <p>
      * For example:
      * <pre>
--- a/jdk/src/jdk.rmic/share/classes/sun/tools/javac/SourceMember.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/jdk/src/jdk.rmic/share/classes/sun/tools/javac/SourceMember.java	Wed Jul 05 20:51:27 2017 +0200
@@ -394,7 +394,7 @@
      * <p>
      * This is the method which requests checking.
      * The real work is done by
-     * <tt>Vset check(Environment, Context, Vset)</tt>.
+     * {@code Vset check(Environment, Context, Vset)}.
      */
     public void check(Environment env) throws ClassNotFound {
         if (tracing) env.dtEnter("SourceMember.check: " +
--- a/jdk/src/jdk.rmic/share/classes/sun/tools/tree/Expression.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/jdk/src/jdk.rmic/share/classes/sun/tools/tree/Expression.java	Wed Jul 05 20:51:27 2017 +0200
@@ -210,8 +210,8 @@
     }
 
     /**
-     * Return a <code>FieldUpdater</code> object to be used in updating the
-     * value of the location denoted by <code>this</code>, which must be an
+     * Return a {@code FieldUpdater} object to be used in updating the
+     * value of the location denoted by {@code this}, which must be an
      * expression suitable for the left-hand side of an assignment.
      * This is used for implementing assignments to private fields for which
      * an access method is required.  Returns null if no access method is
@@ -228,8 +228,8 @@
     }
 
     /**
-     * Return a <code>FieldUpdater</code> object to be used in updating the value of the
-     * location denoted by <code>this</code>, which must be an expression suitable for the
+     * Return a {@code FieldUpdater} object to be used in updating the value of the
+     * location denoted by {@code this}, which must be an expression suitable for the
      * left-hand side of an assignment.  This is used for implementing the assignment
      * operators and the increment/decrement operators on private fields that require an
      * access method, e.g., uplevel from an inner class.  Returns null if no access method
@@ -260,9 +260,9 @@
      * <li> a type name followed by fields or types
      * <li> a package name followed a type and then fields or types
      * </nl>
-     * If a type name is found, it rewrites itself as a <tt>TypeExpression</tt>.
+     * If a type name is found, it rewrites itself as a {@code TypeExpression}.
      * If a node decides it can only be a package prefix, it sets its
-     * type to <tt>Type.tPackage</tt>.  The caller must detect this
+     * type to {@code Type.tPackage}.  The caller must detect this
      * and act appropriately to verify the full package name.
      * @arg loc the expression containing the ambiguous expression
      */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/crypto/provider/CICO/CICOChainingTest.java	Wed Jul 05 20:51:27 2017 +0200
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2007, 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.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
+import java.util.Arrays;
+import javax.crypto.CipherInputStream;
+import javax.crypto.CipherOutputStream;
+
+/*
+ * @test
+ * @bug 8048604
+ * @summary This test verifies the assertion "The chaining feature of
+ *  Filter streams should be supported." for feature "CipherInputStream &
+ *  CipherOutputStream"
+ * @run main CICOChainingTest
+ */
+public class CICOChainingTest {
+    /**
+     * Plain text length.
+     */
+    private static final int PLAIN_TEXT_LENGTH = 200;
+
+    public static void main(String argv[]) throws Exception {
+        CICOChainingTest test = new CICOChainingTest();
+        test.chainTest(true);
+        test.chainTest(false);
+    }
+
+    /**
+     * Chain CipherInputStream/CipherOutputStream with other stream, encrypt
+     * the text and decrypt it, recovered text is supposed to be same as
+     * original text.
+     * @param useInt true if read byte by byte false if read with buffer.
+     * @throws IOException any I/O operation failed.
+     */
+    public void chainTest(boolean useInt) throws IOException {
+        byte[] plainText = TestUtilities.generateBytes(PLAIN_TEXT_LENGTH);
+        byte[] recoveredText = new byte[plainText.length];
+        // Do initialization
+        try (MyNullCipherInputStream ciInput1 = new MyNullCipherInputStream(
+                new ByteArrayInputStream(plainText));
+                PipedOutputStream piOut = new PipedOutputStream();
+                MyNullCipherInputStream ciInput2 = new MyNullCipherInputStream(
+                        new PipedInputStream(piOut));
+                MyNullCipherOutputStream ciOut = new MyNullCipherOutputStream(
+                        piOut);) {
+            if (useInt) {
+                int buffer = ciInput1.read();
+                while (buffer != -1) {
+                    piOut.write(buffer);
+                    buffer = ciInput1.read();
+                }
+            } else {
+                byte[] buffer = new byte[20];
+                int len = ciInput1.read(buffer);
+                while (len != -1) {
+                    ciOut.write(buffer, 0, len);
+                    len = ciInput1.read(buffer);
+                }
+            }
+            ciOut.flush();
+            piOut.flush();
+            // Get the output
+            ciInput2.read(recoveredText);
+            if (ciInput2.available() > 0) {
+                throw new RuntimeException("Expected no data from ciInput2, but"
+                        + " ciInput2.available() = " + ciInput2.available());
+            }
+        }
+        // Verify output is same to input.
+        if (!Arrays.equals(plainText, recoveredText)) {
+            throw new RuntimeException("plainText:" + new String(plainText)
+                    + " recoveredText:" + new String(recoveredText)
+                    + " Test failed due to result compare fail");
+        }
+    }
+}
+
+class MyNullCipherInputStream extends CipherInputStream {
+
+    public MyNullCipherInputStream(InputStream is) {
+        super(is);
+    }
+}
+
+class MyNullCipherOutputStream extends CipherOutputStream {
+
+    public MyNullCipherOutputStream(OutputStream os) {
+        super(os);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/crypto/provider/CICO/CICODESFuncTest.java	Wed Jul 05 20:51:27 2017 +0200
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2007, 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 static java.lang.System.out;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.security.GeneralSecurityException;
+import java.security.NoSuchAlgorithmException;
+import java.security.Provider;
+import java.security.Security;
+import java.security.spec.AlgorithmParameterSpec;
+import java.util.Arrays;
+import javax.crypto.CipherInputStream;
+import javax.crypto.CipherOutputStream;
+import javax.crypto.SecretKey;
+import javax.crypto.Cipher;
+import javax.crypto.KeyGenerator;
+import javax.crypto.spec.IvParameterSpec;
+
+/*
+ * @test
+ * @bug 8048604
+ * @summary to verify cipherInputStream and cipherInputStream cipher function
+ * @run main CICODESFuncTest
+ */
+public class CICODESFuncTest {
+    /**
+     * Algorithms name.
+     */
+    private static final String[] ALGORITHMS = { "DES", "DESede", "Blowfish" };
+    private static final String[] MODES = { "ECB", "CBC", "CFB", "CFB24",
+            "CFB32", "CFB40", "CFB72", "OFB", "OFB20", "OFB48", "OFB56",
+            "OFB64", "PCBC" };
+    /**
+     * Padding mode.
+     */
+    private static final String[] PADDINGS = { "noPadding", "pkcs5padding" };
+    /**
+     * Plain text length.
+     */
+    private static final int TEXT_LENGTH = 80;
+    /**
+     * Initialization vector length.
+     */
+    private static final int IV_LENGTH = 8;
+
+    public static void main(String[] args) throws Exception {
+        Provider provider = Security.getProvider("SunJCE");
+        if (provider == null) {
+            throw new RuntimeException("SunJCE provider does not exist.");
+        }
+        for (String algorithm : ALGORITHMS) {
+            for (String mode : MODES) {
+                // We only test noPadding and pkcs5padding for CFB72, OFB20, ECB
+                // PCBC and CBC. Otherwise test noPadding only.
+                int padKinds = 1;
+                if (mode.equalsIgnoreCase("CFB72")
+                        || mode.equalsIgnoreCase("OFB20")
+                        || mode.equalsIgnoreCase("ECB")
+                        || mode.equalsIgnoreCase("PCBC")
+                        || mode.equalsIgnoreCase("CBC")) {
+                    padKinds = PADDINGS.length;
+                }
+                // PKCS5padding is meaningful only for ECB, CBC, PCBC
+                for (int k = 0; k < padKinds; k++) {
+                    for (ReadModel readMode : ReadModel.values()) {
+                        runTest(provider, algorithm, mode, PADDINGS[k], readMode);
+                    }
+                }
+            }
+        }
+    }
+
+    private static void runTest(Provider p, String algo, String mo, String pad,
+            ReadModel whichRead) throws GeneralSecurityException, IOException {
+        // Do initialization
+        byte[] plainText = TestUtilities.generateBytes(TEXT_LENGTH);
+        byte[] iv = TestUtilities.generateBytes(IV_LENGTH);
+        AlgorithmParameterSpec aps = new IvParameterSpec(iv);
+        try {
+            KeyGenerator kg = KeyGenerator.getInstance(algo, p);
+            out.println(algo + "/" + mo + "/" + pad + "/" + whichRead);
+            SecretKey key = kg.generateKey();
+            Cipher ci1 = Cipher.getInstance(algo + "/" + mo + "/" + pad, p);
+            if ("CFB72".equalsIgnoreCase(mo) || "OFB20".equalsIgnoreCase(mo)) {
+                throw new RuntimeException(
+                        "NoSuchAlgorithmException not throw when mode"
+                                + " is CFB72 or OFB20");
+            }
+            Cipher ci2 = Cipher.getInstance(algo + "/" + mo + "/" + pad, p);
+            if ("ECB".equalsIgnoreCase(mo)) {
+                ci1.init(Cipher.ENCRYPT_MODE, key);
+                ci2.init(Cipher.DECRYPT_MODE, key);
+            } else {
+                ci1.init(Cipher.ENCRYPT_MODE, key, aps);
+                ci2.init(Cipher.DECRYPT_MODE, key, aps);
+            }
+            ByteArrayOutputStream baOutput = new ByteArrayOutputStream();
+            try (CipherInputStream cInput
+                    = new CipherInputStream(
+                            new ByteArrayInputStream(plainText), ci1);
+                    CipherOutputStream ciOutput
+                        = new CipherOutputStream(baOutput, ci2);) {
+                // Read from the input and write to the output using 2 types
+                // of buffering : byte[] and int
+                whichRead.read(cInput, ciOutput, ci1, plainText.length);
+            }
+            // Verify input and output are same.
+            if (!Arrays.equals(plainText, baOutput.toByteArray())) {
+                throw new RuntimeException("Test failed due to compare fail ");
+            }
+        } catch (NoSuchAlgorithmException nsaEx) {
+            if ("CFB72".equalsIgnoreCase(mo) || "OFB20".equalsIgnoreCase(mo)) {
+                out.println("NoSuchAlgorithmException is expected for CFB72 and OFB20");
+            } else {
+                throw new RuntimeException("Unexpected exception testing: "
+                        + algo + "/" + mo + "/" + pad + "/" + whichRead, nsaEx);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/crypto/provider/CICO/CICOSkipTest.java	Wed Jul 05 20:51:27 2017 +0200
@@ -0,0 +1,270 @@
+/*
+ * Copyright (c) 2007, 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 static java.lang.System.out;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.Provider;
+import java.security.Security;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.InvalidKeySpecException;
+import javax.crypto.Cipher;
+import javax.crypto.CipherInputStream;
+import javax.crypto.KeyGenerator;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.PBEKeySpec;
+import javax.crypto.spec.PBEParameterSpec;
+
+/*
+ * @test
+ * @bug 8048604
+ * @summary This test verifies the assertion "The skip feature of Filter
+ *    streams should be supported." for feature
+ *    CipherInputStream and CipherOutputStream
+ */
+public class CICOSkipTest {
+    /**
+     * Block length.
+     */
+    private static final int BLOCK = 50;
+
+    /**
+     * Saving bytes length.
+     */
+    private static final int SAVE = 45;
+
+    /**
+     * Plain text length.
+     */
+    private static final int PLAIN_TEXT_LENGTH = 800;
+
+    /**
+     * Skip reading byte size. This should be same to BLOCK - SAVE
+     */
+    private static final int DISCARD = BLOCK - SAVE;
+
+    private static final String[] ALGOS = {"DES", "DESede", "Blowfish"};
+    private static final String[] MODES = {"ECB", "CBC", "CFB", "CFB32",
+        "OFB", "OFB64", "PCBC"};
+    private static final String[] PADDINGS = {"NoPadding", "Pkcs5Padding"};
+    private static final String[] PBE_ALGOS = {"PBEWithMD5AndDES",
+        "PBEWithMD5AndDES/CBC/PKCS5Padding"};
+
+    public static void main(String[] args) throws Exception {
+        // how many kinds of padding mode such as PKCS5padding and NoPadding
+        for (String algo : ALGOS) {
+            for (String mode : MODES) {
+                int padKinds = 1;
+                if (mode.equalsIgnoreCase("ECB")
+                        || mode.equalsIgnoreCase("PCBC")
+                        || mode.equalsIgnoreCase("CBC")) {
+                    padKinds = PADDINGS.length;
+                }
+                // PKCS5padding is meaningful only for ECB, CBC, PCBC
+                for (int k = 0; k < padKinds; k++) {
+                    String info = algo + "/" + mode + "/" + PADDINGS[k];
+                    try {
+                        CipherGenerator cg = new CipherGenerator(algo, mode,
+                                PADDINGS[k]);
+                        for (ReadMethod model : ReadMethod.values()) {
+                            runTest(cg.getPair(), info, model);
+                        }
+                    } catch (LengthLimitException exp) {
+                        // skip this if this key length is larger than what's
+                        // configured in the jce jurisdiction policy files
+                        out.println(exp.getMessage() + " is expected.");
+                    }
+                }
+            }
+        }
+        for (String pbeAlgo : PBE_ALGOS) {
+            for (ReadMethod model : ReadMethod.values()) {
+                System.out.println("Testing Algorithm : " + pbeAlgo
+                        + " ReadMethod : " + model);
+                runTest(new CipherGenerator(pbeAlgo).getPair(), pbeAlgo, model);
+            }
+        }
+    }
+
+    private static void runTest(Cipher[] pair, String info, ReadMethod whichRead)
+            throws IOException {
+        byte[] plainText = TestUtilities.generateBytes(PLAIN_TEXT_LENGTH);
+        out.println("Testing: " + info + "/" + whichRead);
+        try (ByteArrayInputStream baInput = new ByteArrayInputStream(plainText);
+                CipherInputStream ciInput1 = new CipherInputStream(baInput,
+                        pair[0]);
+                CipherInputStream ciInput2 = new CipherInputStream(ciInput1,
+                        pair[1]);) {
+            // Skip 5 bytes after read 45 bytes and repeat until finish
+            // (Read from the input and write to the output using 2 types
+            // of buffering : byte[] and int)
+            // So output has size:
+            // (OVERALL/BLOCK)* SAVE = (800 / 50) * 45 = 720 bytes
+            int numOfBlocks = plainText.length / BLOCK;
+
+            // Output buffer.
+            byte[] outputText = new byte[numOfBlocks * SAVE];
+            int index = 0;
+            for (int i = 0; i < numOfBlocks; i++) {
+                index = whichRead.readByte(ciInput2, outputText, SAVE, index);
+                // If available is more than expected discard byte size. Skip
+                // discard bytes, otherwise try to read discard bytes by read.
+                if (ciInput2.available() >= DISCARD) {
+                    ciInput2.skip(DISCARD);
+                } else {
+                    for (int k = 0; k < DISCARD; k++) {
+                        ciInput2.read();
+                    }
+                }
+            }
+            // Verify output is same as input
+            if (!TestUtilities
+                    .equalsBlockPartial(plainText, outputText, BLOCK, SAVE)) {
+                throw new RuntimeException("Test failed with compare fail");
+            }
+        }
+    }
+}
+
+class CipherGenerator {
+    /**
+     * Initialization vector  length.
+     */
+    private static final int IV_LENGTH = 8;
+
+    private static final String PASSWD = "Sesame!(@#$%^&*)";
+
+    private final Cipher[] pair = new Cipher[2];
+
+    // For DES/DESede ciphers
+    CipherGenerator(String algo, String mo, String pad)
+            throws NoSuchAlgorithmException,
+            InvalidAlgorithmParameterException, InvalidKeyException,
+            NoSuchPaddingException, SecurityException, LengthLimitException {
+        // Do initialization
+        KeyGenerator kg = KeyGenerator.getInstance(algo);
+        SecretKey key = kg.generateKey();
+        if (key.getEncoded().length * 8 > Cipher.getMaxAllowedKeyLength(algo)) {
+            // skip this if this key length is larger than what's
+            // configured in the jce jurisdiction policy files
+            throw new LengthLimitException(
+                    "Skip this test if key length is larger than what's"
+                    + "configured in the jce jurisdiction policy files");
+        }
+        AlgorithmParameterSpec aps = null;
+        if (!mo.equalsIgnoreCase("ECB")) {
+            byte[] iv = TestUtilities.generateBytes(IV_LENGTH);
+            aps = new IvParameterSpec(iv);
+        }
+        initCiphers(algo + "/" + mo + "/" + pad, key, aps);
+    }
+
+    // For PBE ciphers
+    CipherGenerator(String algo) throws NoSuchAlgorithmException,
+            InvalidAlgorithmParameterException, InvalidKeyException,
+            NoSuchPaddingException, InvalidKeySpecException {
+        // Do initialization
+        byte[] salt = TestUtilities.generateBytes(IV_LENGTH);
+        int iterCnt = 6;
+        SecretKeyFactory skf = SecretKeyFactory.getInstance(algo.split("/")[0]);
+        SecretKey key = skf
+                .generateSecret(new PBEKeySpec(PASSWD.toCharArray()));
+        AlgorithmParameterSpec aps = new PBEParameterSpec(salt, iterCnt);
+        initCiphers(algo, key, aps);
+    }
+
+    private void initCiphers(String algo, SecretKey key,
+            AlgorithmParameterSpec aps) throws NoSuchAlgorithmException,
+            NoSuchPaddingException, InvalidKeyException,
+            InvalidAlgorithmParameterException {
+        Provider provider = Security.getProvider("SunJCE");
+        if (provider == null) {
+            throw new RuntimeException("SunJCE provider does not exist.");
+        }
+        Cipher ci1 = Cipher.getInstance(algo, provider);
+        ci1.init(Cipher.ENCRYPT_MODE, key, aps);
+        pair[0] = ci1;
+        Cipher ci2 = Cipher.getInstance(algo, provider);
+        ci2.init(Cipher.DECRYPT_MODE, key, aps);
+        pair[1] = ci2;
+    }
+
+    Cipher[] getPair() {
+        return pair;
+    }
+}
+
+enum ReadMethod {
+    // read one byte at a time for save times
+    READ_ONE_BYTE {
+        @Override
+        int readByte(CipherInputStream ciIn2, byte[] outputText, int save,
+                int index) throws IOException {
+            for (int j = 0; j < save; j++, index++) {
+                int buffer0 = ciIn2.read();
+                if (buffer0 != -1) {
+                    outputText[index] = (byte) buffer0;
+                } else {
+                    break;
+                }
+            }
+            return index;
+        }
+    },
+    // read a chunk of save bytes if possible
+    READ_BLOCK {
+        @Override
+        int readByte(CipherInputStream ciIn2, byte[] outputText, int save,
+                int index) throws IOException {
+            int len1 = ciIn2.read(outputText, index, save);
+            out.println("Init: index=" + index + ",len=" + len1);
+            // read more until save bytes
+            index += len1;
+            int len2 = 0;
+            while (len1 != save && len2 != -1) {
+                len2 = ciIn2.read(outputText, index, save - len1);
+                out.println("Cont: index=" + index + ",len=" + len2);
+                len1 += len2;
+                index += len2;
+            }
+            return index;
+        }
+    };
+
+    abstract int readByte(CipherInputStream ciIn2, byte[] outputText, int save,
+            int index) throws IOException;
+};
+
+class LengthLimitException extends Exception {
+
+    public LengthLimitException(String string) {
+        super(string);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/crypto/provider/CICO/PBEFunc/AESPBEWrapper.java	Wed Jul 05 20:51:27 2017 +0200
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2007, 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.security.AlgorithmParameters;
+import java.security.GeneralSecurityException;
+import java.security.Provider;
+import java.security.Security;
+import javax.crypto.SecretKey;
+import javax.crypto.Cipher;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.PBEKeySpec;
+
+/**
+ * Wrapper class to test a given AES-based PBE algorithm.
+ */
+public class AESPBEWrapper extends AbstractPBEWrapper {
+    /**
+     * the algorithm parameters.
+     */
+    private AlgorithmParameters pbeParams;
+
+    /**
+     * the encryption key.
+     */
+    private final SecretKey key;
+
+    /**
+     * The Wrapper constructor. Instantiate Cipher using the given AES-based PBE
+     * algorithm.
+     *
+     * @param algo AES-based PBE algorithm.
+     * @param passwd password phrase.
+     * @throws GeneralSecurityException all security exceptions are thrown.
+     */
+    public AESPBEWrapper(PBEAlgorithm algo, String passwd)
+            throws GeneralSecurityException {
+        // salt and iteration count will be generated during encryption
+        super(algo, passwd, 0);
+
+        // Generate secret key. We expect no mode and padding specified.
+        SecretKeyFactory skf = SecretKeyFactory.getInstance(algo.baseAlgo);
+        key = skf.generateSecret(new PBEKeySpec(passwd.toCharArray()));
+    }
+
+    /**
+     * Initiate the Cipher object using given "mode".
+     * @return a cipher object.
+     * @throws GeneralSecurityException all security exceptions are thrown.
+     */
+    @Override
+    protected Cipher initCipher(int mode) throws GeneralSecurityException {
+        Provider provider = Security.getProvider("SunJCE");
+        if (provider == null) {
+            throw new RuntimeException("SunJCE provider does not exist.");
+        }
+        // get Cipher instance
+        Cipher ci = Cipher.getInstance(transformation, provider);
+        if (Cipher.ENCRYPT_MODE == mode) {
+            ci.init(Cipher.ENCRYPT_MODE, key);
+            pbeParams = ci.getParameters();
+        } else {
+            ci.init(Cipher.DECRYPT_MODE, key, pbeParams);
+        }
+        return ci;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/crypto/provider/CICO/PBEFunc/AbstractPBEWrapper.java	Wed Jul 05 20:51:27 2017 +0200
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2007, 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.security.GeneralSecurityException;
+import javax.crypto.Cipher;
+
+/**
+ * PBEWrapper is an abstract class for all concrete PBE Cipher wrappers.
+ */
+public abstract class AbstractPBEWrapper {
+    /**
+     * Iteration count.
+     */
+    public static final int DEFAULT_ITERATION = 1000;
+
+    public static final String PBKDF2 = "PBKDF2";
+    public static final String AES = "AES";
+    public static final String DEFAULT = "default";
+
+    /**
+     * transformation the name of the transformation, e.g.,
+     * DES/CBC/PKCS5Padding
+     */
+    protected final String transformation;
+
+    /**
+     * the standard name of the requested secret-key algorithm.
+     */
+    protected final String baseAlgo;
+
+    /**
+     * The contents of salt are copied to protect against subsequent
+     * modification.
+     */
+    protected final byte[] salt;
+
+    /**
+     * Password.
+     */
+    protected final String password;
+
+    /**
+     * PBEWrapper creator.
+     *
+     * @param algo PBE algorithm to test
+     * @param passwd a password phrase
+     * @return PBEWrapper in accordance to requested algo.
+     * @throws GeneralSecurityException all exceptions are thrown.
+     */
+    public static AbstractPBEWrapper createWrapper(PBEAlgorithm algo, String passwd)
+            throws GeneralSecurityException {
+        switch (algo.type) {
+            case PBKDF2:
+                return new PBKDF2Wrapper(algo, passwd);
+            case AES:
+                return new AESPBEWrapper(algo, passwd);
+            default:
+                return new DefaultPBEWrapper(algo, passwd);
+        }
+    }
+
+    /**
+     * PBEWrapper constructor.
+     *
+     * @param algo algorithm to wrap
+     * @param password password phrase
+     * @param saltSize salt size (defined in subclasses)
+     */
+    protected AbstractPBEWrapper(PBEAlgorithm algo, String password, int saltSize) {
+        this.transformation = algo.getTransformation();
+        this.baseAlgo = algo.baseAlgo;
+        this.salt = TestUtilities.generateBytes(saltSize);
+        this.password = password;
+    }
+
+    /**
+     * Initialize Cipher object for the operation requested in the mode parameter.
+     *
+     * @param mode encryption or decryption
+     * @return a cipher initialize by mode.
+     * @throws GeneralSecurityException all security exceptions are thrown.
+     */
+    protected abstract Cipher initCipher(int mode) throws GeneralSecurityException;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/crypto/provider/CICO/PBEFunc/CICOPBEFuncTest.java	Wed Jul 05 20:51:27 2017 +0200
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8048604
+ * @summary This test verifies the assertion "The encrypt/decrypt
+ *  mechanism of cipher should perform correctly." for feature
+ *  "CipherInputStream & CipherOutputStream".
+ * @library ../
+ * @run main CICOPBEFuncTest
+ */
+
+import java.util.Arrays;
+import javax.crypto.Cipher;
+
+public class CICOPBEFuncTest {
+
+    public static void main(String[] args) throws Exception {
+        for (PBEAlgorithm algorithm : PBEAlgorithm.values()) {
+            // int buffertin test
+            String algo = algorithm.baseAlgo.toUpperCase();
+            if (!algo.contains("TRIPLEDES") && !algo.contains("AES_256")
+                    || Cipher.getMaxAllowedKeyLength(algo) > 128) {
+                // skip this if this key length is larger than what's
+                // configured in the jce jurisdiction policy files
+                System.out.println("Testing " + algorithm.getTransformation());
+                for (String type : Arrays.asList(CICO_PBE_Test.INT_BYTE_BUFFER,
+                        CICO_PBE_Test.BYTE_ARR_BUFFER)) {
+                    new CICO_PBE_RW_Test(algorithm)
+                        .proceedTest(type);
+                    new CICO_PBE_SKIP_Test(algorithm)
+                        .proceedTest(type);
+                }
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/crypto/provider/CICO/PBEFunc/CICO_PBE_RW_Test.java	Wed Jul 05 20:51:27 2017 +0200
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2007, 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.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.security.GeneralSecurityException;
+
+import javax.crypto.CipherOutputStream;
+
+/**
+ * CICO PBE Read/Write functional test.
+ *
+ * Verifies for the given PBE algorithm if the encrypt/decrypt mechanism is
+ * performed correctly for CipherInputStream and CipherOutputStream.
+ *
+ * Test scenario:
+ * 1. initializes plain text with random generated data.
+ * 2. for the given PBE algorithm instantiates encrypt and decrypt Ciphers.
+ * 3. instantiates CipherInputStream with the encrypt Cipher.
+ * 4. instantiates CipherOutputStream with the decrypt Cipher.
+ * 5. performs reading from the CipherInputStream (encryption data) and writing
+ *    to the CipherOutputStream (decryption). As a result the output of the
+ *    CipherOutputStream should be the same as an original plain text.
+ * 6. compares if the original plain text is the same as the output of the
+ *    CipherOutputStream.
+ *
+ * The test implements 2 test cases in accordance with buffering type:
+ * 1. byte array buffering
+ * 2. int buffering
+ */
+public class CICO_PBE_RW_Test extends CICO_PBE_Test {
+
+    public CICO_PBE_RW_Test(PBEAlgorithm pbeAlgo)
+            throws GeneralSecurityException {
+        super(pbeAlgo);
+    }
+
+    /**
+     * The CICO PBE RW test specific part of the super.doTest(). Implements the
+     * scenario in accordance to the class description.
+     * @param type byteArrayBuffering or intByteBuffering
+     * @throws IOException  any I/O operation failed.
+     * @throws GeneralSecurityException any security error.
+     */
+    @Override
+    public void proceedTest(String type) throws IOException,
+            GeneralSecurityException {
+        ByteArrayOutputStream baOutput = new ByteArrayOutputStream();
+        try (CipherOutputStream ciOutput = new CipherOutputStream(baOutput,
+                getDecryptCipher())) {
+            if (type.equals(CICO_PBE_Test.BYTE_ARR_BUFFER)) {
+                proceedTestUsingByteArrayBuffer(ciOutput);
+            } else {
+                proceedTestUsingIntBuffer(ciOutput);
+            }
+            ciOutput.flush();
+        }
+        // Compare input and output
+        if (!TestUtilities.equalsBlock(plainText, baOutput.toByteArray(), TEXT_SIZE)) {
+            throw new RuntimeException("outputText not same with expectedText"
+                    + " when test " + type);
+        }
+    }
+
+    /**
+     * Implements byte array buffering type test case of the CICO PBE RW test.
+     * @param ciOutput  output stream for data written.
+     * @throws java.io.IOException any I/O operation failed.
+     */
+    public void proceedTestUsingByteArrayBuffer(
+            CipherOutputStream ciOutput) throws IOException {
+        byte[] buffer = new byte[TEXT_SIZE];
+        int len = getCiInput().read(buffer);
+        while (len != -1) {
+            ciOutput.write(buffer, 0, len);
+            len = getCiInput().read(buffer);
+        }
+    }
+
+    /**
+     * Implements int buffering type test case.
+     * @param ciOutput output stream for data written.
+     * @throws java.io.IOException any I/O operation failed.
+     */
+    public void proceedTestUsingIntBuffer(CipherOutputStream ciOutput)
+            throws IOException {
+        int buffer = getCiInput().read();
+        while (buffer != -1) {
+            ciOutput.write(buffer);
+            buffer = getCiInput().read();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/crypto/provider/CICO/PBEFunc/CICO_PBE_SKIP_Test.java	Wed Jul 05 20:51:27 2017 +0200
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2007, 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.io.IOException;
+import java.security.GeneralSecurityException;
+import javax.crypto.CipherInputStream;
+
+/**
+ * CICO PBE SKIP functional test.
+ *
+ * Verifies for the given PBE algorithm if the encrypt/decrypt mechanism is
+ * performed correctly for CipherInputStream when skip() method is used.
+ *
+ * Test scenario:
+ * 1. initializes plain text with random generated data with length TEXT_SIZE.
+ * 2. for the given PBE algorithm instantiates encrypt and decrypt Ciphers.
+ * 3. instantiates CipherInputStream 1 with the encrypt Cipher.
+ * 4. instantiates CipherInputStream 2 with the CipherInputStream 1 and decrypt
+ *    Cipher.
+ * 5. the plain text is divided on TEXT_SIZE/BLOCK blocks. Reading from
+ *    CipherInputStream 2 one block at time. The last BLOCK - SAVE bytes are
+ *    skipping for each block. Therefor the plain text data go through
+ *    CipherInputStream 1 (encrypting) and CipherInputStream 2 (decrypting).
+ *    As a result the output should equal to the original text except DISCARD
+ *    byte for each block are skipped.
+ * 6. get the standard output.
+ * 7. compares the expected standard output with the output of the
+ *    CipherInputStream 2. If it is the same the test passed. Otherwise it
+ *    failed. Any uncaught exceptions should be considered as an error.
+ * The test implements 2 test cases in accordance with a buffering type:
+ * 1. byte array buffering
+ * 2. int buffering
+ */
+public class CICO_PBE_SKIP_Test extends CICO_PBE_Test {
+    /**
+     * Block size.
+     */
+    private static final int BLOCK = 50;
+
+    /**
+     * Valid reading byte size.
+     */
+    private static final int SAVE = 45;
+
+    /**
+     * Skip reading byte size. This should be same to BLOCK - SAVE
+     */
+    private static final int DISCARD = BLOCK - SAVE;
+
+    /**
+     * Number of blocks.
+     */
+    private static final int NUMBER_OF_BLOCKS = TEXT_SIZE / BLOCK;
+
+    private final byte[] outputText;
+    /**
+     * CICO PBE Skip test constructor
+     *
+     * @param pbeAlgo the PBE algorithm to test.
+     * @throws java.security.GeneralSecurityException
+     */
+    public CICO_PBE_SKIP_Test(PBEAlgorithm pbeAlgo)
+            throws GeneralSecurityException {
+        super(pbeAlgo);
+        outputText = new byte[NUMBER_OF_BLOCKS * SAVE];
+    }
+
+    /**
+     * Implements byte array buffering type test case of the CICO SKIP test.
+     *
+     * @param blockNum block number to read.
+     */
+    private void proceedSkipTestUsingByteArrayBufferingType(
+            CipherInputStream ciIn2, int blockNum) throws IOException {
+        int index = blockNum * SAVE;
+        int len1 = ciIn2.read(outputText, index, SAVE);
+        // read more until SAVE bytes
+        index += len1;
+        int len2 = 0;
+        int totalRead = len1;
+        while (len1 != SAVE && len2 != -1) {
+            len2 = ciIn2.read(outputText, index, SAVE - len1);
+            len1 += len2;
+            index += len2;
+            totalRead += len2;
+        }
+        if (totalRead != SAVE) {
+            throw new RuntimeException("Read bytes number " + totalRead
+                    + " does not equal to given number " + SAVE);
+        }
+    }
+
+    /**
+     * Implements int buffering type test case of the CICO SKIP test.
+     *
+     * @param blockNum block number to read.
+     */
+    private void proceedSkipTestUsingIntBufferingType(CipherInputStream ciIn2,
+            int blockNum) throws IOException {
+        int index = blockNum * SAVE;
+        int totalRead = 0;
+        for (int j = 0; j < SAVE; j++, index++) {
+            int buffer0 = ciIn2.read();
+            if (buffer0 != -1) {
+                outputText[index] = (byte) buffer0;
+                totalRead++;
+            } else {
+                break;
+            }
+        }
+        if (totalRead != SAVE) {
+            throw new RuntimeException("Read bytes number " + totalRead
+                    + " does not equal to given number " + SAVE);
+        }
+    }
+
+    /**
+     * The CICO PBE SKIP test specific part of the super.doTest(). Implements
+     * the scenario in accordance to the class description.
+     * @throws java.io.IOException any I/O failed.
+     */
+    @Override
+    public void proceedTest(String type) throws IOException {
+        System.out.println("Test type: " + type);
+        // init second input stream with decrypt Cipher
+        try (CipherInputStream ciIn2 = new CipherInputStream(getCiInput(),
+                getDecryptCipher())) {
+            for (int i = 0; i < NUMBER_OF_BLOCKS; i++) {
+                if (type.equals(CICO_PBE_Test.BYTE_ARR_BUFFER)) {
+                    proceedSkipTestUsingByteArrayBufferingType(ciIn2, i);
+                } else {
+                    proceedSkipTestUsingIntBufferingType(ciIn2, i);
+                }
+                if (ciIn2.available() >= DISCARD) {
+                    ciIn2.skip(DISCARD);
+                } else {
+                    for (int k = 0; k < DISCARD; k++) {
+                        ciIn2.read();
+                    }
+                }
+            }
+        }
+        if (!TestUtilities.equalsBlockPartial(plainText, outputText, BLOCK, SAVE)) {
+            throw new RuntimeException("outputText not same with expectedText"
+                    + " when test " + type);
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/crypto/provider/CICO/PBEFunc/CICO_PBE_Test.java	Wed Jul 05 20:51:27 2017 +0200
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2007, 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.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.security.GeneralSecurityException;
+import javax.crypto.Cipher;
+import javax.crypto.CipherInputStream;
+
+/**
+ * This is an abstract class for CipherInputStream/CipherOutputStream PBE
+ * functional tests.
+ */
+public abstract class CICO_PBE_Test {
+    /**
+     * Sample string for byte buffer.
+     */
+    public static final String BYTE_ARR_BUFFER = "byteArrayBuffering";
+
+    /**
+     * Sample string for int buffer.
+     */
+    public static final String INT_BYTE_BUFFER = "intByteBuffering";
+    public static final String PASS_PHRASE = "Some password phrase!";
+
+    /**
+     * Text string size.
+     */
+    public static final int TEXT_SIZE = 800;
+
+    protected final byte[] plainText;
+    private final Cipher encryptCipher, decryptCipher;
+
+    /**
+     * An CipherInputStream for reading cipher and plain text.
+     */
+    private final CipherInputStream ciInput;
+
+    /**
+     * Constructor by algorithm.
+     * @param pbeAlgo PBE algorithm to test.
+     * @throws GeneralSecurityException if any security error.
+     */
+    public CICO_PBE_Test(PBEAlgorithm pbeAlgo) throws GeneralSecurityException {
+        // Do initialization of the plainText
+        plainText = TestUtilities.generateBytes(TEXT_SIZE);
+        // Do initialization of the ciphers
+        AbstractPBEWrapper pbeWrap = AbstractPBEWrapper.createWrapper(pbeAlgo, PASS_PHRASE);
+        encryptCipher = pbeWrap.initCipher(Cipher.ENCRYPT_MODE);
+        decryptCipher = pbeWrap.initCipher(Cipher.DECRYPT_MODE);
+        // init cipher input stream
+        ciInput = new CipherInputStream(new ByteArrayInputStream(plainText),
+                encryptCipher);
+    }
+
+    protected byte[] getPlainText() {
+        return plainText;
+    }
+
+    /**
+     * The body of the test. Should be defined in subclasses.
+     * @param type byteArrayBuffering or intByteBuffering
+     * @throws IOException I/O operation failed.
+     * @throws GeneralSecurityException all exceptions thrown.
+     */
+    protected abstract void proceedTest(String type)
+            throws IOException, GeneralSecurityException;
+
+    protected Cipher getEncryptCipher() {
+        return encryptCipher;
+    }
+
+    public CipherInputStream getCiInput() {
+        return ciInput;
+    }
+
+    public Cipher getDecryptCipher() {
+        return decryptCipher;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/crypto/provider/CICO/PBEFunc/CipherNCFuncTest.java	Wed Jul 05 20:51:27 2017 +0200
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 8048604
+ * @library ../ /lib/testlibrary
+ * @summary This test verifies the assertion "There should be no transformation
+ *  on the plaintext/ciphertext in encryption/decryption mechanism" for
+ *  feature "NullCipher".
+ */
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NullCipher;
+import javax.crypto.ShortBufferException;
+import jdk.testlibrary.RandomFactory;
+
+public class CipherNCFuncTest {
+    public static void main(String[] args) throws ShortBufferException,
+            IllegalBlockSizeException, BadPaddingException {
+        byte[] plainText = new byte[801];
+        // Initialization
+        RandomFactory.getRandom().nextBytes(plainText);
+        Cipher ci = new NullCipher();
+        // Encryption
+        byte[] cipherText = new byte[ci.getOutputSize(plainText.length)];
+        int offset = ci.update(plainText, 0, plainText.length, cipherText, 0);
+        ci.doFinal(cipherText, offset);
+        // Decryption
+        byte[] recoveredText = new byte[ci.getOutputSize(cipherText.length)];
+        int len = ci.doFinal(cipherText, 0, cipherText.length, recoveredText);
+        // Comparison
+        if (len != plainText.length ||
+                !TestUtilities.equalsBlock(plainText, cipherText, len) ||
+                !TestUtilities.equalsBlock(plainText, recoveredText, len)) {
+            throw new RuntimeException(
+                "Test failed because plainText not equal to cipherText and revoveredText");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/crypto/provider/CICO/PBEFunc/DefaultPBEWrapper.java	Wed Jul 05 20:51:27 2017 +0200
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2007, 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.security.GeneralSecurityException;
+import java.security.Provider;
+import java.security.Security;
+import javax.crypto.SecretKey;
+import javax.crypto.Cipher;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.PBEKeySpec;
+import javax.crypto.spec.PBEParameterSpec;
+
+/**
+ * Default wrapper for a password based encryption Cipher.
+ */
+
+public class DefaultPBEWrapper extends AbstractPBEWrapper {
+    /**
+     * Define default SALT size as 8.
+     */
+    private static final int PBE_SALT_SIZE = 8;
+
+    /**
+     * Default PBE wrapper constructor.
+     *
+     * @param algo PGE algorithm to wrap.
+     * @param passwd password phrase
+     */
+    public DefaultPBEWrapper(PBEAlgorithm algo, String passwd) {
+        super(algo, passwd, PBE_SALT_SIZE);
+    }
+
+    /**
+     * Instantiate Cipher for the PBE algorithm.
+     *
+     * @param mode Cipher mode: encrypt or decrypt.
+     * @return Cipher in accordance to the PBE algorithm
+     * @throws java.security.GeneralSecurityException
+     */
+    @Override
+    protected Cipher initCipher(int mode) throws  GeneralSecurityException {
+        Provider provider = Security.getProvider("SunJCE");
+        if (provider == null) {
+            throw new RuntimeException("SunJCE provider does not exist.");
+        }
+        SecretKey key = SecretKeyFactory.getInstance(baseAlgo)
+                .generateSecret(new PBEKeySpec(password.toCharArray()));
+        Cipher ci = Cipher.getInstance(transformation, provider);
+        ci.init(mode, key, new PBEParameterSpec(salt, DEFAULT_ITERATION));
+        return ci;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/crypto/provider/CICO/PBEFunc/PBEAlgorithm.java	Wed Jul 05 20:51:27 2017 +0200
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2007, 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.util.StringJoiner;
+
+public enum PBEAlgorithm {
+    MD5_DES("PBEWithMD5ANDdes", "", "", AbstractPBEWrapper.DEFAULT),
+    MD5_DES_CBC_PKCS5("PBEWithMD5AndDES", "CBC", "PKCS5Padding",
+            AbstractPBEWrapper.DEFAULT),
+    MD5_TRIPLEDES("PBEWithMD5ANDtripledes", "", "", AbstractPBEWrapper.DEFAULT),
+    MD5_TRIPLEDES_CBC_PKCS5("PBEWithMD5AndTRIPLEDES", "CBC", "PKCS5Padding",
+            AbstractPBEWrapper.DEFAULT),
+    SHA1_DESEDE("PBEwithSHA1AndDESede", "", "", AbstractPBEWrapper.DEFAULT),
+    SHA1_DESEDE_CBC_PKCS5("PBEwithSHA1AndDESede", "CBC", "PKCS5Padding",
+            AbstractPBEWrapper.DEFAULT),
+    SHA1_RC2_40("PBEwithSHA1AndRC2_40", "", "", AbstractPBEWrapper.DEFAULT),
+    SHA1_RC2_40_PKCS5("PBEwithSHA1Andrc2_40", "CBC", "PKCS5Padding",
+            AbstractPBEWrapper.DEFAULT),
+    SHA1_RC2_128("PBEWithSHA1AndRC2_128", "", "", AbstractPBEWrapper.DEFAULT),
+    SHA1_RC2_128_PKCS5("PBEWithSHA1andRC2_128", "CBC", "PKCS5Padding",
+            AbstractPBEWrapper.DEFAULT),
+    SHA1_RC4_40("PBEWithSHA1AndRC4_40", "", "", AbstractPBEWrapper.DEFAULT),
+    SHA1_RC4_40_ECB_NOPADDING("PBEWithsha1AndRC4_40", "ECB", "NoPadding",
+            AbstractPBEWrapper.DEFAULT),
+    SHA1_RC4_128("PBEWithSHA1AndRC4_128", "", "", AbstractPBEWrapper.DEFAULT),
+    SHA1_RC4_128_ECB_NOPADDING("pbeWithSHA1AndRC4_128", "ECB", "NoPadding",
+            AbstractPBEWrapper.DEFAULT),
+    HMAC_SHA1_AES_128("PBEWithHmacSHA1AndAES_128", "", "", AbstractPBEWrapper.AES),
+    HMAC_SHA224_AES_128("PBEWithHmacSHA224AndAES_128", "", "", AbstractPBEWrapper.AES),
+    HMAC_SHA256_AES_128("PBEWithHmacSHA256AndAES_128", "", "", AbstractPBEWrapper.AES),
+    HMAC_SHA384_AES_128("PBEWithHmacSHA384AndAES_128", "", "", AbstractPBEWrapper.AES),
+    HMAC_SHA512_AES_128("PBEWithHmacSHA512AndAES_128", "", "", AbstractPBEWrapper.AES),
+    HMAC_SHA1_AES_256("PBEWithHmacSHA1AndAES_256", "", "", AbstractPBEWrapper.AES),
+    HMAC_SHA224_AES_256("PBEWithHmacSHA224AndAES_256", "", "", AbstractPBEWrapper.AES),
+    HMAC_SHA256_AES_256("PBEWithHmacSHA256AndAES_256", "", "", AbstractPBEWrapper.AES),
+    HMAC_SHA384_AES_256("PBEWithHmacSHA384AndAES_256", "", "", AbstractPBEWrapper.AES),
+    HMAC_SHA512_AES_256("PBEWithHmacSHA512AndAES_256", "", "", AbstractPBEWrapper.AES),
+    PBKDF_HMAC_SHA1("PBKDF2WithHmacSHA1", "", "", AbstractPBEWrapper.PBKDF2),
+    PBKDF_HMAC_SHA224("PBKDF2WithHmacSHA224", "", "", AbstractPBEWrapper.PBKDF2),
+    PBKDF_HMAC_SHA256("PBKDF2WithHmacSHA256", "", "", AbstractPBEWrapper.PBKDF2),
+    PBKDF_HMAC_SHA384("PBKDF2WithHmacSHA384", "", "", AbstractPBEWrapper.PBKDF2),
+    PBKDF_HMAC_SHA512("PBKDF2WithHmacSHA512", "", "", AbstractPBEWrapper.PBKDF2);
+    final String baseAlgo;
+    final String mode;
+    final String padding;
+    final String type;
+
+    PBEAlgorithm(String alg, String mode, String padding, String type) {
+        this.baseAlgo = alg;
+        this.mode = mode;
+        this.padding = padding;
+        this.type = type;
+    }
+
+    public String getTransformation() {
+        StringJoiner sj = new StringJoiner("/");
+        sj.add(baseAlgo);
+        if (!mode.equals("")) {
+            sj.add(this.mode);
+        }
+        if (!padding.equals("")) {
+            sj.add(this.padding);
+        }
+        return sj.toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/crypto/provider/CICO/PBEFunc/PBKDF2Wrapper.java	Wed Jul 05 20:51:27 2017 +0200
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2007, 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.security.GeneralSecurityException;
+import java.security.Provider;
+import java.security.Security;
+import javax.crypto.Cipher;
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.PBEKeySpec;
+import javax.crypto.spec.SecretKeySpec;
+
+/**
+ * Wrapper class to test a given SecretKeyFactory.PBKDF2 algorithm.
+ */
+public class PBKDF2Wrapper extends AbstractPBEWrapper {
+    /**
+     * Default salt size.
+     */
+    public static final int PBKDF2_SALT_SIZE = 64;
+
+    /**
+     * Default key length.
+     */
+    public static final int PKDF2_DEFAULT_KEY_LEN = 128;
+
+    /**
+     * Default transformation.
+     */
+    public static final String CIPHER_TRANSFORMATION = "AES/CBC/PKCS5Padding";
+
+    /**
+     * Algorithm name.
+     */
+    public static final String KEY_ALGORITHM = "AES";
+
+    /**
+     * Initialization vector length.
+     */
+    private static final int IV_LENGTH = 16;
+
+    /**
+     * The buffer with the IV.
+     */
+    private final byte[] iv;
+
+    /**
+     * PBKDF2Wrapper constructor. Instantiate Cipher using
+     * "AES/CBC/PKCS5Padding" transformation. Generate a secret key using PKDF2
+     * algorithms given in the "algo" parameter.
+     *
+     * @param algo AES-based PBE algorithm.
+     * @param passwd password phrase.
+     * @throws GeneralSecurityException all security exceptions are thrown.
+     */
+    public PBKDF2Wrapper(PBEAlgorithm algo, String passwd)
+            throws GeneralSecurityException {
+        super(algo, passwd, PBKDF2_SALT_SIZE);
+        iv = TestUtilities.generateBytes(IV_LENGTH);
+    }
+
+    /**
+     * Initiate the Cipher object for PBKDF2 algorithm using given "mode".
+     *
+     * @param mode Cipher mode: encrypt or decrypt
+     * @return Cipher object for PBKDF2 algorithm
+     * @throws GeneralSecurityException all security exceptions are thrown.
+     */
+    @Override
+    protected Cipher initCipher(int mode) throws GeneralSecurityException {
+        Provider provider = Security.getProvider("SunJCE");
+        if (provider == null) {
+            throw new RuntimeException("SunJCE provider does not exist.");
+        }
+        // Generate secret key
+        PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray(),
+                salt, DEFAULT_ITERATION, PKDF2_DEFAULT_KEY_LEN);
+        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(baseAlgo);
+        SecretKey key = keyFactory.generateSecret(pbeKeySpec);
+
+        // get Cipher instance
+        Cipher cipher = Cipher.getInstance(CIPHER_TRANSFORMATION, provider);
+        cipher.init(mode,
+                new SecretKeySpec(key.getEncoded(),KEY_ALGORITHM),
+                new IvParameterSpec(iv));
+        return cipher;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/crypto/provider/CICO/ReadModel.java	Wed Jul 05 20:51:27 2017 +0200
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2007, 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.io.IOException;
+
+import javax.crypto.Cipher;
+import javax.crypto.CipherInputStream;
+import javax.crypto.CipherOutputStream;
+
+/**
+ * ReadModel provides different way to test
+ * CipherInputStream.read()/read(byte[])/read(byte[], int, int) and
+ * CipherOutputStream.write(int)/write(byte[], int, int)/read(byte[]) API
+ */
+enum ReadModel {
+    READ_BYTE {
+        @Override
+        public void read(CipherInputStream cInput, CipherOutputStream ciOutput,
+                Cipher ciIn, int inputLen) throws IOException {
+            int buffer0 = cInput.read();
+            while (buffer0 != -1) {
+                ciOutput.write(buffer0);
+                buffer0 = cInput.read();
+            }
+        }
+    },
+    READ_BUFFER {
+        @Override
+        public void read(CipherInputStream cInput, CipherOutputStream ciOutput,
+                Cipher ciIn, int inputLen) throws IOException {
+            byte[] buffer1 = new byte[20];
+            int len1;
+            while ((len1 = cInput.read(buffer1)) != -1) {
+                ciOutput.write(buffer1, 0, len1);
+            }
+
+        }
+    },
+    READ_BUFFER_OFFSET {
+        @Override
+        public void read(CipherInputStream cInput, CipherOutputStream ciOutput,
+                Cipher ciIn, int inputLen) throws IOException {
+            byte[] buffer2 = new byte[ciIn.getOutputSize(inputLen)];
+            int offset2 = 0;
+            int len2 = 0;
+            while (len2 != -1) {
+                len2 = cInput.read(buffer2, offset2, buffer2.length - offset2);
+                offset2 += len2;
+            }
+            ciOutput.write(buffer2);
+
+        }
+    };
+
+    abstract public void read(CipherInputStream cInput,
+            CipherOutputStream ciOutput, Cipher ciIn, int inputLen)
+            throws IOException;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/crypto/provider/CICO/TestUtilities.java	Wed Jul 05 20:51:27 2017 +0200
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+
+/*
+ * utility class
+ */
+
+public class TestUtilities {
+    public static boolean equalsBlock(byte[] b1, byte[] b2, int len) {
+        for (int i = 0; i < len; i++) {
+            if (b1[i] != b2[i]) {
+                System.err.println("b1[" + i + "] : " + b1[i]
+                        + " b2[" + i + "] : " + b2[i]);
+                return false;
+            }
+        }
+        return true;
+    }
+
+    public static boolean equals(byte[] b1, byte[] b2) {
+        if (b2.length != b1.length) {
+            System.err.println("b1.length = " + b1.length
+                    + " b2.length = " + b2.length );
+            return false;
+        }
+        return equalsBlock(b1, b2, b1.length);
+    }
+
+    /**
+     * Verify b1's partial part is same as b2. compares b1 and b2 by chopping up
+     * b1 into blocks of b1BKSize and b2 into blocks of b2BKSize, and then
+     * compare the first b2BKSize bytes of each block, return true if they equal
+     * , otherwise return false.
+     * @param b1 byte array to be compared.
+     * @param b2 saved byte array.
+     * @param b1BKSize b1's block size.
+     * @param b2BKSize b2's block size.
+     * @return true is same. false otherwise.
+     */
+    public static boolean equalsBlockPartial(byte[] b1, byte[] b2, int b1BKSize,
+            int b2BKSize) {
+        int numOfBlock = b1.length / b1BKSize;
+        for (int b = 0; b < numOfBlock; b++) {
+            for (int i = 0; i < b2BKSize; i++) {
+                int j1 = b * b1BKSize + i;
+                int j2 = b * b2BKSize + i;
+                if (b1[j1] != b2[j2]) {
+                    System.err.println("Compare failed at b1[" + j1 + "]:" +
+                            b1[j1] + " b2[" + j2 + "]:" + b2[j2]);
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Generate a byte block by given length. The content of byte block
+     * is determined by the index.
+     * @param length length of byte array
+     * @return a byte array
+     */
+    public static byte[] generateBytes(int length) {
+        byte[] bytes = new byte[length];
+        for (int i = 0; i < length; i++) {
+            bytes[i] = (byte) (i & 0xff);
+        }
+        return bytes;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/crypto/provider/Cipher/DES/TextPKCS5PaddingTest.java	Wed Jul 05 20:51:27 2017 +0200
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 8048604
+ * @summary This test checks boundary conditions for testing
+ *          ShortBufferException.
+ */
+import static java.lang.System.out;
+
+import java.security.AlgorithmParameters;
+import java.security.Provider;
+import java.security.Security;
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
+
+public class TextPKCS5PaddingTest {
+    /**
+     * Test plain text.
+     */
+    private static final byte[] PLAIN_TEXT = {
+        0b10001, 0b10001, 0b10001, 0b10001,
+        0b10001, 0b10001, 0b11,    0b11
+    };
+
+    public static void main(String[] args) throws Exception {
+        Provider provider = Security.getProvider("SunJCE");
+        if (provider == null) {
+            throw new RuntimeException("SunJCE provider not exist");
+        }
+        // generate no-padding cipher with secret key
+        Cipher c = Cipher.getInstance("DES/CBC/NoPadding", provider);
+        KeyGenerator kgen = KeyGenerator.getInstance("DES", provider);
+        SecretKey skey = kgen.generateKey();
+        // this is the improperly padded plaintext
+
+        c.init(Cipher.ENCRYPT_MODE, skey);
+        // encrypt plaintext
+        byte[] cipher = c.doFinal(PLAIN_TEXT);
+        AlgorithmParameters params = c.getParameters();
+        // generate cipher that enforces PKCS5 padding
+        c = Cipher.getInstance("DES/CBC/PKCS5Padding", provider);
+        c.init(Cipher.DECRYPT_MODE, skey, params);
+        try {
+            c.doFinal(cipher);
+            throw new RuntimeException(
+                    "ERROR: Expected BadPaddingException not thrown");
+        } catch (BadPaddingException expected) {
+            out.println("Expected BadPaddingException thrown");
+        }
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/crypto/provider/NSASuiteB/TestAESOids.java	Wed Jul 05 20:51:27 2017 +0200
@@ -0,0 +1,194 @@
+/*
+ * 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 static javax.crypto.Cipher.ENCRYPT_MODE;
+import static javax.crypto.Cipher.getMaxAllowedKeyLength;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.spec.AlgorithmParameterSpec;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.KeyGenerator;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKey;
+import javax.crypto.ShortBufferException;
+import javax.crypto.spec.IvParameterSpec;
+
+/*
+ * @test
+ * @bug 8075286
+ * @summary Test the AES algorithm OIDs in JDK.
+ *          OID and Algorithm transformation string should match.
+ *          Both could be able to be used to generate the algorithm instance.
+ * @run main TestAESOids
+ */
+public class TestAESOids {
+
+    private static final String PROVIDER_NAME = "SunJCE";
+    private static final byte[] INPUT = "1234567890123456".getBytes();
+
+    private static final List<DataTuple> DATA = Arrays.asList(
+            new DataTuple("2.16.840.1.101.3.4.1.1", "AES_128/ECB/NoPadding",
+                    128, "ECB"),
+            new DataTuple("2.16.840.1.101.3.4.1.2", "AES_128/CBC/NoPadding",
+                    128, "CBC"),
+            new DataTuple("2.16.840.1.101.3.4.1.3", "AES_128/OFB/NoPadding",
+                    128, "OFB"),
+            new DataTuple("2.16.840.1.101.3.4.1.4", "AES_128/CFB/NoPadding",
+                    128, "CFB"),
+            new DataTuple("2.16.840.1.101.3.4.1.21", "AES_192/ECB/NoPadding",
+                    192, "ECB"),
+            new DataTuple("2.16.840.1.101.3.4.1.22", "AES_192/CBC/NoPadding",
+                    192, "CBC"),
+            new DataTuple("2.16.840.1.101.3.4.1.23", "AES_192/OFB/NoPadding",
+                    192, "OFB"),
+            new DataTuple("2.16.840.1.101.3.4.1.24", "AES_192/CFB/NoPadding",
+                    192, "CFB"),
+            new DataTuple("2.16.840.1.101.3.4.1.41", "AES_256/ECB/NoPadding",
+                    256, "ECB"),
+            new DataTuple("2.16.840.1.101.3.4.1.42", "AES_256/CBC/NoPadding",
+                    256, "CBC"),
+            new DataTuple("2.16.840.1.101.3.4.1.43", "AES_256/OFB/NoPadding",
+                    256, "OFB"),
+            new DataTuple("2.16.840.1.101.3.4.1.44", "AES_256/CFB/NoPadding",
+                    256, "CFB"));
+
+    public static void main(String[] args) throws Exception {
+        for (DataTuple dataTuple : DATA) {
+            int maxAllowedKeyLength =
+                    getMaxAllowedKeyLength(dataTuple.algorithm);
+            boolean supportedKeyLength =
+                    maxAllowedKeyLength >= dataTuple.keyLength;
+
+            try {
+                runTest(dataTuple, supportedKeyLength);
+                System.out.println("passed");
+            } catch (InvalidKeyException ike) {
+                if (supportedKeyLength) {
+                    throw new RuntimeException(String.format(
+                            "The key length %d is supported, but test failed.",
+                            dataTuple.keyLength), ike);
+                } else {
+                    System.out.printf(
+                            "Catch expected InvalidKeyException due "
+                                    + "to the key length %d is greater than "
+                                    + "max supported key length %d%n",
+                            dataTuple.keyLength, maxAllowedKeyLength);
+                }
+            }
+        }
+    }
+
+    private static void runTest(DataTuple dataTuple,
+            boolean supportedKeyLength) throws NoSuchAlgorithmException,
+            NoSuchProviderException, NoSuchPaddingException,
+            InvalidKeyException, ShortBufferException,
+            IllegalBlockSizeException, BadPaddingException,
+            InvalidAlgorithmParameterException {
+        Cipher algorithmCipher = Cipher.getInstance(dataTuple.algorithm,
+                PROVIDER_NAME);
+        Cipher oidCipher = Cipher.getInstance(dataTuple.oid, PROVIDER_NAME);
+
+        if (algorithmCipher == null) {
+            throw new RuntimeException(
+                    String.format("Test failed: algorithm string %s getInstance"
+                            + " failed.%n", dataTuple.algorithm));
+        }
+
+        if (oidCipher == null) {
+            throw new RuntimeException(
+                    String.format("Test failed: OID %s getInstance failed.%n",
+                            dataTuple.oid));
+        }
+
+        if (!algorithmCipher.getAlgorithm().equals(dataTuple.algorithm)) {
+            throw new RuntimeException(String.format(
+                    "Test failed: algorithm string %s getInstance "
+                            + "doesn't generate expected algorithm.%n",
+                    dataTuple.algorithm));
+        }
+
+        KeyGenerator kg = KeyGenerator.getInstance("AES");
+        kg.init(dataTuple.keyLength);
+        SecretKey key = kg.generateKey();
+
+        // encrypt
+        algorithmCipher.init(ENCRYPT_MODE, key);
+        if (!supportedKeyLength) {
+            throw new RuntimeException(String.format(
+                    "The key length %d is not supported, so the initialization "
+                            + "of algorithmCipher should fail.%n",
+                    dataTuple.keyLength));
+        }
+
+        byte[] cipherText = new byte[algorithmCipher.getOutputSize(INPUT.length)];
+        int offset = algorithmCipher.update(INPUT, 0, INPUT.length,
+                cipherText, 0);
+        algorithmCipher.doFinal(cipherText, offset);
+
+        AlgorithmParameterSpec aps = null;
+        if (!dataTuple.mode.equalsIgnoreCase("ECB")) {
+            aps = new IvParameterSpec(algorithmCipher.getIV());
+        }
+
+        oidCipher.init(Cipher.DECRYPT_MODE, key, aps);
+        if (!supportedKeyLength) {
+            throw new RuntimeException(String.format(
+                    "The key length %d is not supported, so the "
+                            + "initialization of oidCipher should fail.%n",
+                    dataTuple.keyLength));
+        }
+
+        byte[] recoveredText = new byte[oidCipher.getOutputSize(cipherText.length)];
+        oidCipher.doFinal(cipherText, 0, cipherText.length, recoveredText);
+
+        // Comparison
+        if (!Arrays.equals(INPUT, recoveredText)) {
+            throw new RuntimeException(
+                    "Decrypted data is not the same as the original text");
+        }
+    }
+
+    private static class DataTuple {
+
+        private final String oid;
+        private final String algorithm;
+        private final int keyLength;
+        private final String mode;
+
+        private DataTuple(String oid, String algorithm, int keyLength,
+                String mode) {
+            this.oid = oid;
+            this.algorithm = algorithm;
+            this.keyLength = keyLength;
+            this.mode = mode;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/crypto/provider/NSASuiteB/TestAESWrapOids.java	Wed Jul 05 20:51:27 2017 +0200
@@ -0,0 +1,154 @@
+/*
+ * 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 static javax.crypto.Cipher.getMaxAllowedKeyLength;
+
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.KeyGenerator;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKey;
+
+/*
+ * @test
+ * @bug 8075286
+ * @summary Test the AESWrap algorithm OIDs in JDK.
+ *          OID and Algorithm transformation string should match.
+ *          Both could be able to be used to generate the algorithm instance.
+ * @run main TestAESWrapOids
+ */
+public class TestAESWrapOids {
+
+    private static final String PROVIDER_NAME = "SunJCE";
+
+    private static final List<DataTuple> DATA = Arrays.asList(
+            new DataTuple("2.16.840.1.101.3.4.1.5", "AESWrap_128", 128),
+            new DataTuple("2.16.840.1.101.3.4.1.25", "AESWrap_192", 192),
+            new DataTuple("2.16.840.1.101.3.4.1.45", "AESWrap_256", 256));
+
+    public static void main(String[] args) throws Exception {
+        for (DataTuple dataTuple : DATA) {
+            int maxAllowedKeyLength = getMaxAllowedKeyLength(
+                    dataTuple.algorithm);
+            boolean supportedKeyLength =
+                    maxAllowedKeyLength >= dataTuple.keyLength;
+
+            try {
+                runTest(dataTuple, supportedKeyLength);
+                System.out.println("passed");
+            } catch (InvalidKeyException ike) {
+                if (supportedKeyLength) {
+                    throw new RuntimeException(String.format(
+                            "The key length %d is supported, but test failed.",
+                            dataTuple.keyLength), ike);
+                } else {
+                    System.out.printf(
+                            "Catch expected InvalidKeyException "
+                                    + "due to the key length %d is greater "
+                                    + "than max supported key length %d%n",
+                            dataTuple.keyLength, maxAllowedKeyLength);
+                }
+            }
+        }
+    }
+
+    private static void runTest(DataTuple dataTuple, boolean supportedKeyLength)
+            throws NoSuchAlgorithmException, NoSuchProviderException,
+            NoSuchPaddingException, InvalidKeyException,
+            IllegalBlockSizeException {
+        Cipher algorithmCipher = Cipher.getInstance(
+                dataTuple.algorithm, PROVIDER_NAME);
+        Cipher oidCipher = Cipher.getInstance(dataTuple.oid, PROVIDER_NAME);
+
+        if (algorithmCipher == null) {
+            throw new RuntimeException(String.format(
+                    "Test failed: algorithm string %s getInstance failed.%n",
+                    dataTuple.algorithm));
+        }
+
+        if (oidCipher == null) {
+            throw new RuntimeException(
+                    String.format("Test failed: OID %s getInstance failed.%n",
+                            dataTuple.oid));
+        }
+
+        if (!algorithmCipher.getAlgorithm().equals(
+                dataTuple.algorithm)) {
+            throw new RuntimeException(String.format(
+                    "Test failed: algorithm string %s getInstance "
+                            + "doesn't generate expected algorithm.%n",
+                    dataTuple.oid));
+        }
+
+        KeyGenerator kg = KeyGenerator.getInstance("AES");
+        kg.init(dataTuple.keyLength);
+        SecretKey key = kg.generateKey();
+
+        // Wrap the key
+        algorithmCipher.init(Cipher.WRAP_MODE, key);
+        if (!supportedKeyLength) {
+            throw new RuntimeException(String.format(
+                    "The key length %d is not supported, so the initialization"
+                            + " of algorithmCipher should fail.%n",
+                    dataTuple.keyLength));
+        }
+
+        // Unwrap the key
+        oidCipher.init(Cipher.UNWRAP_MODE, key);
+        if (!supportedKeyLength) {
+            throw new RuntimeException(String.format(
+                    "The key length %d is not supported, so the initialization"
+                            + " of oidCipher should fail.%n",
+                    dataTuple.keyLength));
+        }
+
+        byte[] keyWrapper = algorithmCipher.wrap(key);
+        Key unwrappedKey = oidCipher.unwrap(keyWrapper, "AES",
+                Cipher.SECRET_KEY);
+
+        // Comparison
+        if (!Arrays.equals(key.getEncoded(), unwrappedKey.getEncoded())) {
+            throw new RuntimeException("Key comparison failed");
+        }
+    }
+
+    private static class DataTuple {
+
+        private final String oid;
+        private final String algorithm;
+        private final int keyLength;
+
+        private DataTuple(String oid, String algorithm, int keyLength) {
+            this.oid = oid;
+            this.algorithm = algorithm;
+            this.keyLength = keyLength;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/crypto/provider/NSASuiteB/TestHmacSHAOids.java	Wed Jul 05 20:51:27 2017 +0200
@@ -0,0 +1,116 @@
+/*
+ * 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.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.crypto.KeyGenerator;
+import javax.crypto.Mac;
+import javax.crypto.SecretKey;
+
+/*
+ * @test
+ * @bug 8075286
+ * @summary Test the HmacSHA algorithm OIDs in JDK.
+ *          OID and Algorithm transformation string should match.
+ *          Both could be able to be used to generate the algorithm instance.
+ * @run main TestHmacSHAOids
+ */
+public class TestHmacSHAOids {
+
+    private static final String PROVIDER_NAME = "SunJCE";
+    private static final byte[] INPUT = "1234567890".getBytes();
+
+    private static final List<DataTuple> DATA = Arrays.asList(
+            new DataTuple("1.2.840.113549.2.7", "HmacSHA1"),
+            new DataTuple("1.2.840.113549.2.8", "HmacSHA224"),
+            new DataTuple("1.2.840.113549.2.9", "HmacSHA256"),
+            new DataTuple("1.2.840.113549.2.10", "HmacSHA384"),
+            new DataTuple("1.2.840.113549.2.11", "HmacSHA512"));
+
+    public static void main(String[] args) throws Exception {
+        for (DataTuple dataTuple : DATA) {
+            runTest(dataTuple);
+            System.out.println("passed");
+        }
+        System.out.println("All tests passed");
+    }
+
+    private static void runTest(DataTuple dataTuple)
+            throws NoSuchAlgorithmException, NoSuchProviderException,
+            InvalidKeyException {
+        Mac mcAlgorithm = Mac.getInstance(dataTuple.algorithm,
+                PROVIDER_NAME);
+        Mac mcOid = Mac.getInstance(dataTuple.oid, PROVIDER_NAME);
+
+        if (mcAlgorithm == null) {
+            throw new RuntimeException(String.format(
+                    "Test failed: Mac using algorithm "
+                            + "string %s getInstance failed.%n",
+                    dataTuple.algorithm));
+        }
+
+        if (mcOid == null) {
+            throw new RuntimeException(String.format(
+                    "Test failed: Mac using OID %s getInstance failed.%n",
+                    dataTuple.oid));
+        }
+
+        if (!mcAlgorithm.getAlgorithm().equals(dataTuple.algorithm)) {
+            throw new RuntimeException(String.format(
+                    "Test failed: Mac using algorithm string %s getInstance "
+                            + "doesn't generate expected algorithm.%n",
+                    dataTuple.algorithm));
+        }
+
+        KeyGenerator kg = KeyGenerator.getInstance(dataTuple.algorithm,
+                PROVIDER_NAME);
+        SecretKey key = kg.generateKey();
+
+        mcAlgorithm.init(key);
+        mcAlgorithm.update(INPUT);
+
+        mcOid.init(key);
+        mcOid.update(INPUT);
+
+        // Comparison
+        if (!Arrays.equals(mcAlgorithm.doFinal(), mcOid.doFinal())) {
+            throw new RuntimeException("Digest comparison failed: "
+                    + "the two MACs are not the same");
+        }
+    }
+
+    private static class DataTuple {
+
+        private final String oid;
+        private final String algorithm;
+
+        private DataTuple(String oid, String algorithm) {
+            this.oid = oid;
+            this.algorithm = algorithm;
+        }
+    }
+}
--- a/jdk/test/com/sun/jndi/ldap/LdapTimeoutTest.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/jdk/test/com/sun/jndi/ldap/LdapTimeoutTest.java	Wed Jul 05 20:51:27 2017 +0200
@@ -412,11 +412,14 @@
 
             // run the ReadServerTest with connect / read timeouts set
             // this should exit after the connect timeout expires
-            System.out.println("Running read timeout test with 10ms connect timeout, 3000ms read timeout");
-            Hashtable env4 = createEnv();
-            env4.put("com.sun.jndi.ldap.connect.timeout", "10");
-            env4.put("com.sun.jndi.ldap.read.timeout", "3000");
-            results.add(testPool.submit(new ReadServerTimeoutTest(env4)));
+            //
+            // NOTE: commenting this test out as it is failing intermittently.
+            //
+            // System.out.println("Running read timeout test with 10ms connect timeout, 3000ms read timeout");
+            // Hashtable env4 = createEnv();
+            // env4.put("com.sun.jndi.ldap.connect.timeout", "10");
+            // env4.put("com.sun.jndi.ldap.read.timeout", "3000");
+            // results.add(testPool.submit(new ReadServerTimeoutTest(env4)));
 
             // run the DeadServerTest with connect timeout set
             // this should exit after the connect timeout expires
--- a/jdk/test/java/lang/ProcessBuilder/Basic.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/jdk/test/java/lang/ProcessBuilder/Basic.java	Wed Jul 05 20:51:27 2017 +0200
@@ -738,7 +738,7 @@
      * Remove it from the list of env variables
      */
     private static String removeAixExpectedVars(String vars) {
-        return vars.replace("AIXTHREAD_GUARDPAGES=0,","");
+        return vars.replace("AIXTHREAD_GUARDPAGES=0,", "");
     }
 
     private static String sortByLinesWindowsly(String text) {
@@ -785,8 +785,8 @@
                 equal(entry.getKey(), key);
                 equal(entry.getValue(), value);
             }
-            check(! kIter.hasNext() &&
-                  ! vIter.hasNext());
+            check(!kIter.hasNext() &&
+                    !vIter.hasNext());
 
         } catch (Throwable t) { unexpected(t); }
     }
@@ -815,9 +815,9 @@
 
     static void checkRedirects(ProcessBuilder pb,
                                Redirect in, Redirect out, Redirect err) {
-        equal(pb.redirectInput(),  in);
+        equal(pb.redirectInput(), in);
         equal(pb.redirectOutput(), out);
-        equal(pb.redirectError(),  err);
+        equal(pb.redirectError(), err);
     }
 
     static void redirectIO(ProcessBuilder pb,
@@ -862,6 +862,7 @@
         Redirect[] redirects =
             { PIPE,
               INHERIT,
+              DISCARD,
               Redirect.from(ifile),
               Redirect.to(ifile),
               Redirect.appendTo(ifile),
@@ -884,6 +885,10 @@
         equal(INHERIT.toString(), "INHERIT");
         equal(INHERIT.file(), null);
 
+        equal(DISCARD.type(), Redirect.Type.WRITE);
+        equal(DISCARD.toString(), "WRITE");
+        equal(DISCARD.file(), new File((Windows.is() ? "NUL" : "/dev/null")));
+
         equal(Redirect.from(ifile).type(), Redirect.Type.READ);
         equal(Redirect.from(ifile).toString(),
               "redirect to read from file \"ifile\"");
@@ -926,6 +931,12 @@
         checkRedirects(pb, INHERIT, INHERIT, INHERIT);
 
         //----------------------------------------------------------------
+        // Check DISCARD for stdout,stderr
+        //----------------------------------------------------------------
+        redirectIO(pb, INHERIT, DISCARD, DISCARD);
+        checkRedirects(pb, INHERIT, DISCARD, DISCARD);
+
+        //----------------------------------------------------------------
         // Check setters and getters agree
         //----------------------------------------------------------------
         pb.redirectInput(ifile);
@@ -943,7 +954,8 @@
         THROWS(IllegalArgumentException.class,
                () -> pb.redirectInput(Redirect.to(ofile)),
                () -> pb.redirectOutput(Redirect.from(ifile)),
-               () -> pb.redirectError(Redirect.from(ifile)));
+               () -> pb.redirectError(Redirect.from(ifile)),
+               () -> pb.redirectInput(DISCARD));
 
         THROWS(NullPointerException.class,
                 () -> pb.redirectInput((File)null),
@@ -980,7 +992,7 @@
             ProcessResults r = run(pb);
             equal(r.exitValue(), 0);
             equal(fileContents(ofile),
-                  "standard error" + "standard output");
+                    "standard error" + "standard output");
             equal(fileContents(efile), "");
             equal(r.out(), "");
             equal(r.err(), "");
@@ -1051,6 +1063,79 @@
         }
 
         //----------------------------------------------------------------
+        // DISCARDing output
+        //----------------------------------------------------------------
+        {
+            setFileContents(ifile, "standard input");
+            pb.redirectOutput(DISCARD);
+            pb.redirectError(DISCARD);
+            ProcessResults r = run(pb);
+            equal(r.exitValue(), 0);
+            equal(r.out(), "");
+            equal(r.err(), "");
+        }
+
+        //----------------------------------------------------------------
+        // DISCARDing output and redirecting error
+        //----------------------------------------------------------------
+        {
+            setFileContents(ifile, "standard input");
+            setFileContents(ofile, "ofile-contents");
+            setFileContents(efile, "efile-contents");
+            pb.redirectOutput(DISCARD);
+            pb.redirectError(efile);
+            ProcessResults r = run(pb);
+            equal(r.exitValue(), 0);
+            equal(fileContents(ofile), "ofile-contents");
+            equal(fileContents(efile), "standard error");
+            equal(r.out(), "");
+            equal(r.err(), "");
+            ofile.delete();
+            efile.delete();
+        }
+
+        //----------------------------------------------------------------
+        // DISCARDing error and redirecting output
+        //----------------------------------------------------------------
+        {
+            setFileContents(ifile, "standard input");
+            setFileContents(ofile, "ofile-contents");
+            setFileContents(efile, "efile-contents");
+            pb.redirectOutput(ofile);
+            pb.redirectError(DISCARD);
+            ProcessResults r = run(pb);
+            equal(r.exitValue(), 0);
+            equal(fileContents(ofile), "standard output");
+            equal(fileContents(efile), "efile-contents");
+            equal(r.out(), "");
+            equal(r.err(), "");
+            ofile.delete();
+            efile.delete();
+        }
+
+        //----------------------------------------------------------------
+        // DISCARDing output and merging error into output
+        //----------------------------------------------------------------
+        {
+            setFileContents(ifile, "standard input");
+            setFileContents(ofile, "ofile-contents");
+            setFileContents(efile, "efile-contents");
+            pb.redirectOutput(DISCARD);
+            pb.redirectErrorStream(true);
+            pb.redirectError(efile);
+            ProcessResults r = run(pb);
+            equal(r.exitValue(), 0);
+            equal(fileContents(ofile), "ofile-contents");   // untouched
+            equal(fileContents(efile), "");                 // empty
+            equal(r.out(), "");
+            equal(r.err(), "");
+            ifile.delete();
+            ofile.delete();
+            efile.delete();
+            pb.redirectErrorStream(false);                  // reset for next test
+        }
+
+        //----------------------------------------------------------------
         // Testing INHERIT is harder.
         // Note that this requires __FOUR__ nested JVMs involved in one test,
         // if you count the harness JVM.
--- a/jdk/test/java/lang/StrictMath/HypotTests.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/jdk/test/java/lang/StrictMath/HypotTests.java	Wed Jul 05 20:51:27 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -42,9 +42,37 @@
 public class HypotTests {
     private HypotTests(){}
 
+    /**
+     * The hypot implementation is commutative, {@code hypot(a, b) ==
+     * hypot(b, a)}, and independent of sign, {@code hypot(a, b) ==
+     * hypot(-a, b) == hypot(a, -b) == hypot(-a, -b)}.
+     */
     static int testHypotCase(double input1, double input2, double expected) {
-        return Tests.test("StrictMath.hypot(double)", input1, input2,
-                          StrictMath.hypot(input1, input2), expected);
+        int failures = 0;
+        failures += Tests.test("StrictMath.hypot(double)", input1, input2,
+                               StrictMath.hypot(input1, input2), expected);
+
+        failures += Tests.test("StrictMath.hypot(double)", input2, input1,
+                          StrictMath.hypot(input2, input1), expected);
+
+        failures += Tests.test("StrictMath.hypot(double)", -input1, input2,
+                               StrictMath.hypot(-input1, input2), expected);
+
+        failures += Tests.test("StrictMath.hypot(double)", input2, -input1,
+                          StrictMath.hypot(input2, -input1), expected);
+
+        failures += Tests.test("StrictMath.hypot(double)", input1, -input2,
+                               StrictMath.hypot(input1, -input2), expected);
+
+        failures += Tests.test("StrictMath.hypot(double)", -input2, input1,
+                          StrictMath.hypot(-input2, input1), expected);
+
+        failures += Tests.test("StrictMath.hypot(double)", -input1, -input2,
+                               StrictMath.hypot(-input1, -input2), expected);
+
+        failures +=  Tests.test("StrictMath.hypot(double)", -input2, -input1,
+                          StrictMath.hypot(-input2, -input1), expected);
+        return failures;
     }
 
     static int testHypot() {
@@ -611,21 +639,60 @@
             {0x1.8p1,   0x1.8bffffffffff6p6,    0x1.8c2e88e6f44b1p6},
             {0x1.8p1,   0x1.8ffffffffffe8p6,    0x1.902e11d3b5549p6},
             {0x1.8p1,   0x1.8fffffffffffep6,    0x1.902e11d3b556p6},
+
+            // Test near decision points of the fdlibm algorithm
+            {0x1.0000000000001p501,   0x1.000000000000p501,    0x1.6a09e667f3bcdp501},
+            {0x1.0p501,               0x1.0p499,               0x1.07e0f66afed07p501},
+
+            {0x1.0p500,               0x1.0p450,               0x1.0p500},
+            {0x1.0000000000001p500,   0x1.0p450,               0x1.0000000000001p500},
+
+            {0x1.0p500,               0x1.0p440,               0x1.0p500},
+            {0x1.0000000000001p500,   0x1.0p440,               0x1.0000000000001p500},
+            {0x1.0p500,               0x1.0p439,               0x1.0p500},
+            {0x1.0000000000001p500,   0x1.0p439,               0x1.0000000000001p500},
+
+            {0x1.0p-450,              0x1.0p-500,              0x1.0p-450},
+            {0x1.0000000000001p-450,  0x1.0p-500,              0x1.0000000000001p-450},
+            {0x1.0p-450,              0x1.fffffffffffffp-499,  0x1.0p-450},
+            {0x1.0000000000001p-450,  0x1.fffffffffffffp-499,  0x1.0000000000001p-450},
+
+
+            {0x1.0p-450,              0x1.0p-500,              0x1.0p-450},
+            {0x1.0000000000001p-450,  0x1.0p-500,              0x1.0000000000001p-450},
+            {0x1.0p-450,              0x1.fffffffffffffp-499,  0x1.0p-450},
+            {0x1.0000000000001p-450,  0x1.fffffffffffffp-499,  0x1.0000000000001p-450},
+
+            // 0x1.0p-1022 is MIN_NORMAL
+            {0x1.0000000000001p-1022, 0x1.0000000000001p-1022, 0x1.6a09e667f3bcep-1022},
+            {0x1.0000000000001p-1022, 0x1.0p-1022,             0x1.6a09e667f3bcdp-1022},
+            {0x1.0000000000001p-1022, 0x0.fffffffffffffp-1022, 0x1.6a09e667f3bcdp-1022},
+            {0x1.0000000000001p-1022, 0x0.0000000000001P-1022, 0x1.0000000000001p-1022},
+            {0x1.0000000000001p-1022, 0.0,                     0x1.0000000000001p-1022},
+
+            {0x1.0000000000000p-1022, 0x0.fffffffffffffp-1022, 0x1.6a09e667f3bccp-1022},
+            {0x1.0000000000000p-1021, 0x0.fffffffffffffp-1022, 0x1.1e3779b97f4a8p-1021},
+            {0x1.0000000000000p-1020, 0x0.fffffffffffffp-1022, 0x1.07e0f66afed07p-1020},
+
+            // 0x0.0000000000001P-1022 is MIN_VALUE (smallest nonzero number)
+            {0x0.0000000000001p-1022, 0x0.0000000000001p-1022, 0x0.0000000000001p-1022},
+            {0x0.0000000000002p-1022, 0x0.0000000000001p-1022, 0x0.0000000000002p-1022},
+            {0x0.0000000000003p-1022, 0x0.0000000000002p-1022, 0x0.0000000000004p-1022},
         };
 
         for (double[] testCase: testCases)
-            failures+=testHypotCase(testCase[0], testCase[1], testCase[2]);
+            failures += testHypotCase(testCase[0], testCase[1], testCase[2]);
 
         return failures;
     }
 
-    public static void main(String [] argv) {
+    public static void main(String... args) {
         int failures = 0;
 
         failures += testHypot();
 
         if (failures > 0) {
-            System.err.println("Testing log1p incurred "
+            System.err.println("Testing hypot incurred "
                                + failures + " failures.");
             throw new RuntimeException();
         }
--- a/jdk/test/java/lang/invoke/LFCaching/LFMultiThreadCachingTest.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/jdk/test/java/lang/invoke/LFCaching/LFMultiThreadCachingTest.java	Wed Jul 05 20:51:27 2017 +0200
@@ -32,7 +32,7 @@
  * @build LambdaFormTestCase
  * @build LFCachingTestCase
  * @build LFMultiThreadCachingTest
- * @run main/othervm LFMultiThreadCachingTest
+ * @run main/othervm -Djava.lang.invoke.MethodHandle.OBSERVE_BMH_SPECIES_CREATION=true LFMultiThreadCachingTest
  */
 
 import java.lang.invoke.MethodHandle;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/channels/FileChannel/LoopingTruncate.java	Wed Jul 05 20:51:27 2017 +0200
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8137121
+ * @summary (fc) Infinite loop FileChannel.truncate
+ * @run main/othervm LoopingTruncate
+ */
+
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import static java.nio.file.StandardOpenOption.*;
+
+public class LoopingTruncate {
+
+    // (int)FATEFUL_SIZE == -3 == IOStatus.INTERRUPTED
+    static long FATEFUL_SIZE = 0x1FFFFFFFDL;
+
+    static long TIMEOUT = 10_000; // 10 seconds
+
+    public static void main(String[] args) throws Throwable {
+        Path path = Files.createTempFile("LoopingTruncate.tmp", null);
+        try {
+            Thread th = new Thread(() -> {
+                try (FileChannel fc = FileChannel.open(path, CREATE, WRITE)) {
+                    fc.position(FATEFUL_SIZE + 1L);
+                    fc.write(ByteBuffer.wrap(new byte[] {0}));
+                    fc.truncate(FATEFUL_SIZE);
+                } catch (Exception e) {
+                    throw new RuntimeException(e);
+                }});
+            th.start();
+            th.join(TIMEOUT);
+
+            if (th.isAlive()) {
+                th.interrupt();
+                throw new RuntimeException("Failed to complete on time");
+            }
+        } finally {
+            Files.deleteIfExists(path);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/security/Policy/ExtensiblePolicy/ExtensiblePolicyTest.java	Wed Jul 05 20:51:27 2017 +0200
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import TVJar.TVPermission;
+import java.security.AccessController;
+
+/**
+ * @test @bug 8050402
+ * @summary Check policy is extensible with user defined permissions
+ * @run main/othervm/policy=ExtensiblePolicyTest1.policy
+ *      ExtensiblePolicyTest false
+ * @run main/othervm/policy=ExtensiblePolicyTest2.policy
+ *      ExtensiblePolicyTest true
+ * @run main/othervm/policy=ExtensiblePolicyTest3.policy
+ *      ExtensiblePolicyTest true
+ */
+public class ExtensiblePolicyTest {
+
+    public static void main(String args[]) throws Throwable {
+        // ExtensiblePolicyTest1.policy: policy file grants permission to
+        // watch TVChannel 3-6
+        // ExtensiblePolicyTest2.policy: policy file grants permission to
+        // watch TVChanel 4
+        // ExtensiblePolicyTest3.policy: policy file grants permission signed
+        // by duke2 to watch TVChanel 5
+
+        TVPermission perm = new TVPermission("channel:5", "watch");
+        boolean getException = false;
+        String exceptionMessage = null;
+        boolean expectException = Boolean.parseBoolean(args[0]);
+        try {
+            AccessController.checkPermission(perm);
+        } catch (SecurityException se) {
+            getException = true;
+            exceptionMessage = se.getMessage();
+        }
+
+        if (expectException ^ getException) {
+            throw new RuntimeException("Test Failed: expectException = "
+                    + expectException + " getException = " + getException
+                    + "\n" + exceptionMessage);
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/security/Policy/ExtensiblePolicy/ExtensiblePolicyTest1.policy	Wed Jul 05 20:51:27 2017 +0200
@@ -0,0 +1,4 @@
+grant {
+	permission TVJar.TVPermission "channel:3-6", "watch";
+};
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/security/Policy/ExtensiblePolicy/ExtensiblePolicyTest2.policy	Wed Jul 05 20:51:27 2017 +0200
@@ -0,0 +1,3 @@
+grant {
+	permission TVJar.TVPermission "channel:4", "watch";
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/security/Policy/ExtensiblePolicy/ExtensiblePolicyTest3.policy	Wed Jul 05 20:51:27 2017 +0200
@@ -0,0 +1,5 @@
+keystore "file:${user.dir}/epkeystore";
+
+grant {
+	permission TVJar.TVPermission "channel:5", "watch", SignedBy "duke2";
+};
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/security/Policy/ExtensiblePolicy/ExtensiblePolicyWithJarTest.java	Wed Jul 05 20:51:27 2017 +0200
@@ -0,0 +1,113 @@
+/*
+ * 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 TVJar.TVPermission;
+import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.security.AccessController;
+import jdk.testlibrary.ProcessTools;
+import jdk.testlibrary.JarUtils;
+
+/**
+ * @test
+ * @bug 8050402
+ * @summary Check policy is extensible with user defined permissions
+ * @library /lib/testlibrary
+ * @compile TVJar/TVPermission.java
+ * @run main ExtensiblePolicyWithJarTest
+ */
+public class ExtensiblePolicyWithJarTest {
+
+    public static void main(String args[]) throws Throwable {
+        final String FS = File.separator;
+        final String PS = File.pathSeparator;
+        final String POL = "ExtensiblePolicyTest3.policy";
+        final String JAVA_HOME = System.getProperty("test.jdk");
+        final String KEYTOOL = JAVA_HOME + FS + "bin" + FS + "keytool";
+        final String JARSIGNER = JAVA_HOME + FS + "bin" + FS + "jarsigner";
+        final String KEYSTORE = "epkeystore";
+        final String PASSWORD = "password";
+        final String ALIAS = "duke2";
+        final String CLASSPATH = System.getProperty("test.class.path", "");
+        final String TESTCLASSES = System.getProperty("test.classes", "");
+        final String TVPERMJAR = "tvPerm.jar";
+        final String PATHTOJAR = System.getProperty("user.dir", "")
+                                + FS + TVPERMJAR;
+
+        // create jar file for TVpermission
+        new File("TVJar").mkdir();
+        Files.copy(Paths.get(TESTCLASSES + FS + "TVJar", "TVPermission.class"),
+                Paths.get("TVJar", "TVPermission.class"));
+        Files.copy(Paths.get(TESTCLASSES + FS + "TVJar",
+                "TVPermissionCollection.class"),
+                Paths.get("TVJar", "TVPermissionCollection.class"));
+        JarUtils.createJar(TVPERMJAR, "TVJar/TVPermission.class",
+                "TVJar/TVPermissionCollection.class");
+
+        // create key pair for jar signing
+        ProcessTools.executeCommand(KEYTOOL,
+                "-genkey",
+                "-alias", ALIAS,
+                "-keystore", KEYSTORE,
+                "-storetype", "JKS",
+                "-keypass", PASSWORD,
+                "-dname", "cn=Blah",
+                "-storepass", PASSWORD
+        ).shouldHaveExitValue(0);
+        // sign jar
+        ProcessTools.executeCommand(JARSIGNER,
+                "-keystore", KEYSTORE,
+                "-storepass", PASSWORD,
+                "-keypass", PASSWORD,
+                TVPERMJAR,
+                ALIAS).shouldHaveExitValue(0);
+        // add jar file to classpath
+        String cp = PATHTOJAR + PS + CLASSPATH;
+
+        // policy file grants permission signed by duke2 to watch TVChanel 5
+        try {
+            String[] cmd = {
+            "-classpath", cp,
+            "-Djava.security.manager",
+            "-Djava.security.policy=" + POL,
+            "ExtensiblePolicyTest_orig$TestMain"};
+            ProcessTools.executeTestJvm(cmd).shouldHaveExitValue(0);
+        } catch (Exception ex) {
+            System.out.println("ExtensiblePolicyWithJarTest Failed");
+        }
+
+    }
+
+    public static class TestMain {
+        public static void main(String args[]) {
+            TVPermission perm = new TVPermission("channel:5", "watch");
+            try {
+                AccessController.checkPermission(perm);
+            } catch (SecurityException se) {
+                throw new RuntimeException(se);
+            }
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/security/Policy/ExtensiblePolicy/TVJar/TVPermission.java	Wed Jul 05 20:51:27 2017 +0200
@@ -0,0 +1,358 @@
+/*
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package TVJar;
+
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.StringJoiner;
+import java.util.StringTokenizer;
+
+public class TVPermission extends Permission {
+
+    /**
+     * Watch
+     */
+    private final static int WATCH = 0x1;
+
+    /**
+     * Preview
+     */
+    private final static int PREVIEW = 0x2;
+
+    /**
+     * No actions
+     */
+    private final static int NONE = 0x0;
+
+    /**
+     * All actions
+     */
+    private final static int ALL = WATCH | PREVIEW;
+
+    // the actions mask
+    private int mask;
+
+    // the actions string
+    private String actions;
+
+    // the canonical name of the channel
+    private String cname;
+
+    // true if the channelname is a wildcard
+    private boolean wildcard;
+
+    // num range on channel
+    private int[] numrange;
+
+    // various num constants
+    private final static int NUM_MIN = 1;
+    private final static int NUM_MAX = 128;
+
+    public TVPermission(String channel, String action) {
+        this(channel, getMask(action));
+    }
+
+    TVPermission(String channel, int mask) {
+        super(channel);
+        init(channel, mask);
+    }
+
+    private synchronized int[] parseNum(String num)
+            throws Exception {
+
+        if (num == null || num.equals("") || num.equals("*")) {
+            wildcard = true;
+            return new int[]{NUM_MIN, NUM_MAX};
+        }
+
+        int dash = num.indexOf('-');
+
+        if (dash == -1) {
+            int p = 0;
+            try {
+                p = Integer.parseInt(num);
+            } catch (NumberFormatException nfe) {
+                throw new IllegalArgumentException("invalid input" + num);
+            }
+            return new int[]{p, p};
+        } else {
+            String low = num.substring(0, dash);
+            String high = num.substring(dash + 1);
+            int l, h;
+
+            if (low.equals("")) {
+                l = NUM_MIN;
+            } else {
+                try {
+                    l = Integer.parseInt(low);
+                } catch (NumberFormatException nfe) {
+                    throw new IllegalArgumentException("invalid input" + num);
+                }
+            }
+
+            if (high.equals("")) {
+                h = NUM_MAX;
+            } else {
+                try {
+                    h = Integer.parseInt(high);
+                } catch (NumberFormatException nfe) {
+                    throw new IllegalArgumentException("invalid input" + num);
+                }
+            }
+            if (h < l || l < NUM_MIN || h > NUM_MAX) {
+                throw new IllegalArgumentException("invalid num range");
+            }
+
+            return new int[]{l, h};
+        }
+    }
+
+    /**
+     * Initialize the TVPermission object.
+     */
+    private synchronized void init(String channel, int mask) {
+
+        // Parse the channel name.
+        int sep = channel.indexOf(':');
+
+        if (sep != -1) {
+            String num = channel.substring(sep + 1);
+            cname = channel.substring(0, sep);
+            try {
+                numrange = parseNum(num);
+            } catch (Exception e) {
+                throw new IllegalArgumentException("invalid num range: " + num);
+            }
+        } else {
+            numrange = new int[]{NUM_MIN, NUM_MAX};
+        }
+    }
+
+    /**
+     * Convert an action string to an integer actions mask.
+     *
+     * @param action the action string
+     * @return the action mask
+     */
+    private synchronized static int getMask(String action) {
+        int mask = NONE;
+
+        if (action == null) {
+            return mask;
+        }
+
+        StringTokenizer st = new StringTokenizer(action.toLowerCase(), ",");
+        while (st.hasMoreTokens()) {
+            String token = st.nextToken();
+            if (token.equals("watch")) {
+                mask |= WATCH;
+            } else if (token.equals("preview")) {
+                mask |= PREVIEW;
+            } else {
+                throw new IllegalArgumentException("invalid TV permission: " + token);
+            }
+        }
+        return mask;
+    }
+
+    @Override
+    public boolean implies(Permission p) {
+        if (!(p instanceof TVPermission)) {
+            return false;
+        }
+
+        if (this.wildcard) {
+            return true;
+        }
+
+        TVPermission that = (TVPermission) p;
+
+        if ((this.mask & that.mask) != that.mask) {
+            System.out.println("Masks are not ok this = "
+                    + this.mask + "THat = " + that.mask);
+            return false;
+        }
+
+        if ((this.numrange[0] > that.numrange[0])
+                || (this.numrange[1] < that.numrange[1])) {
+
+            System.out.println("This 0= " + this.numrange[0]
+                    + " 1 = " + this.numrange[1]);
+            System.out.println("That 0= " + that.numrange[0]
+                    + " 1 = " + that.numrange[1]);
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Checks two TVPermission objects for equality.
+     * <p>
+     * @param obj the object we are testing for equality.
+     * @return true if obj is a TVPermission, and has the same channelname and
+     * action mask as this TVPermission object.
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+
+        if (!(obj instanceof TVPermission)) {
+            return false;
+        }
+
+        TVPermission that = (TVPermission) obj;
+
+        // check the mask first
+        if (this.mask != that.mask) {
+            return false;
+        }
+
+        // now check the num range...
+        if ((this.numrange[0] != that.numrange[0])
+                || (this.numrange[1] != that.numrange[1])) {
+            return false;
+        }
+
+        return this.getName().equals(that.getName());
+    }
+
+    /**
+     * Returns the hash code value for this object.
+     *
+     * @return a hash code value for this object.
+     */
+    @Override
+    public int hashCode() {
+        return this.getName().hashCode();
+    }
+
+    /**
+     * Return the canonical string representation of the actions. Always returns
+     * actions in the following order: watch,preview.
+     *
+     * @param mask a specific integer action mask to translate into a string
+     * @return the canonical string representation of the actions
+     */
+    private synchronized static String getActions(int mask) {
+        StringJoiner sj = new StringJoiner(",");
+        if ((mask & WATCH) == WATCH) {
+            sj.add("watch");
+        }
+        if ((mask & PREVIEW) == PREVIEW) {
+            sj.add("preview");
+        }
+        return sj.toString();
+    }
+
+    /**
+     * Return the canonical string representation of the actions. Always returns
+     * actions in the following order: watch,preview.
+     *
+     * @return the canonical string representation of the actions.
+     */
+    @Override
+    public String getActions() {
+        if (actions == null) {
+            actions = getActions(this.mask);
+        }
+
+        return actions;
+    }
+
+    @Override
+    public String toString() {
+        return super.toString() + "\n"
+                + "cname = " + cname + "\n"
+                + "wildcard = " + wildcard + "\n"
+                + "numrange = " + numrange[0] + "," + numrange[1] + "\n";
+
+    }
+
+    @Override
+    public PermissionCollection newPermissionCollection() {
+        return new TVPermissionCollection();
+    }
+}
+
+final class TVPermissionCollection extends PermissionCollection {
+
+    /**
+     * The TVPermissions for this set.
+     */
+    private final ArrayList<TVPermission> permissions = new ArrayList<>();
+
+    /**
+     * Adds a permission to the TVPermissions. The key for the hash is the name
+     * in the case of wildcards, or all the IP addresses.
+     *
+     * @param permission the Permission object to add.
+     */
+    @Override
+    public void add(Permission permission) {
+        if (!(permission instanceof TVPermission)) {
+            throw new IllegalArgumentException("invalid permission: " + permission);
+        }
+        permissions.add((TVPermission) permission);
+    }
+
+    /**
+     * Check and see if this collection of permissions implies the permissions
+     * expressed in "permission".
+     *
+     * @param p the Permission object to compare
+     *
+     * @return true if "permission" is a proper subset of a permission in the
+     * collection, false if not.
+     */
+    @Override
+    public boolean implies(Permission p) {
+        if (!(p instanceof TVPermission)) {
+            return false;
+        }
+
+        Iterator<TVPermission> i = permissions.iterator();
+        while (i.hasNext()) {
+            if (((TVPermission) i.next()).implies(p)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Returns an enumeration of all the TVPermission objects in the container.
+     *
+     * @return an enumeration of all the TVPermission objects.
+     */
+    @Override
+    public Enumeration elements() {
+        return Collections.enumeration(permissions);
+    }
+
+}
--- a/jdk/test/java/util/TimeZone/CLDRDisplayNamesTest.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/jdk/test/java/util/TimeZone/CLDRDisplayNamesTest.java	Wed Jul 05 20:51:27 2017 +0200
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8005471 8008577 8129881 8130845
+ * @bug 8005471 8008577 8129881 8130845 8136518
  * @run main/othervm -Djava.locale.providers=CLDR CLDRDisplayNamesTest
  * @summary Make sure that localized time zone names of CLDR are used
  * if specified.
@@ -93,7 +93,7 @@
 
         // for 8129881
         tz = TimeZone.getTimeZone("Europe/Vienna");
-        String name = tz.getDisplayName(false, SHORT);
+        String name = tz.getDisplayName(false, SHORT, Locale.ENGLISH);
         if (!"CET".equals(name)) {
             System.err.printf("error: got '%s' expected 'CET' %n", name);
             errors++;
--- a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/CountTest.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/CountTest.java	Wed Jul 05 20:51:27 2017 +0200
@@ -31,6 +31,7 @@
 
 import java.util.HashSet;
 import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.Collectors;
 import java.util.stream.DoubleStream;
 import java.util.stream.DoubleStreamTestDataProvider;
 import java.util.stream.IntStream;
@@ -61,6 +62,12 @@
                 expectedResult(expectedCount).
                 exercise();
 
+        // Test counting collector
+        withData(data).
+                terminal(s -> s, s -> s.collect(Collectors.counting())).
+                expectedResult(expectedCount).
+                exercise();
+
         // Test with stateful distinct op that is a barrier or lazy
         // depending if source is not already distinct and encounter order is
         // preserved or not
--- a/jdk/test/javax/crypto/KeyGenerator/TestKGParity.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/jdk/test/javax/crypto/KeyGenerator/TestKGParity.java	Wed Jul 05 20:51:27 2017 +0200
@@ -34,6 +34,7 @@
  * @test
  * @bug 8048607
  * @compile ../../../com/sun/crypto/provider/Cipher/DES/TestUtility.java
+ * @run main TestKGParity
  * @summary Test key generation of DES and DESEDE
  * @key randomness
  */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/security/auth/login/JAASConfigSyntaxCheck/JAASConfigSyntaxTest.java	Wed Jul 05 20:51:27 2017 +0200
@@ -0,0 +1,57 @@
+
+/**
+ * Copyright (c) 2007, 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 javax.security.auth.login.LoginContext;
+
+/**
+ * @test
+ * @bug 8050461
+ * @summary Test should throw Configuration error if configuration file contains
+ * syntax error
+ * @build SampleLoginModule JAASConfigSyntaxTest
+ * @run main/othervm -Djava.security.auth.login.config=file:${test.src}/JAASSynWithOutApplication.config JAASConfigSyntaxTest
+ * @run main/othervm -Djava.security.auth.login.config=file:${test.src}/JAASSynWithOutBraces.config JAASConfigSyntaxTest
+ * @run main/othervm -Djava.security.auth.login.config=file:${test.src}/JAASSynWithOutFlag.config JAASConfigSyntaxTest
+ * @run main/othervm -Djava.security.auth.login.config=file:${test.src}/JAASSynWithOutLoginModule.config JAASConfigSyntaxTest
+ * @run main/othervm -Djava.security.auth.login.config=file:${test.src}/JAASSynWithOutSemiColen.config JAASConfigSyntaxTest
+ */
+public class JAASConfigSyntaxTest {
+
+    private static final String TEST_NAME = "JAASConfigSyntaxTest";
+
+    public static void main(String[] args) throws Exception {
+        try {
+            LoginContext lc = new LoginContext(TEST_NAME);
+            lc.login();
+            throw new RuntimeException("Test Case Failed, did not get "
+                    + "expected exception");
+        } catch (Exception ex) {
+            if (ex.getMessage().contains("java.io.IOException: "
+                    + "Configuration Error:")) {
+                System.out.println("Test case passed");
+            } else {
+                throw new RuntimeException(ex);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/security/auth/login/JAASConfigSyntaxCheck/JAASSynWithOutApplication.config	Wed Jul 05 20:51:27 2017 +0200
@@ -0,0 +1,5 @@
+{
+SampleLoginModule Required;
+SampleLoginModule Required;
+SampleLoginModule Required;
+};
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/security/auth/login/JAASConfigSyntaxCheck/JAASSynWithOutBraces.config	Wed Jul 05 20:51:27 2017 +0200
@@ -0,0 +1,5 @@
+JAASConfigSyntaxTest
+SampleLoginModule Required;
+SampleLoginModule Required;
+SampleLoginModule Required;
+;
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/security/auth/login/JAASConfigSyntaxCheck/JAASSynWithOutFlag.config	Wed Jul 05 20:51:27 2017 +0200
@@ -0,0 +1,5 @@
+JAASConfigSyntaxTest{
+SampleLoginModule ;
+SampleLoginModule ;
+SampleLoginModule ;
+};
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/security/auth/login/JAASConfigSyntaxCheck/JAASSynWithOutLoginModule.config	Wed Jul 05 20:51:27 2017 +0200
@@ -0,0 +1,5 @@
+JAASConfigSyntaxTest{
+;
+;
+;
+};
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/security/auth/login/JAASConfigSyntaxCheck/JAASSynWithOutSemiColen.config	Wed Jul 05 20:51:27 2017 +0200
@@ -0,0 +1,5 @@
+JAASConfigSyntaxTest{
+SampleLoginModule Required;
+SampleLoginModule Required
+SampleLoginModule Required;
+};
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/security/auth/login/JAASConfigSyntaxCheck/SampleLoginModule.java	Wed Jul 05 20:51:27 2017 +0200
@@ -0,0 +1,75 @@
+/**
+ * Copyright (c) 2007, 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 static java.lang.System.out;
+import java.util.Map;
+import javax.security.auth.Subject;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.login.LoginException;
+import javax.security.auth.spi.LoginModule;
+
+/**
+ * Login module which passes all the time
+ */
+
+public class SampleLoginModule implements LoginModule {
+
+    private final String name;
+
+    public SampleLoginModule() {
+        name = this.getClass().getName();
+    }
+
+    @Override
+    public void initialize(Subject subject, CallbackHandler callbackHandler,
+            Map<String, ?> sharedState, Map<String, ?> options) {
+    }
+
+    @Override
+    public boolean login() throws LoginException {
+        out.println(name + " Login method of AbstractLoginModule is called ");
+        out.println(name + ":login:PASS");
+        return true;
+    }
+
+    @Override
+    public boolean commit() throws LoginException {
+        out.println("Commit of AbstractLoginModule is called");
+        out.println(name + ":commit:PASS");
+        return true;
+
+    }
+
+    @Override
+    public boolean abort() throws LoginException {
+        out.println("Abourt is called in AbstractLoginModule");
+        out.println(name + ":abort:PASS");
+        return true;
+    }
+
+    @Override
+    public boolean logout() throws LoginException {
+        out.println("logout is called in AbstractLoginModule");
+        out.println(name + ":logout:PASS");
+        return true;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/security/auth/login/LoginContext/DummyLoginModule.java	Wed Jul 05 20:51:27 2017 +0200
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2004, 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 javax.security.auth.login.LoginException;
+
+/**
+ * Login module which passes all the time
+ */
+
+public class DummyLoginModule extends SmartLoginModule {
+    private final String header;
+
+    public DummyLoginModule() {
+        header = "DummyLoginModule: ";
+    }
+
+    @Override
+    public boolean login() throws LoginException {
+        System.out.println("\t\t" + header + " login method is called ");
+        System.out.println("\t\t" + header + " login:PASS");
+        return true;
+    }
+
+    @Override
+    public boolean commit() throws LoginException {
+        System.out.println("\t\t" + header + " commit method is called");
+        System.out.println("\t\t" + header + " commit:PASS");
+        return true;
+    }
+
+    @Override
+    public boolean abort() throws LoginException {
+        System.out.println("\t\t" + header + " abort method is called ");
+        System.out.println("\t\t" + header + " abort:PASS");
+
+        return true;
+    }
+
+    @Override
+    public boolean logout() throws LoginException {
+        System.out.println("\t\t" + header + " logout method is called");
+        System.out.println("\t\t" + header + " logout:PASS");
+        return true;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/security/auth/login/LoginContext/DynamicConfigurationTest.java	Wed Jul 05 20:51:27 2017 +0200
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2004, 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.io.IOException;
+import javax.security.auth.Subject;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.NameCallback;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import javax.security.auth.login.Configuration;
+import javax.security.auth.login.LoginContext;
+import javax.security.auth.login.LoginException;
+
+/**
+ * @test
+ * @bug 8050427 4703361
+ * @summary Test case for RFE: 4703361. Tests the Dynamic Configuration of
+ * Authentication Modules with different methods
+ * @compile SmartLoginModule.java DummyLoginModule.java MyConfiguration.java
+ * @run main/othervm DynamicConfigurationTest
+ */
+public class DynamicConfigurationTest {
+
+    public static void main(String... args) {
+        String rightConfigName = "PT";
+        String wrongConfigName = "NT";
+        char[] rightPwd = new char[]{'t', 'e', 's', 't', 'P', 'a', 's', 's',
+            'w', 'o', 'r', 'd', '1'};
+        char[] wrongPwd = new char[]{'w', 'r', 'o', 'n', 'g', 'P', 'a', 's',
+            's','w', 'o', 'r', 'd'};
+
+        // Test with wrong configuration name
+        // Expect LoginException when initiate a new LoginContext object
+        testConfigName(wrongConfigName, true);
+        System.out.println("Wrong Config Name Test passed ");
+
+        // Spedify two loginModules: SmartLoginModule and DummyLoginModule
+        // Flags: required-required
+        // Test with right password for SmartLoginModule
+        // No exception is expected
+        Configuration cf = new MyConfiguration();
+        testLogin(rightConfigName, rightPwd, cf, false);
+        System.out.println("Positive test passed");
+
+        // Spedify two loginModules: SmartLoginModule and DummyLoginModule
+        // Flags: required-required
+        // Test with wrong password for SmartLoginModule
+        // Expect LoginException by calling LoginContext.login() method
+        testLogin(rightConfigName, wrongPwd, cf, true);
+        System.out.println("Should fail test passed");
+
+        // Spedify two loginModules: SmartLoginModule and DummyLoginModule
+        // Change the flags from required-required to optional-sufficient
+        // Test with wrong password for SmartLoginModule, while DummyLoginModule
+        // always passes
+        // No Exception is expected
+        cf = new MyConfiguration(true);
+        testLogin(rightConfigName, wrongPwd, cf, false);
+        System.out.println("One module fails where are other module succeeeds "
+                + "Test passed with optional-sufficient flags");
+    }
+
+    public static void testConfigName(String confName,
+            boolean expectException) {
+        String expectedMsg = "No LoginModules configured for " + confName;
+        try {
+            LoginContext lc = new LoginContext(confName, new Subject(),
+                    new MyCallbackHandler(), new MyConfiguration());
+
+            if (expectException) {
+                throw new RuntimeException("Wrong Config Name Test failed: "
+                        + "expected LoginException not thrown.");
+            }
+        } catch (LoginException le) {
+            if (!expectException || !le.getMessage().equals(expectedMsg)) {
+                System.out.println("Wrong Config Name Test failed: "
+                        + "received Unexpected exception.");
+                throw new RuntimeException(le);
+            }
+        }
+    }
+
+    public static void testLogin(String confName, char[] passwd,
+            Configuration cf, boolean expectException) {
+        try {
+            CallbackHandler ch = new MyCallbackHandler("testUser", passwd);
+            LoginContext lc = new LoginContext(confName, new Subject(),
+                    ch, cf);
+            lc.login();
+            if (expectException) {
+                throw new RuntimeException("Login Test failed: "
+                        + "expected LoginException not thrown");
+            }
+        } catch (LoginException le) {
+            if (!expectException) {
+                System.out.println("Login Test failed: "
+                        + "received Unexpected exception.");
+                throw new RuntimeException(le);
+            }
+        }
+    }
+}
+
+/**
+ * The application simulates the CallbackHandler. It simulates! which means all
+ * process to get username and password is ignored. We have to take this
+ * approach for automation purpose. So, this is not a real world example at all.
+ */
+class MyCallbackHandler implements CallbackHandler {
+
+    String userName;
+    char[] password;
+
+    /**
+     * This is simply a workaround approach for IO approach to get username and
+     * password. For automation purpose only.
+     */
+    public MyCallbackHandler() {
+        super();
+    }
+
+    public MyCallbackHandler(String username, char[] password) {
+        super();
+        userName = username;
+        this.password = password;
+    }
+
+    @Override
+    public void handle(Callback[] callbacks) throws IOException,
+            UnsupportedCallbackException {
+        for (Callback callback : callbacks) {
+            if (callback instanceof NameCallback) {
+                NameCallback nc = (NameCallback) callback;
+                nc.setName(userName);
+            } else if (callback instanceof PasswordCallback) {
+                PasswordCallback pc = (PasswordCallback) callback;
+                pc.setPassword(password);
+            } else {
+                throw new UnsupportedCallbackException(callback,
+                        "Unrecognized Callback");
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/security/auth/login/LoginContext/MyConfiguration.java	Wed Jul 05 20:51:27 2017 +0200
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2004, 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.util.HashMap;
+import javax.security.auth.login.AppConfigurationEntry;
+import static javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag.OPTIONAL;
+import static javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag.REQUIRED;
+import static javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag.SUFFICIENT;
+import javax.security.auth.login.Configuration;
+
+/**
+ * This class is used to test LoginContext constructor API. It simply contains
+ * one configuration entry: PT.
+ */
+public class MyConfiguration extends Configuration {
+
+    private static final AppConfigurationEntry[] ptAE
+            = new AppConfigurationEntry[2];
+    private static final HashMap<String, String> map = new HashMap<>();
+    private boolean optionOrder = false;
+
+    public MyConfiguration() {
+        setupConfiguration();
+    }
+
+    public MyConfiguration(boolean optionOrder) {
+        this.optionOrder = optionOrder;
+        setupConfiguration();
+    }
+
+    private void setupConfiguration() {
+        ptAE[0] = new AppConfigurationEntry("SmartLoginModule",
+                optionOrder ? OPTIONAL : REQUIRED,
+                map);
+        ptAE[1] = new AppConfigurationEntry("DummyLoginModule",
+                optionOrder ? SUFFICIENT : REQUIRED,
+                map);
+    }
+
+    @Override
+    public AppConfigurationEntry[]
+            getAppConfigurationEntry(String applicationName) {
+        if (applicationName.equals("PT")) {
+            return ptAE;
+        } else {
+            return null;
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/security/auth/login/LoginContext/SmartLoginModule.java	Wed Jul 05 20:51:27 2017 +0200
@@ -0,0 +1,253 @@
+/*
+ * Copyright (c) 2004, 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.security.Principal;
+import java.util.Arrays;
+import java.util.Map;
+import javax.security.auth.Subject;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.NameCallback;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import javax.security.auth.login.FailedLoginException;
+import javax.security.auth.login.LoginException;
+import javax.security.auth.spi.LoginModule;
+
+/**
+ * This code was based on JAAS demo code, small modification is made for testing
+ * purpose.
+ */
+public class SmartLoginModule implements LoginModule {
+
+    // initial state
+    private Subject subject;
+    private CallbackHandler callbackHandler;
+
+    // the authentication status
+    private boolean succeeded = false;
+    private boolean commitSucceeded = false;
+
+    // username and password
+    private String username;
+    private char[] password;
+
+    // Default values for this login module. In real world,
+    // don't do it in this way!
+    private String myUsername;
+    private char[] myPassword;
+    private String header;
+
+    // testUser's SamplePrincipal
+    private SamplePrincipal userPrincipal;
+
+    public SmartLoginModule() {
+        this("testUser",
+                new char[]{'t', 'e', 's', 't', 'P', 'a', 's', 's',
+                    'w', 'o', 'r', 'd', '1'},
+                "SmartLoginModule1: ");
+    }
+
+    public SmartLoginModule(String userName, char[] password, String header) {
+        myUsername = userName;
+        myPassword = password;
+        this.header = header;
+    }
+
+    @Override
+    public boolean abort() throws LoginException {
+        if (!succeeded) {
+            return false;
+        } else if (succeeded && !commitSucceeded) {
+            // login succeeded but overall authentication failed
+            succeeded = false;
+            username = null;
+            password = null;
+            userPrincipal = null;
+        } else {
+            // overall authentication succeeded and commit succeeded,
+            // but someone else's commit failed
+            logout();
+        }
+        return true;
+    }
+
+    @Override
+    public boolean commit() throws LoginException {
+        if (!succeeded) {
+            return false;
+        } else {
+            // add a Principal (authenticated identity) to the Subject
+            // assume the user we authenticated is the SamplePrincipal
+            userPrincipal = new SamplePrincipal(username);
+            if (!subject.getPrincipals().contains(userPrincipal)) {
+                subject.getPrincipals().add(userPrincipal);
+            }
+            // in any case, clean out state
+            username = null;
+            password = null;
+            commitSucceeded = true;
+            return true;
+        }
+    }
+
+    @Override
+    public void initialize(Subject subject, CallbackHandler callbackHandler,
+            Map<String, ?> sharedState, Map<String, ?> options) {
+        this.subject = subject;
+        this.callbackHandler = callbackHandler;
+    }
+
+    @Override
+    public boolean login() throws LoginException {
+        if (callbackHandler == null) {
+            throw new LoginException("Error: no CallbackHandler available to "
+                    + "garner authentication information from the user");
+        }
+
+        Callback[] callbacks = new Callback[2];
+        callbacks[0] = new NameCallback(header + "user name: ");
+        callbacks[1] = new PasswordCallback(header + "password: ", false);
+
+        try {
+            callbackHandler.handle(callbacks);
+            username = ((NameCallback) callbacks[0]).getName();
+            char[] tmpPassword
+                    = ((PasswordCallback) callbacks[1]).getPassword();
+            if (tmpPassword == null) {
+                tmpPassword = new char[0];
+            }
+            password = new char[tmpPassword.length];
+            System.arraycopy(tmpPassword, 0, password, 0, tmpPassword.length);
+            ((PasswordCallback) callbacks[1]).clearPassword();
+        } catch (java.io.IOException ioe) {
+            throw (LoginException) new LoginException().initCause(ioe);
+        } catch (UnsupportedCallbackException uce) {
+            throw new LoginException("Error: " + header
+                    + uce.getCallback().toString()
+                    + " not available to garner authentication information "
+                    + "from the user");
+        }
+
+        // verify the username/password
+        if (username.equals(myUsername)
+                && Arrays.equals(password, myPassword)) {
+            System.out.println("\t\t" + header + " authentication succeeded");
+            succeeded = true;
+            return true;
+        } else {
+            // authentication failed -- clean out state
+            System.out.println("\t\t" + header + " authentication failed");
+            printDebugInfo();
+            succeeded = false;
+            username = null;
+            password = null;
+            throw new FailedLoginException("User Name or Password Incorrect");
+        }
+    }
+
+    @Override
+    public boolean logout() throws LoginException {
+        subject.getPrincipals().remove(userPrincipal);
+        succeeded = false;
+        succeeded = commitSucceeded;
+        username = null;
+        password = null;
+        userPrincipal = null;
+        return true;
+    }
+
+    // print debugging information
+    private void printDebugInfo() {
+        System.out.println("\t\t" + header + " correct user name: "
+                + myUsername);
+        System.out.println("\t\t" + header + " user entered user name: "
+                + username);
+        System.out.print("\t\t" + header + " correct password: ");
+        for (char c : myPassword) {
+            System.out.print(c);
+        }
+        System.out.println();
+        System.out.print("\t\t" + header + " user entered password: ");
+        for (char c : password) {
+            System.out.print(c);
+        }
+        System.out.println();
+    }
+}
+
+class SamplePrincipal implements Principal, java.io.Serializable {
+
+    /**
+     * @serial
+     */
+    private String name;
+
+    /**
+     * Create a SamplePrincipal with a Sample username.
+     *
+     * @param name the Sample username for this user.
+     * @exception NullPointerException if the <code>name</code> is
+     * <code>null</code>.
+     */
+    public SamplePrincipal(String name) {
+        if (name == null) {
+            throw new NullPointerException("illegal null input");
+        }
+
+        this.name = name;
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public String toString() {
+        return "SamplePrincipal:  " + name;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o == null) {
+            return false;
+        }
+
+        if (this == o) {
+            return true;
+        }
+
+        if (!(o instanceof SamplePrincipal)) {
+            return false;
+        }
+        SamplePrincipal that = (SamplePrincipal) o;
+
+        return this.getName().equals(that.getName());
+    }
+
+    @Override
+    public int hashCode() {
+        return name.hashCode();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/TestSignatureOidHelper.java	Wed Jul 05 20:51:27 2017 +0200
@@ -0,0 +1,124 @@
+/*
+ * 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.security.InvalidKeyException;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.util.List;
+
+/*
+ * Utilities for testing the signature algorithm OIDs.
+ */
+public class TestSignatureOidHelper {
+
+    private static final byte[] INPUT = "1234567890".getBytes();
+
+    private final String algorithm;
+
+    private final String provider;
+
+    private final int keySize;
+
+    private final List<OidAlgorithmPair> data;
+
+    public TestSignatureOidHelper(String algorithm, String provider,
+            int keySize, List<OidAlgorithmPair> data) {
+        this.algorithm = algorithm;
+        this.provider = provider;
+        this.keySize = keySize;
+        this.data = data;
+    }
+
+    public void execute() throws Exception {
+        KeyPair keyPair = createKeyPair();
+        for (OidAlgorithmPair oidAlgorithmPair : data) {
+            runTest(oidAlgorithmPair, keyPair);
+            System.out.println("passed");
+        }
+        System.out.println("All tests passed");
+    }
+
+    private KeyPair createKeyPair()
+            throws NoSuchAlgorithmException, NoSuchProviderException {
+        KeyPairGenerator keyGen = KeyPairGenerator.getInstance(algorithm,
+                provider);
+        keyGen.initialize(keySize);
+        return keyGen.generateKeyPair();
+    }
+
+    private void runTest(OidAlgorithmPair oidAlgorithmPair, KeyPair keyPair)
+            throws NoSuchAlgorithmException, NoSuchProviderException,
+            InvalidKeyException, SignatureException {
+        Signature sgAlgorithm =
+                Signature.getInstance(oidAlgorithmPair.algorithm, provider);
+        Signature sgOid = Signature.getInstance(oidAlgorithmPair.oid, provider);
+
+        if (sgAlgorithm == null) {
+            throw new RuntimeException(String.format(
+                    "Test failed: algorithm string %s getInstance failed.%n",
+                    oidAlgorithmPair.algorithm));
+        }
+
+        if (sgOid == null) {
+            throw new RuntimeException(
+                    String.format("Test failed: OID %s getInstance failed.%n",
+                            oidAlgorithmPair.oid));
+        }
+
+        if (!sgAlgorithm.getAlgorithm().equals(oidAlgorithmPair.algorithm)) {
+            throw new RuntimeException(String.format(
+                    "Test failed: algorithm string %s getInstance "
+                            + "doesn't generate expected algorithm.%n",
+                    oidAlgorithmPair.algorithm));
+        }
+
+        sgAlgorithm.initSign(keyPair.getPrivate());
+        sgAlgorithm.update(INPUT);
+        sgOid.initVerify(keyPair.getPublic());
+        sgOid.update(INPUT);
+        if (!sgOid.verify(sgAlgorithm.sign())) {
+            throw new RuntimeException(
+                    "Signature verification failed unexpectedly");
+        }
+    }
+}
+
+class OidAlgorithmPair {
+
+    public final String oid;
+    public final String algorithm;
+
+    public OidAlgorithmPair(String oid, String algorithm) {
+        this.oid = oid;
+        this.algorithm = algorithm;
+    }
+
+    @Override
+    public String toString() {
+        return "[oid=" + oid + ", algorithm=" + algorithm + "]";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/ec/NSASuiteB/TestSHAwithECDSASignatureOids.java	Wed Jul 05 20:51:27 2017 +0200
@@ -0,0 +1,50 @@
+/*
+ * 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.util.Arrays;
+import java.util.List;
+
+/*
+ * @test
+ * @bug 8075286
+ * @summary Test the SHAwithECDSA signature algorithm OIDs in JDK.
+ *          OID and algorithm transformation string should match.
+ *          Both could be able to be used to generate the algorithm instance.
+ * @compile ../../TestSignatureOidHelper.java
+ * @run main TestSHAwithECDSASignatureOids
+ */
+public class TestSHAwithECDSASignatureOids {
+
+    private static final List<OidAlgorithmPair> DATA = Arrays.asList(
+            new OidAlgorithmPair("1.2.840.10045.4.1", "SHA1withECDSA"),
+            new OidAlgorithmPair("1.2.840.10045.4.3.1", "SHA224withECDSA"),
+            new OidAlgorithmPair("1.2.840.10045.4.3.2", "SHA256withECDSA"),
+            new OidAlgorithmPair("1.2.840.10045.4.3.3", "SHA384withECDSA"),
+            new OidAlgorithmPair("1.2.840.10045.4.3.4", "SHA512withECDSA"));
+
+    public static void main(String[] args) throws Exception {
+        TestSignatureOidHelper helper = new TestSignatureOidHelper("EC",
+                "SunEC", 256, DATA);
+        helper.execute();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/provider/NSASuiteB/TestDSAGenParameterSpec.java	Wed Jul 05 20:51:27 2017 +0200
@@ -0,0 +1,185 @@
+/*
+ * 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.security.AlgorithmParameterGenerator;
+import java.security.AlgorithmParameters;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidParameterException;
+import java.security.KeyPairGenerator;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.spec.DSAGenParameterSpec;
+import java.security.spec.DSAParameterSpec;
+import java.security.spec.InvalidParameterSpecException;
+import java.util.Arrays;
+import java.util.List;
+
+/*
+ * @test
+ * @bug 8075286
+ * @summary Verify that DSAGenParameterSpec can and can only be used to generate
+ *          DSA within some certain range of key sizes as described in the class
+ *          specification (L, N) as (1024, 160), (2048, 224), (2048, 256) and
+ *          (3072, 256) should be OK for DSAGenParameterSpec. But the real
+ *          implementation SUN doesn't support (3072, 256).
+ * @run main TestDSAGenParameterSpec
+ */
+public class TestDSAGenParameterSpec {
+
+    private static final String ALGORITHM_NAME = "DSA";
+    private static final String PROVIDER_NAME = "SUN";
+
+    private static final List<DataTuple> DATA = Arrays.asList(
+            new DataTuple(1024, 160, true, true),
+            new DataTuple(2048, 224, true, true),
+            new DataTuple(2048, 256, true, true),
+            new DataTuple(3072, 256, true, false),
+            new DataTuple(1024, 224),
+            new DataTuple(2048, 160),
+            new DataTuple(4096, 256),
+            new DataTuple(512, 160),
+            new DataTuple(3072, 224));
+
+    private static void testDSAGenParameterSpec(DataTuple dataTuple)
+            throws NoSuchAlgorithmException, NoSuchProviderException,
+            InvalidParameterSpecException, InvalidAlgorithmParameterException {
+        System.out.printf("Test case: primePLen=%d, " + "subprimeQLen=%d%n",
+                dataTuple.primePLen, dataTuple.subprimeQLen);
+
+        AlgorithmParameterGenerator apg =
+                AlgorithmParameterGenerator.getInstance(ALGORITHM_NAME,
+                        PROVIDER_NAME);
+
+        DSAGenParameterSpec genParamSpec = createGenParameterSpec(dataTuple);
+        // genParamSpec will be null if IllegalAE is thrown when expected.
+        if (genParamSpec == null) {
+            return;
+        }
+
+        try {
+            apg.init(genParamSpec, null);
+            AlgorithmParameters param = apg.generateParameters();
+
+            checkParam(param, genParamSpec);
+            System.out.println("Test case passed");
+        } catch (InvalidParameterException ipe) {
+            // The DSAGenParameterSpec API support this, but the real
+            // implementation in SUN doesn't
+            if (!dataTuple.isSunProviderSupported) {
+                System.out.println("Test case passed: expected "
+                        + "InvalidParameterException is caught");
+            } else {
+                throw new RuntimeException("Test case failed.", ipe);
+            }
+        }
+    }
+
+    private static void checkParam(AlgorithmParameters param,
+            DSAGenParameterSpec genParam) throws InvalidParameterSpecException,
+                    NoSuchAlgorithmException, NoSuchProviderException,
+                    InvalidAlgorithmParameterException {
+        String algorithm = param.getAlgorithm();
+        if (!algorithm.equalsIgnoreCase(ALGORITHM_NAME)) {
+            throw new RuntimeException(
+                    "Unexpected type of parameters: " + algorithm);
+        }
+
+        DSAParameterSpec spec = param.getParameterSpec(DSAParameterSpec.class);
+        int valueL = spec.getP().bitLength();
+        int strengthP = genParam.getPrimePLength();
+        if (strengthP != valueL) {
+            System.out.printf("P: Expected %d but actual %d%n", strengthP,
+                    valueL);
+            throw new RuntimeException("Wrong P strength");
+        }
+
+        int valueN = spec.getQ().bitLength();
+        int strengthQ = genParam.getSubprimeQLength();
+        if (strengthQ != valueN) {
+            System.out.printf("Q: Expected %d but actual %d%n", strengthQ,
+                    valueN);
+            throw new RuntimeException("Wrong Q strength");
+        }
+
+        if (genParam.getSubprimeQLength() != genParam.getSeedLength()) {
+            System.out.println("Defaut seed length should be the same as Q.");
+            throw new RuntimeException("Wrong seed length");
+        }
+
+        // use the parameters to generate real DSA keys
+        KeyPairGenerator keyGen = KeyPairGenerator.getInstance(ALGORITHM_NAME,
+                PROVIDER_NAME);
+        keyGen.initialize(spec);
+        keyGen.generateKeyPair();
+    }
+
+    private static DSAGenParameterSpec createGenParameterSpec(
+            DataTuple dataTuple) {
+        DSAGenParameterSpec genParamSpec = null;
+        try {
+            genParamSpec = new DSAGenParameterSpec(dataTuple.primePLen,
+                    dataTuple.subprimeQLen);
+            if (!dataTuple.isDSASpecSupported) {
+                throw new RuntimeException(
+                        "Test case failed: the key length must not supported");
+            }
+        } catch (IllegalArgumentException e) {
+            if (!dataTuple.isDSASpecSupported) {
+                System.out.println("Test case passed: expected "
+                        + "IllegalArgumentException is caught");
+            } else {
+                throw new RuntimeException("Test case failed: unexpected "
+                        + "IllegalArgumentException is thrown", e);
+            }
+        }
+
+        return genParamSpec;
+    }
+
+    public static void main(String[] args) throws Exception {
+        for (DataTuple dataTuple : DATA) {
+            testDSAGenParameterSpec(dataTuple);
+        }
+        System.out.println("All tests passed");
+    }
+
+    private static class DataTuple {
+
+        private int primePLen;
+        private int subprimeQLen;
+        private boolean isDSASpecSupported;
+        private boolean isSunProviderSupported;
+
+        private DataTuple(int primePLen, int subprimeQLen,
+                boolean isDSASpecSupported, boolean isSunProviderSupported) {
+            this.primePLen = primePLen;
+            this.subprimeQLen = subprimeQLen;
+            this.isDSASpecSupported = isDSASpecSupported;
+            this.isSunProviderSupported = isSunProviderSupported;
+        }
+
+        private DataTuple(int primePLen, int subprimeQLen) {
+            this(primePLen, subprimeQLen, false, false);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/provider/NSASuiteB/TestSHAOids.java	Wed Jul 05 20:51:27 2017 +0200
@@ -0,0 +1,103 @@
+/*
+ * 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.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.util.Arrays;
+import java.util.List;
+
+/*
+ * @test
+ * @bug 8075286
+ * @summary Test the SHA algorithm OIDs in JDK.
+ *          OID and algorithm transformation string should match.
+ *          Both could be able to be used to generate the algorithm instance.
+ * @run main TestSHAOids
+ */
+public class TestSHAOids {
+
+    private static final String PROVIDER_NAME = "SUN";
+    private static final byte[] INPUT = "1234567890".getBytes();
+
+    private static final List<DataTuple> DATA = Arrays.asList(
+            new DataTuple("2.16.840.1.101.3.4.2.1", "SHA-256"),
+            new DataTuple("2.16.840.1.101.3.4.2.2", "SHA-384"),
+            new DataTuple("2.16.840.1.101.3.4.2.3", "SHA-512"),
+            new DataTuple("2.16.840.1.101.3.4.2.4", "SHA-224"));
+
+    public static void main(String[] args) throws Exception {
+        for (DataTuple dataTuple : DATA) {
+            runTest(dataTuple);
+            System.out.println("passed");
+        }
+        System.out.println("All tests passed");
+    }
+
+    private static void runTest(DataTuple dataTuple)
+            throws NoSuchAlgorithmException, NoSuchProviderException {
+        MessageDigest mdAlgorithm = MessageDigest.getInstance(
+                dataTuple.algorithm, PROVIDER_NAME);
+        MessageDigest mdOid = MessageDigest.getInstance(dataTuple.oid,
+                PROVIDER_NAME);
+
+        if (mdAlgorithm == null) {
+            throw new RuntimeException(String.format(
+                    "Test failed: algorithm string %s getInstance failed.%n",
+                    dataTuple.algorithm));
+        }
+
+        if (mdOid == null) {
+            throw new RuntimeException(
+                    String.format("Test failed: OID %s getInstance failed.%n",
+                            dataTuple.oid));
+        }
+
+        if (!mdAlgorithm.getAlgorithm().equals(dataTuple.algorithm)) {
+            throw new RuntimeException(String.format(
+                    "Test failed: algorithm string %s getInstance doesn't "
+                            + "generate expected algorithm.%n",
+                    dataTuple.algorithm));
+        }
+
+        mdAlgorithm.update(INPUT);
+        mdOid.update(INPUT);
+
+        // Comparison
+        if (!Arrays.equals(mdAlgorithm.digest(), mdOid.digest())) {
+            throw new RuntimeException("Digest comparison failed: "
+                    + "the two digests are not the same");
+        }
+    }
+
+    private static class DataTuple {
+
+        private final String oid;
+        private final String algorithm;
+
+        private DataTuple(String oid, String algorithm) {
+            this.oid = oid;
+            this.algorithm = algorithm;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/provider/NSASuiteB/TestSHAwithDSASignatureOids.java	Wed Jul 05 20:51:27 2017 +0200
@@ -0,0 +1,47 @@
+/*
+ * 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.util.Arrays;
+import java.util.List;
+
+/*
+ * @test
+ * @bug 8075286
+ * @summary Test the SHAwithDSA signature algorithm OIDs in JDK.
+ *          OID and algorithm transformation string should match.
+ *          Both could be able to be used to generate the algorithm instance.
+ * @compile ../../TestSignatureOidHelper.java
+ * @run main TestSHAwithDSASignatureOids
+ */
+public class TestSHAwithDSASignatureOids {
+
+    private static final List<OidAlgorithmPair> DATA = Arrays.asList(
+            new OidAlgorithmPair("2.16.840.1.101.3.4.3.1", "SHA224withDSA"),
+            new OidAlgorithmPair("2.16.840.1.101.3.4.3.2", "SHA256withDSA"));
+
+    public static void main(String[] args) throws Exception {
+        TestSignatureOidHelper helper = new TestSignatureOidHelper("DSA",
+                "SUN", 1024, DATA);
+        helper.execute();
+    }
+}
--- a/make/Init.gmk	Sat Sep 26 09:22:24 2015 -0700
+++ b/make/Init.gmk	Wed Jul 05 20:51:27 2017 +0200
@@ -50,7 +50,8 @@
   include $(topdir)/make/Help.gmk
 
   # Targets provided by Init.gmk.
-  ALL_INIT_TARGETS := print-modules print-targets print-configuration reconfigure
+  ALL_INIT_TARGETS := print-modules print-targets print-configuration \
+      reconfigure pre-compare-build post-compare-build
 
   # CALLED_TARGETS is the list of targets that the user provided,
   # or "default" if unspecified.
@@ -163,25 +164,39 @@
 	      $(COMMAND_LINE_VARIABLES) $(MAKECMDGOALS))')
         endif
 
+    MAKE_INIT_WITH_SPEC_ARGUMENTS := ACTUAL_TOPDIR=$(topdir) \
+        USER_MAKE_VARS="$(USER_MAKE_VARS)" MAKE_LOG_FLAGS=$(MAKE_LOG_FLAGS) \
+        LOG_LEVEL=$(LOG_LEVEL) LOG_NOFILE=$(LOG_NOFILE) \
+        INIT_TARGETS="$(INIT_TARGETS)" \
+        SEQUENTIAL_TARGETS="$(SEQUENTIAL_TARGETS)" \
+        PARALLEL_TARGETS="$(PARALLEL_TARGETS)"
+
     # Now the init and main targets will be called, once for each SPEC. The
     # recipe will be run once for every target specified, but we only want to
     # execute the recipe a single time, hence the TARGET_DONE with a dummy
     # command if true.
+    # The COMPARE_BUILD part implements special support for makefile development.
     $(ALL_INIT_TARGETS) $(ALL_MAIN_TARGETS): make-info
 	@$(if $(TARGET_DONE), \
 	  true \
 	, \
+	  ( cd $(topdir) && \
 	  $(foreach spec, $(SPECS), \
-	    ( cd $(topdir) && \
 	    $(MAKE) $(MFLAGS) $(MAKE_LOG_FLAGS) -r -R -j 1 -f $(topdir)/make/Init.gmk \
-	        SPEC=$(spec) HAS_SPEC=true ACTUAL_TOPDIR=$(topdir) \
-	        USER_MAKE_VARS="$(USER_MAKE_VARS)" MAKE_LOG_FLAGS=$(MAKE_LOG_FLAGS) \
-	        LOG_LEVEL=$(LOG_LEVEL) LOG_NOFILE=$(LOG_NOFILE) \
-	        INIT_TARGETS="$(INIT_TARGETS)" \
-	        SEQUENTIAL_TARGETS="$(SEQUENTIAL_TARGETS)" \
-	        PARALLEL_TARGETS="$(PARALLEL_TARGETS)"  \
-	        main ) && \
-	  ) true \
+	        SPEC=$(spec) HAS_SPEC=true $(MAKE_INIT_WITH_SPEC_ARGUMENTS) \
+	        main && \
+	    $(if $(and $(COMPARE_BUILD), $(PARALLEL_TARGETS)), \
+	        $(MAKE) $(MFLAGS) $(MAKE_LOG_FLAGS) -r -R -f $(topdir)/make/Init.gmk \
+	            SPEC=$(spec) HAS_SPEC=true ACTUAL_TOPDIR=$(topdir) \
+	            COMPARE_BUILD="$(COMPARE_BUILD)" pre-compare-build && \
+	        $(MAKE) $(MFLAGS) $(MAKE_LOG_FLAGS) -r -R -j 1 -f $(topdir)/make/Init.gmk \
+	            SPEC=$(spec) HAS_SPEC=true $(MAKE_INIT_WITH_SPEC_ARGUMENTS) \
+	            COMPARE_BUILD="$(COMPARE_BUILD)" main && \
+	        $(MAKE) $(MFLAGS) $(MAKE_LOG_FLAGS) -r -R -f $(topdir)/make/Init.gmk \
+	            SPEC=$(spec) HAS_SPEC=true ACTUAL_TOPDIR=$(topdir) \
+	            COMPARE_BUILD="$(COMPARE_BUILD)" post-compare-build && \
+	    ) \
+	  ) true ) \
 	  $(eval TARGET_DONE=true) \
 	)
 
@@ -205,6 +220,9 @@
   # Verify that the spec file we included seems okay.
   $(eval $(call CheckSpecSanity))
 
+  # Parse COMPARE_BUILD (for makefile development)
+  $(eval $(call ParseCompareBuild))
+
   ifeq ($(LOG_NOFILE), true)
     # Disable log wrapper if LOG=[level,]nofile was given
     override BUILD_LOG_WRAPPER :=
@@ -244,7 +262,7 @@
   # The main target, for delegating into Main.gmk
   ##############################################################################
 
-  MAIN_TARGETS := $(SEQUENTIAL_TARGETS) $(PARALLEL_TARGETS)
+  MAIN_TARGETS := $(SEQUENTIAL_TARGETS) $(PARALLEL_TARGETS) $(COMPARE_BUILD_MAKE)
   TARGET_DESCRIPTION := target$(if $(word 2, $(MAIN_TARGETS)),s) \
       '$(strip $(MAIN_TARGETS))' in configuration '$(CONF_NAME)'
 
@@ -271,7 +289,7 @@
 	    ( cd $(TOPDIR) && \
 	        $(BUILD_LOG_WRAPPER) $(MAKE) $(MAKE_ARGS) $(OUTPUT_SYNC_FLAG) \
 	            -j $(JOBS) -f make/Main.gmk $(USER_MAKE_VARS) \
-	            $(PARALLEL_TARGETS) || \
+	            $(PARALLEL_TARGETS) $(COMPARE_BUILD_MAKE) || \
 	        ( exitcode=$$? && $(BUILD_LOG_WRAPPER) \
 	        $(PRINTF) "\nERROR: Build failed for $(TARGET_DESCRIPTION) (exit code $$exitcode) \n" && \
 	        cd $(TOPDIR) && $(MAKE) $(MAKE_ARGS) -j 1 -f make/Init.gmk \
@@ -304,5 +322,30 @@
 	fi
 	$(PRINTF) "Hint: If caused by a warning, try configure --disable-warnings-as-errors.\n\n"
 
+    # Support targets for COMPARE_BUILD, used for makefile development
+    pre-compare-build:
+	$(ECHO) "Preparing for comparison rebuild"
+        # Apply patch, if any
+        ifneq ($(COMPARE_BUILD_PATCH), )
+	  $(PATCH) -p1 < $(COMPARE_BUILD_PATCH)
+        endif
+        # Move the first build away and re-create the output directory
+	( cd $(TOPDIR) && \
+	    $(MV) $(OUTPUT_ROOT) $(OUTPUT_ROOT).OLD && \
+	    $(MKDIR) -p $(OUTPUT_ROOT) )
+        # Re-run configure with the same arguments (and possibly some additional),
+	# must be done after patching.
+	( cd $(OUTPUT_ROOT) && PATH="$(ORIGINAL_PATH)" \
+	    $(BASH) $(TOPDIR)/configure $(CONFIGURE_COMMAND_LINE) $(COMPARE_BUILD_CONF))
+
+    post-compare-build:
+        # Compare first and second build. Ignore any error code from compare.sh.
+	$(ECHO) "Comparing between comparison rebuild (this/new) and baseline (other/old)"
+        ifneq ($(COMPARE_BUILD_COMP_DIR), )
+	  +(cd $(OUTPUT_ROOT) && ./compare.sh $(COMPARE_BUILD_COMP_OPTS) -2dirs $(OUTPUT_ROOT)/$(COMPARE_BUILD_COMP_DIR) $(OUTPUT_ROOT).OLD/$(COMPARE_BUILD_COMP_DIR) || true)
+        else
+	  +(cd $(OUTPUT_ROOT) && ./compare.sh $(COMPARE_BUILD_COMP_OPTS) -o $(OUTPUT_ROOT).OLD || true)
+        endif
+
   .PHONY: print-targets print-modules reconfigure main on-failure
 endif
--- a/make/InitSupport.gmk	Sat Sep 26 09:22:24 2015 -0700
+++ b/make/InitSupport.gmk	Wed Jul 05 20:51:27 2017 +0200
@@ -40,7 +40,7 @@
   ##############################################################################
 
   # Make control variables, handled by Init.gmk
-  INIT_CONTROL_VARIABLES := LOG CONF SPEC JOBS CONF_CHECK
+  INIT_CONTROL_VARIABLES := LOG CONF SPEC JOBS CONF_CHECK COMPARE_BUILD
 
   # All known make control variables
   MAKE_CONTROL_VARIABLES := $(INIT_CONTROL_VARIABLES) TEST JDK_FILTER
@@ -53,12 +53,14 @@
 
   # The variable MAKEOVERRIDES contains variable assignments from the command
   # line, but in reverse order to what the user entered.
+  # The '\#' <=> '\ 'dance is needed to keep values with space in them connected.
   COMMAND_LINE_VARIABLES := $(subst \#,\ , $(call reverse, $(subst \ ,\#,$(MAKEOVERRIDES))))
 
   # A list like FOO="val1" BAR="val2" containing all user-supplied make
   # variables that we should propagate.
-  USER_MAKE_VARS := $(filter-out $(addsuffix =%, $(INIT_CONTROL_VARIABLES)), \
-      $(MAKEOVERRIDES))
+  # The '\#' <=> '\ 'dance is needed to keep values with space in them connected.
+  USER_MAKE_VARS := $(subst \#,\ , $(filter-out $(addsuffix =%, $(INIT_CONTROL_VARIABLES)), \
+      $(subst \ ,\#,$(MAKEOVERRIDES))))
 
   # Setup information about available configurations, if any.
   build_dir=$(topdir)/build
@@ -309,6 +311,59 @@
     endif
   endef
 
+  # Parse COMPARE_BUILD into COMPARE_BUILD_*
+  # Syntax: COMPARE_BUILD=CONF=<configure options>:PATCH=<patch file>:
+  #         MAKE=<make targets>:COMP_OPTS=<compare script options>:
+  #         COMP_DIR=<compare script base dir>|<default>
+  # If neither CONF or PATCH is given, assume <default> means CONF if it
+  # begins with "--", otherwise assume it means PATCH.
+  # MAKE and COMP_OPTS can only be used with CONF and/or PATCH specified.
+  # If any value contains "+", it will be replaced by space.
+  define ParseCompareBuild
+    ifneq ($$(COMPARE_BUILD), )
+      ifneq ($$(findstring :, $$(COMPARE_BUILD)), )
+        $$(foreach part, $$(subst :, , $$(COMPARE_BUILD)), \
+          $$(if $$(filter PATCH=%, $$(part)), \
+            $$(eval COMPARE_BUILD_PATCH=$$(strip $$(patsubst PATCH=%, %, $$(part)))) \
+          ) \
+          $$(if $$(filter CONF=%, $$(part)), \
+            $$(eval COMPARE_BUILD_CONF=$$(strip $$(subst +, , $$(patsubst CONF=%, %, $$(part))))) \
+          ) \
+          $$(if $$(filter MAKE=%, $$(part)), \
+            $$(eval COMPARE_BUILD_MAKE=$$(strip $$(subst +, , $$(patsubst MAKE=%, %, $$(part))))) \
+          ) \
+          $$(if $$(filter COMP_OPTS=%, $$(part)), \
+            $$(eval COMPARE_BUILD_COMP_OPTS=$$(strip $$(subst +, , $$(patsubst COMP_OPTS=%, %, $$(part))))) \
+          ) \
+          $$(if $$(filter COMP_DIR=%, $$(part)), \
+            $$(eval COMPARE_BUILD_COMP_DIR=$$(strip $$(subst +, , $$(patsubst COMP_DIR=%, %, $$(part))))) \
+          ) \
+        )
+      else
+        # Separate handling for single field case, to allow for spaces in values.
+        ifneq ($$(filter PATCH=%, $$(COMPARE_BUILD)), )
+          COMPARE_BUILD_PATCH=$$(strip $$(patsubst PATCH=%, %, $$(COMPARE_BUILD)))
+        else ifneq ($$(filter CONF=%, $$(COMPARE_BUILD)), )
+          COMPARE_BUILD_CONF=$$(strip $$(subst +, , $$(patsubst CONF=%, %, $$(COMPARE_BUILD))))
+        else ifneq ($$(filter --%, $$(COMPARE_BUILD)), )
+          # Assume CONF if value begins with --
+          COMPARE_BUILD_CONF=$$(strip $$(subst +, , $$(COMPARE_BUILD)))
+        else
+          # Otherwise assume patch file
+          COMPARE_BUILD_PATCH=$$(strip $$(COMPARE_BUILD))
+        endif
+      endif
+      ifneq ($$(COMPARE_BUILD_PATCH), )
+        ifneq ($$(wildcard $$(TOPDIR)/$$(COMPARE_BUILD_PATCH)), )
+          # Assume relative path, if file exists
+          COMPARE_BUILD_PATCH := $$(wildcard $$(TOPDIR)/$$(COMPARE_BUILD_PATCH))
+        else ifeq ($$(wildcard $$(COMPARE_BUILD_PATCH)), )
+          $$(error Patch file $$(COMPARE_BUILD_PATCH) does not exist)
+        endif
+      endif
+    endif
+  endef
+
   define RotateLogFiles
 	$(RM) $(BUILD_LOG).old 2> /dev/null
 	$(MV) $(BUILD_LOG) $(BUILD_LOG).old 2> /dev/null || true
--- a/make/common/JavaCompilation.gmk	Sat Sep 26 09:22:24 2015 -0700
+++ b/make/common/JavaCompilation.gmk	Wed Jul 05 20:51:27 2017 +0200
@@ -155,6 +155,7 @@
   # When this macro is run in the same makefile as the java compilation, dependencies are
   # transfered in make variables. When the macro is run in a different makefile than the
   # java compilation, the dependencies need to be found in the filesystem.
+  $1_ORIG_DEPS := $$($1_DEPENDENCIES)
   ifeq ($$($1_DEPENDENCIES), )
     # Add all source roots to the find cache since we are likely going to run find
     # on these more than once. The cache will only be updated if necessary.
@@ -266,7 +267,8 @@
 
   # Include all variables of significance in the vardeps file
   $1_VARDEPS := $(JAR) $$($1_JAR_CREATE_OPTIONS) $$($1_MANIFEST) \
-      $$($1_JARMAIN) $$($1_EXTRA_MANIFEST_ATTR)
+      $$($1_JARMAIN) $$($1_EXTRA_MANIFEST_ATTR) $$($1_ORIG_DEPS) $$($1_SRCS) \
+      $$($1_INCLUDES) $$($1_EXCLUDES) $$($1_EXCLUDE_FILES) $$($1_EXTRA_FILES)
   $1_VARDEPS_FILE := $$(call DependOnVariable, $1_VARDEPS, $$(dir $$($1_JAR))_the.$$($1_JARNAME).vardeps)
 
   # Here is the rule that creates/updates the jar file.
@@ -280,7 +282,7 @@
         # potential changes.
 	$$(if $$(filter $$($1_VARDEPS_FILE) $$($1_MANIFEST), $$?), \
 	  $$(if $$($1_MANIFEST), \
-	    $(CP) $$($1_MANIFEST) $$($1_MANIFEST_FILE) $$(NEWLINE) \
+	    $(SED) -e '$(DOLLAR)$(DOLLAR)a\' $$($1_MANIFEST) > $$($1_MANIFEST_FILE) $$(NEWLINE) \
 	  , \
 	    $(RM) $$($1_MANIFEST_FILE) && $(TOUCH) $$($1_MANIFEST_FILE) $$(NEWLINE)) \
 	  $$(if $$($1_JARMAIN), \
@@ -417,6 +419,7 @@
 #   HEADERS:=path to directory where all generated c-headers are written.
 #   DEPENDS:=Extra dependecy
 #   DISABLE_SJAVAC:=Explicitly disable the use of sjavac for this compilation unit.
+#   KEEP_DUPS:=Do not remove duplicate file names from different source roots.
 SetupJavaCompilation = $(NamedParamsMacroTemplate)
 define SetupJavaCompilationBody
 
@@ -469,19 +472,27 @@
     $1_SRCS := $$(filter-out $$($1_SRC_EXCLUDES),$$($1_SRCS))
   endif
 
-  # Remove duplicate source files by keeping the first found of each duplicate.
-  # This allows for automatic overrides with custom or platform specific versions
-  # source files.
-  #
-  # For the smart javac wrapper case, add each removed file to an extra exclude
-  # file list to prevent sjavac from finding duplicate sources.
-  $1_SRCS := $$(strip $$(foreach s, $$($1_SRCS), \
-      $$(eval relative_src := $$(call remove-prefixes, $$($1_SRC), $$(s))) \
-      $$(if $$($1_$$(relative_src)), \
-        $$(eval $1_SJAVAC_EXCLUDE_FILES += $$(s)), \
-        $$(eval $1_$$(relative_src) := 1) $$(s))))
+  ifneq ($$($1_KEEP_DUPS), true)
+    # Remove duplicate source files by keeping the first found of each duplicate.
+    # This allows for automatic overrides with custom or platform specific versions
+    # source files.
+    #
+    # For the smart javac wrapper case, add each removed file to an extra exclude
+    # file list to prevent sjavac from finding duplicate sources.
+    $1_SRCS := $$(strip $$(foreach s, $$($1_SRCS), \
+        $$(eval relative_src := $$(call remove-prefixes, $$($1_SRC), $$(s))) \
+        $$(if $$($1_$$(relative_src)), \
+          $$(eval $1_SJAVAC_EXCLUDE_FILES += $$(s)), \
+          $$(eval $1_$$(relative_src) := 1) $$(s))))
+  endif
 
- # Create the corresponding smart javac wrapper command line.
+  ifeq ($$(strip $$($1_SRCS)), )
+    $$(error No source files found for $1)
+  endif
+
+  $1_SAFE_NAME := $$(strip $$(subst /,_, $1))
+
+  # Create the corresponding smart javac wrapper command line.
   $1_SJAVAC_ARGS:=$$(addprefix -x ,$$(addsuffix /*,$$($1_EXCLUDES))) \
       $$(addprefix -i ,$$(addsuffix /*,$$($1_INCLUDES))) \
       $$(addprefix -xf *,$$(strip $$($1_EXCLUDE_FILES) $$($1_SJAVAC_EXCLUDE_FILES))) \
@@ -560,14 +571,15 @@
         $$(SPACE),%20,$$(subst $$(COMMA),%2C,$$(strip $$($1_SERVER_JVM) $$($1_SJAVAC))))
 
     $1_VARDEPS := $$($1_JVM) $$($1_SJAVAC) $$($1_SJAVAC_ARGS) $$($1_FLAGS) \
-        $$($1_HEADERS_ARG) $$($1_BIN)
+        $$($1_HEADERS_ARG) $$($1_BIN) $$($1_EXCLUDES) $$($1_INCLUDES) \
+        $$($1_EXCLUDE_FILES) $$($1_INCLUDE_FILES)
     $1_VARDEPS_FILE := $$(call DependOnVariable, $1_VARDEPS, $$($1_BIN)/_the.$1.vardeps)
 
     $$($1_BIN)/_the.$1_batch: $$($1_SRCS) $$($1_DEPENDS) $$($1_VARDEPS_FILE)
 	$(MKDIR) -p $$(@D) $$(dir $$($1_SJAVAC_PORTFILE))
 	$$(call ListPathsSafely,$1_SRCS,\n, >> $$($1_BIN)/_the.$1_batch.tmp)
 	$(ECHO) Compiling $1
-	$(call LogFailures, $$($1_BIN)/_the.$1_batch.log, $1, \
+	$(call LogFailures, $$($1_BIN)/_the.$$($1_SAFE_NAME)_batch.log, $$($1_SAFE_NAME), \
 	    $$($1_JVM) $$($1_SJAVAC) \
 	        $$($1_REMOTE) \
 	        -j 1 \
@@ -575,6 +587,7 @@
 	        --permit-sources-without-package \
 	        --compare-found-sources $$($1_BIN)/_the.$1_batch.tmp \
 	        --log=$(LOG_LEVEL) \
+	        --state-dir=$$($1_BIN) \
 	        $$($1_SJAVAC_ARGS) \
 	        $$($1_FLAGS) \
 	        $$($1_HEADERS_ARG) \
@@ -615,7 +628,9 @@
       $1_HEADER_TARGETS := $$($1_HEADERS)/_the.$1_headers
     endif
 
-    $1_VARDEPS := $$($1_JVM) $$($1_JAVAC) $$($1_FLAGS) $$($1_BIN) $$($1_HEADERS_ARG)
+    $1_VARDEPS := $$($1_JVM) $$($1_JAVAC) $$($1_FLAGS) $$($1_BIN) \
+        $$($1_HEADERS_ARG) $$($1_EXCLUDES) $$($1_INCLUDES) \
+        $$($1_EXCLUDE_FILES) $$($1_INCLUDE_FILES)
     $1_VARDEPS_FILE := $$(call DependOnVariable, $1_VARDEPS, $$($1_BIN)/_the.$1.vardeps)
 
     # When not using sjavac, pass along all sources to javac using an @file.
@@ -624,7 +639,7 @@
 	$(RM) $$($1_BIN)/_the.$1_batch $$($1_BIN)/_the.$1_batch.tmp
 	$$(call ListPathsSafely,$1_SRCS,\n, >> $$($1_BIN)/_the.$1_batch.tmp)
 	$(ECHO) Compiling `$(WC) $$($1_BIN)/_the.$1_batch.tmp | $(TR) -s ' ' | $(CUT) -f 2 -d ' '` files for $1
-	$(call LogFailures, $$($1_BIN)/_the.$1_batch.log, $1, \
+	$(call LogFailures, $$($1_BIN)/_the.$$($1_SAFE_NAME)_batch.log, $$($1_SAFE_NAME), \
 	    $$($1_JVM) $$($1_JAVAC) $$($1_FLAGS) \
 	        -implicit:none \
 	        -d $$($1_BIN) $$($1_HEADERS_ARG) @$$($1_BIN)/_the.$1_batch.tmp) && \
--- a/make/common/NativeCompilation.gmk	Sat Sep 26 09:22:24 2015 -0700
+++ b/make/common/NativeCompilation.gmk	Wed Jul 05 20:51:27 2017 +0200
@@ -204,18 +204,18 @@
           ifeq ($(TOOLCHAIN_TYPE)$$(filter %.s,$2), solstudio)
             # The Solaris studio compiler doesn't output the full path to the object file in the
             # generated deps files. Fixing it with sed. If compiling assembly, don't try this.
-	    $(call LogFailures, $$($1_$2_OBJ).log, $1_$$(notdir $2), \
+	    $(call LogFailures, $$($1_$2_OBJ).log, $$($1_SAFE_NAME)_$$(notdir $2), \
 	        $$($1_$2_COMP) $$($1_$2_FLAGS) $$($1_$2_DEP_FLAG) $$($1_$2_DEP).tmp $(CC_OUT_OPTION)$$($1_$2_OBJ) $2)
 	    $(SED) 's|^$$(@F):|$$@:|' $$($1_$2_DEP).tmp > $$($1_$2_DEP)
           else
-	    $(call LogFailures, $$($1_$2_OBJ).log, $1_$$(notdir $2), \
+	    $(call LogFailures, $$($1_$2_OBJ).log, $$($1_SAFE_NAME)_$$(notdir $2), \
 	        $$($1_$2_COMP) $$($1_$2_FLAGS) $$($1_$2_DEP_FLAG) $$($1_$2_DEP) $(CC_OUT_OPTION)$$($1_$2_OBJ) $2)
           endif
         else
           # The Visual Studio compiler lacks a feature for generating make dependencies, but by
           # setting -showIncludes, all included files are printed. These are filtered out and
           # parsed into make dependences.
-	  ($(call LogFailures, $$($1_$2_OBJ).log, $1_$$(notdir $2), \
+	  ($(call LogFailures, $$($1_$2_OBJ).log, $$($1_SAFE_NAME)_$$(notdir $2), \
 	      $$($1_$2_COMP) $$($1_$2_FLAGS) -showIncludes $$($1_$2_DEBUG_OUT_FLAGS) \
 	          $(CC_OUT_OPTION)$$($1_$2_OBJ) $2) ; echo $$$$? > $$($1_$2_DEP).exitvalue) \
 	      | $(TEE) $$($1_$2_DEP).raw | $(GREP) -v -e "^Note: including file:" \
@@ -353,6 +353,7 @@
     $1_TARGET:=$$($1_OUTPUT_DIR)/$$($1_BASENAME)
     $1_NOSUFFIX:=$$($1_PROGRAM)
   endif
+  $1_SAFE_NAME := $$(strip $$(subst /,_, $1))
 
   ifeq (,$$($1_TARGET))
     $$(error Neither PROGRAM, LIBRARY nor STATIC_LIBRARY has been specified for SetupNativeCompilation)
@@ -414,6 +415,10 @@
 
   $1_SRCS += $$($1_EXTRA_FILES)
 
+  ifeq (,$$($1_SRCS))
+    $$(error No sources found for $1 when looking inside the dirs $$($1_SRC))
+  endif
+
   # Calculate the expected output from compiling the sources (sort to remove duplicates. Also provides
   # a reproducable order on the input files to the linker).
   $1_EXPECTED_OBJS_FILENAMES := $$(call replace_with_obj_extension, $$(notdir $$($1_SRCS)))
@@ -549,8 +554,8 @@
         else
 	  $(ECHO) $$(strip 'Updating $$($1_BASENAME)' \
 	      $$(if $$(filter-out %.vardeps, $$?), \
-	        'from $$(words $$(filter-out %.vardeps, $$?)) file(s)') \
-	      $$(if $$(filter %.vardeps, $$?), 'due to makefile changes'))
+	        'due to $$(words $$(filter-out %.vardeps, $$?)) file(s)', \
+	      $$(if $$(filter %.vardeps, $$?), 'due to makefile changes')))
         endif
 	$(TOUCH) $$@
 
@@ -674,7 +679,7 @@
     $$($1_TARGET): $$($1_EXPECTED_OBJS) $$($1_RES) $$($1_REAL_MAPFILE) \
         $$($1_VARDEPS_FILE)
 		$(ECHO) $(LOG_INFO) "Linking $$($1_BASENAME)"
-		$(call LogFailures, $$($1_OBJECT_DIR)/$1_link.log, $1_link, \
+		$(call LogFailures, $$($1_OBJECT_DIR)/$$($1_SAFE_NAME)_link.log, $$($1_SAFE_NAME)_link, \
 		    $$($1_LD) $$($1_LDFLAGS) $$($1_EXTRA_LDFLAGS) $$($1_SYSROOT_LDFLAGS) \
 		    $(LD_OUT_OPTION)$$@ \
 		    $$($1_EXPECTED_OBJS) $$($1_RES) \
@@ -697,7 +702,7 @@
     # Generating a static library, ie object file archive.
     $$($1_TARGET): $$($1_EXPECTED_OBJS) $$($1_RES) $$($1_VARDEPS_FILE)
 	$(ECHO) $(LOG_INFO) "Archiving $$($1_STATIC_LIBRARY)"
-	$(call LogFailures, $$($1_OBJECT_DIR)/$1_link.log, $1_link, \
+	$(call LogFailures, $$($1_OBJECT_DIR)/$$($1_SAFE_NAME)_link.log, $$($1_SAFE_NAME)_link, \
 	    $$($1_AR) $$($1_ARFLAGS) $(AR_OUT_OPTION)$$($1_TARGET) $$($1_EXPECTED_OBJS) \
 	        $$($1_RES) $$($1_LDFLAGS_SUFFIX) $$($1_EXTRA_LDFLAGS_SUFFIX))
   endif
@@ -715,7 +720,7 @@
     $$($1_TARGET): $$($1_EXPECTED_OBJS) $$($1_RES) $$($1_MANIFEST) \
         $$($1_VARDEPS_FILE)
 		$(ECHO) $(LOG_INFO) "Linking executable $$($1_BASENAME)"
-		$(call LogFailures, $$($1_OBJECT_DIR)/$1_link.log, $1_link, \
+		$(call LogFailures, $$($1_OBJECT_DIR)/$$($1_SAFE_NAME)_link.log, $$($1_SAFE_NAME)_link, \
 		    $$($1_LD) $$($1_LDFLAGS) $$($1_EXTRA_LDFLAGS) $$($1_SYSROOT_LDFLAGS) \
 		        $(EXE_OUT_OPTION)$$($1_TARGET) \
 		        $$($1_EXPECTED_OBJS) $$($1_RES) \
--- a/nashorn/.hgtags	Sat Sep 26 09:22:24 2015 -0700
+++ b/nashorn/.hgtags	Wed Jul 05 20:51:27 2017 +0200
@@ -316,3 +316,4 @@
 61b401b23fc28208930977d46b690423911173c6 jdk9-b80
 42d8ed4651b62572b39e6fed3fafcb7ee93f9dc2 jdk9-b81
 8bab0a9d8a638affdd680c5ec783373f71c19267 jdk9-b82
+21b86b980a5f0d27f1f758a3e4818d3331387172 jdk9-b83
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/AssignSymbols.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/AssignSymbols.java	Wed Jul 05 20:51:27 2017 +0200
@@ -70,11 +70,10 @@
 import jdk.nashorn.internal.ir.LexicalContext;
 import jdk.nashorn.internal.ir.LexicalContextNode;
 import jdk.nashorn.internal.ir.LiteralNode;
-import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode;
-import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode.ArrayUnit;
 import jdk.nashorn.internal.ir.Node;
 import jdk.nashorn.internal.ir.RuntimeNode;
 import jdk.nashorn.internal.ir.RuntimeNode.Request;
+import jdk.nashorn.internal.ir.Splittable;
 import jdk.nashorn.internal.ir.Statement;
 import jdk.nashorn.internal.ir.SwitchNode;
 import jdk.nashorn.internal.ir.Symbol;
@@ -984,7 +983,7 @@
         boolean previousWasBlock = false;
         for (final Iterator<LexicalContextNode> it = lc.getAllNodes(); it.hasNext();) {
             final LexicalContextNode node = it.next();
-            if (node instanceof FunctionNode || isSplitArray(node)) {
+            if (node instanceof FunctionNode || isSplitLiteral(node)) {
                 // We reached the function boundary or a splitting boundary without seeing a definition for the symbol.
                 // It needs to be in scope.
                 return true;
@@ -1010,12 +1009,8 @@
         throw new AssertionError();
     }
 
-    private static boolean isSplitArray(final LexicalContextNode expr) {
-        if(!(expr instanceof ArrayLiteralNode)) {
-            return false;
-        }
-        final List<ArrayUnit> units = ((ArrayLiteralNode)expr).getUnits();
-        return !(units == null || units.isEmpty());
+    private static boolean isSplitLiteral(final LexicalContextNode expr) {
+        return expr instanceof Splittable && ((Splittable) expr).getSplitRanges() != null;
     }
 
     private void throwUnprotectedSwitchError(final VarNode varNode) {
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/CodeGenerator.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/CodeGenerator.java	Wed Jul 05 20:51:27 2017 +0200
@@ -105,7 +105,6 @@
 import jdk.nashorn.internal.ir.LexicalContextNode;
 import jdk.nashorn.internal.ir.LiteralNode;
 import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode;
-import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode.ArrayUnit;
 import jdk.nashorn.internal.ir.LiteralNode.PrimitiveLiteralNode;
 import jdk.nashorn.internal.ir.LocalVariableConversion;
 import jdk.nashorn.internal.ir.LoopNode;
@@ -118,6 +117,7 @@
 import jdk.nashorn.internal.ir.RuntimeNode.Request;
 import jdk.nashorn.internal.ir.SetSplitState;
 import jdk.nashorn.internal.ir.SplitReturn;
+import jdk.nashorn.internal.ir.Splittable;
 import jdk.nashorn.internal.ir.Statement;
 import jdk.nashorn.internal.ir.SwitchNode;
 import jdk.nashorn.internal.ir.Symbol;
@@ -242,7 +242,7 @@
     private final DebugLogger log;
 
     /** From what size should we use spill instead of fields for JavaScript objects? */
-    private static final int OBJECT_SPILL_THRESHOLD = Options.getIntProperty("nashorn.spill.threshold", 256);
+    static final int OBJECT_SPILL_THRESHOLD = Options.getIntProperty("nashorn.spill.threshold", 256);
 
     private final Set<String> emittedMethods = new HashSet<>();
 
@@ -1634,7 +1634,7 @@
 
                     @Override
                     void consumeStack() {
-                        dynamicCall(2 + argsCount, getCallSiteFlags(), origCallee.getName());
+                        dynamicCall(2 + argsCount, getCallSiteFlags(), null);
                     }
                 }.emit();
                 return false;
@@ -2234,73 +2234,33 @@
      *
      * @param arrayLiteralNode the array of contents
      * @param arrayType        the type of the array, e.g. ARRAY_NUMBER or ARRAY_OBJECT
-     *
-     * @return the method generator that was used
      */
-    private MethodEmitter loadArray(final ArrayLiteralNode arrayLiteralNode, final ArrayType arrayType) {
+    private void loadArray(final ArrayLiteralNode arrayLiteralNode, final ArrayType arrayType) {
         assert arrayType == Type.INT_ARRAY || arrayType == Type.LONG_ARRAY || arrayType == Type.NUMBER_ARRAY || arrayType == Type.OBJECT_ARRAY;
 
-        final Expression[]    nodes    = arrayLiteralNode.getValue();
-        final Object          presets  = arrayLiteralNode.getPresets();
-        final int[]           postsets = arrayLiteralNode.getPostsets();
-        final Class<?>        type     = arrayType.getTypeClass();
-        final List<ArrayUnit> units    = arrayLiteralNode.getUnits();
+        final Expression[]     nodes    = arrayLiteralNode.getValue();
+        final Object           presets  = arrayLiteralNode.getPresets();
+        final int[]            postsets = arrayLiteralNode.getPostsets();
+        final List<Splittable.SplitRange> ranges   = arrayLiteralNode.getSplitRanges();
 
         loadConstant(presets);
 
         final Type elementType = arrayType.getElementType();
 
-        if (units != null) {
-            final MethodEmitter savedMethod     = method;
-            final FunctionNode  currentFunction = lc.getCurrentFunction();
-
-            for (final ArrayUnit arrayUnit : units) {
-                unit = lc.pushCompileUnit(arrayUnit.getCompileUnit());
-
-                final String className = unit.getUnitClassName();
-                assert unit != null;
-                final String name      = currentFunction.uniqueName(SPLIT_PREFIX.symbolName());
-                final String signature = methodDescriptor(type, ScriptFunction.class, Object.class, ScriptObject.class, type);
-
-                pushMethodEmitter(unit.getClassEmitter().method(EnumSet.of(Flag.PUBLIC, Flag.STATIC), name, signature));
-
-                method.setFunctionNode(currentFunction);
-                method.begin();
-
-                defineCommonSplitMethodParameters();
-                defineSplitMethodParameter(CompilerConstants.SPLIT_ARRAY_ARG.slot(), arrayType);
-
-                // NOTE: when this is no longer needed, SplitIntoFunctions will no longer have to add IS_SPLIT
-                // to synthetic functions, and FunctionNode.needsCallee() will no longer need to test for isSplit().
-                final int arraySlot = fixScopeSlot(currentFunction, 3);
-
-                lc.enterSplitNode();
-
-                for (int i = arrayUnit.getLo(); i < arrayUnit.getHi(); i++) {
-                    method.load(arrayType, arraySlot);
-                    storeElement(nodes, elementType, postsets[i]);
+        if (ranges != null) {
+
+            loadSplitLiteral(new SplitLiteralCreator() {
+                @Override
+                public void populateRange(final MethodEmitter method, final Type type, final int slot, final int start, final int end) {
+                    for (int i = start; i < end; i++) {
+                        method.load(type, slot);
+                        storeElement(nodes, elementType, postsets[i]);
+                    }
+                    method.load(type, slot);
                 }
-
-                method.load(arrayType, arraySlot);
-                method._return();
-                lc.exitSplitNode();
-                method.end();
-                lc.releaseSlots();
-                popMethodEmitter();
-
-                assert method == savedMethod;
-                method.loadCompilerConstant(CALLEE);
-                method.swap();
-                method.loadCompilerConstant(THIS);
-                method.swap();
-                method.loadCompilerConstant(SCOPE);
-                method.swap();
-                method.invokestatic(className, name, signature);
-
-                unit = lc.popCompileUnit(unit);
-            }
-
-            return method;
+            }, ranges, arrayType);
+
+            return;
         }
 
         if(postsets.length > 0) {
@@ -2312,7 +2272,6 @@
             }
             method.load(arrayType, arraySlot);
         }
-        return method;
     }
 
     private void storeElement(final Expression[] nodes, final Type elementType, final int index) {
@@ -2537,6 +2496,7 @@
         final List<MapTuple<Expression>> tuples = new ArrayList<>();
         final List<PropertyNode> gettersSetters = new ArrayList<>();
         final int ccp = getCurrentContinuationEntryPoint();
+        final List<Splittable.SplitRange> ranges = objectNode.getSplitRanges();
 
         Expression protoNode = null;
         boolean restOfProperty = false;
@@ -2583,7 +2543,13 @@
                     loadExpressionAsType(node, type);
                 }};
         }
-        oc.makeObject(method);
+
+        if (ranges != null) {
+            oc.createObject(method);
+            loadSplitLiteral(oc, ranges, Type.typeFor(oc.getAllocatorClass()));
+        } else {
+            oc.makeObject(method);
+        }
 
         //if this is a rest of method and our continuation point was found as one of the values
         //in the properties above, we need to reset the map to oc.getMap() in the continuation
@@ -2899,6 +2865,54 @@
         method.onLocalStore(type, slot);
     }
 
+    private void loadSplitLiteral(final SplitLiteralCreator creator, final List<Splittable.SplitRange> ranges, final Type literalType) {
+        assert ranges != null;
+
+        // final Type literalType = Type.typeFor(literalClass);
+        final MethodEmitter savedMethod     = method;
+        final FunctionNode  currentFunction = lc.getCurrentFunction();
+
+        for (final Splittable.SplitRange splitRange : ranges) {
+            unit = lc.pushCompileUnit(splitRange.getCompileUnit());
+
+            assert unit != null;
+            final String className = unit.getUnitClassName();
+            final String name      = currentFunction.uniqueName(SPLIT_PREFIX.symbolName());
+            final Class<?> clazz   = literalType.getTypeClass();
+            final String signature = methodDescriptor(clazz, ScriptFunction.class, Object.class, ScriptObject.class, clazz);
+
+            pushMethodEmitter(unit.getClassEmitter().method(EnumSet.of(Flag.PUBLIC, Flag.STATIC), name, signature));
+
+            method.setFunctionNode(currentFunction);
+            method.begin();
+
+            defineCommonSplitMethodParameters();
+            defineSplitMethodParameter(CompilerConstants.SPLIT_ARRAY_ARG.slot(), literalType);
+
+            // NOTE: when this is no longer needed, SplitIntoFunctions will no longer have to add IS_SPLIT
+            // to synthetic functions, and FunctionNode.needsCallee() will no longer need to test for isSplit().
+            final int literalSlot = fixScopeSlot(currentFunction, 3);
+
+            lc.enterSplitNode();
+
+            creator.populateRange(method, literalType, literalSlot, splitRange.getLow(), splitRange.getHigh());
+
+            method._return();
+            lc.exitSplitNode();
+            method.end();
+            lc.releaseSlots();
+            popMethodEmitter();
+
+            assert method == savedMethod;
+            method.loadCompilerConstant(CALLEE).swap();
+            method.loadCompilerConstant(THIS).swap();
+            method.loadCompilerConstant(SCOPE).swap();
+            method.invokestatic(className, name, signature);
+
+            unit = lc.popCompileUnit(unit);
+        }
+    }
+
     private int fixScopeSlot(final FunctionNode functionNode, final int extraSlot) {
         // TODO hack to move the scope to the expected slot (needed because split methods reuse the same slots as the root method)
         final int actualScopeSlot = functionNode.compilerConstant(SCOPE).getSlot(SCOPE_TYPE);
@@ -5461,4 +5475,21 @@
             method.uncheckedGoto(targetCatchLabel);
         }
     }
+
+    /**
+     * Interface implemented by object creators that support splitting over multiple methods.
+     */
+    interface SplitLiteralCreator {
+        /**
+         * Generate code to populate a range of the literal object. A reference to the object
+         * should be left on the stack when the method terminates.
+         *
+         * @param method the method emitter
+         * @param type the type of the literal object
+         * @param slot the local slot containing the literal object
+         * @param start the start index (inclusive)
+         * @param end the end index (exclusive)
+         */
+        void populateRange(MethodEmitter method, Type type, int slot, int start, int end);
+    }
 }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/FieldObjectCreator.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/FieldObjectCreator.java	Wed Jul 05 20:51:27 2017 +0200
@@ -34,7 +34,6 @@
 import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.getArrayIndex;
 import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.isValidArrayIndex;
 
-import java.util.Iterator;
 import java.util.List;
 import jdk.nashorn.internal.codegen.types.Type;
 import jdk.nashorn.internal.ir.Symbol;
@@ -91,27 +90,20 @@
         findClass();
     }
 
-    /**
-     * Construct an object.
-     *
-     * @param method the method emitter
-     */
     @Override
-    protected void makeObject(final MethodEmitter method) {
+    public void createObject(final MethodEmitter method) {
         makeMap();
         final String className = getClassName();
-        try {
-            // NOTE: we must load the actual structure class here, because the API operates with Nashorn Type objects,
-            // and Type objects need a loaded class, for better or worse. We also have to be specific and use the type
-            // of the actual structure class, we can't generalize it to e.g. Type.typeFor(ScriptObject.class) as the
-            // exact type information is needed for generating continuations in rest-of methods. If we didn't do this,
-            // object initializers like { x: arr[i] } would fail during deoptimizing compilation on arr[i], as the
-            // values restored from the RewriteException would be cast to "ScriptObject" instead of to e.g. "JO4", and
-            // subsequently the "PUTFIELD J04.L0" instruction in the continuation code would fail bytecode verification.
-            method._new(Context.forStructureClass(className.replace('/', '.'))).dup();
-        } catch (final ClassNotFoundException e) {
-            throw new AssertionError(e);
-        }
+        // NOTE: we must load the actual structure class here, because the API operates with Nashorn Type objects,
+        // and Type objects need a loaded class, for better or worse. We also have to be specific and use the type
+        // of the actual structure class, we can't generalize it to e.g. Type.typeFor(ScriptObject.class) as the
+        // exact type information is needed for generating continuations in rest-of methods. If we didn't do this,
+        // object initializers like { x: arr[i] } would fail during deoptimizing compilation on arr[i], as the
+        // values restored from the RewriteException would be cast to "ScriptObject" instead of to e.g. "JO4", and
+        // subsequently the "PUTFIELD J04.L0" instruction in the continuation code would fail bytecode verification.
+        assert fieldObjectClass != null;
+        method._new(fieldObjectClass).dup();
+
         loadMap(method); //load the map
 
         if (isScope()) {
@@ -126,14 +118,14 @@
         } else {
             method.invoke(constructorNoLookup(className, PropertyMap.class));
         }
+    }
 
-        helpOptimisticRecognizeDuplicateIdentity(method);
-
+    @Override
+    public void populateRange(final MethodEmitter method, final Type objectType, final int objectSlot, final int start, final int end) {
+        method.load(objectType, objectSlot);
         // Set values.
-        final Iterator<MapTuple<T>> iter = tuples.iterator();
-
-        while (iter.hasNext()) {
-            final MapTuple<T> tuple = iter.next();
+        for (int i = start; i < end; i++) {
+            final MapTuple<T> tuple = tuples.get(i);
             //we only load when we have both symbols and values (which can be == the symbol)
             //if we didn't load, we need an array property
             if (tuple.symbol != null && tuple.value != null) {
@@ -212,6 +204,11 @@
         }
     }
 
+    @Override
+    protected Class<? extends ScriptObject> getAllocatorClass() {
+        return fieldObjectClass;
+    }
+
     /**
      * Get the class name for the object class,
      * e.g. {@code com.nashorn.oracle.scripts.JO2P0}
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/FindScopeDepths.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/FindScopeDepths.java	Wed Jul 05 20:51:27 2017 +0200
@@ -275,15 +275,11 @@
         final Set<Symbol> symbols = new HashSet<>();
         block.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
             @Override
-            public final boolean enterDefault(final Node node) {
-                if (!compiler.isOnDemandCompilation()) {
-                    if (node instanceof IdentNode) {
-                        final Symbol symbol = ((IdentNode)node).getSymbol();
-                        if (symbol != null && symbol.isScope()) {
-                            //if this is an internal symbol, skip it.
-                            symbols.add(symbol);
-                        }
-                    }
+            public boolean enterIdentNode(final IdentNode identNode) {
+                final Symbol symbol = identNode.getSymbol();
+                if (symbol != null && symbol.isScope()) {
+                    //if this is an internal symbol, skip it.
+                    symbols.add(symbol);
                 }
                 return true;
             }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/FoldConstants.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/FoldConstants.java	Wed Jul 05 20:51:27 2017 +0200
@@ -116,7 +116,7 @@
                 statements.addAll(executed.getStatements()); // Get statements form executed branch
             }
             if (dropped != null) {
-                extractVarNodes(dropped, statements); // Get var-nodes from non-executed branch
+                extractVarNodesFromDeadCode(dropped, statements); // Get var-nodes from non-executed branch
             }
             if (statements.isEmpty()) {
                 return new EmptyNode(ifNode);
@@ -185,14 +185,27 @@
         protected abstract LiteralNode<?> eval();
     }
 
-    private static void extractVarNodes(final Block block, final List<Statement> statements) {
-        final LexicalContext lc = new LexicalContext();
-        block.accept(lc, new NodeVisitor<LexicalContext>(lc) {
+    /**
+     * When we eliminate dead code, we must preserve var declarations as they are scoped to the whole
+     * function. This method gathers var nodes from code passed to it, removing their initializers.
+     *
+     * @param deadCodeRoot the root node of eliminated dead code
+     * @param statements a list that will be receiving the var nodes from the dead code, with their
+     * initializers removed.
+     */
+    static void extractVarNodesFromDeadCode(final Node deadCodeRoot, final List<Statement> statements) {
+        deadCodeRoot.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
             @Override
             public boolean enterVarNode(final VarNode varNode) {
                 statements.add(varNode.setInit(null));
                 return false;
             }
+
+            @Override
+            public boolean enterFunctionNode(final FunctionNode functionNode) {
+                // Don't descend into nested functions
+                return false;
+            }
         });
     }
 
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/Lower.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/Lower.java	Wed Jul 05 20:51:27 2017 +0200
@@ -121,13 +121,7 @@
                             terminated = true;
                         }
                     } else {
-                        statement.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
-                            @Override
-                            public boolean enterVarNode(final VarNode varNode) {
-                                newStatements.add(varNode.setInit(null));
-                                return false;
-                            }
-                        });
+                        FoldConstants.extractVarNodesFromDeadCode(statement, newStatements);
                     }
                 }
                 return newStatements;
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/MethodEmitter.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/MethodEmitter.java	Wed Jul 05 20:51:27 2017 +0200
@@ -257,8 +257,7 @@
      */
     private Type popType(final Type expected) {
         final Type type = popType();
-        assert type.isObject() && expected.isObject() ||
-            type.isEquivalentTo(expected) : type + " is not compatible with " + expected;
+        assert type.isEquivalentTo(expected) : type + " is not compatible with " + expected;
         return type;
     }
 
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/ObjectCreator.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/ObjectCreator.java	Wed Jul 05 20:51:27 2017 +0200
@@ -36,7 +36,7 @@
  * Base class for object creation code generation.
  * @param <T> value type
  */
-public abstract class ObjectCreator<T> {
+public abstract class ObjectCreator<T> implements CodeGenerator.SplitLiteralCreator {
 
     /** List of keys & symbols to initiate in this ObjectCreator */
     final List<MapTuple<T>> tuples;
@@ -69,7 +69,23 @@
      * Generate code for making the object.
      * @param method Script method.
      */
-    protected abstract void makeObject(final MethodEmitter method);
+    public void makeObject(final MethodEmitter method) {
+        createObject(method);
+        // We need to store the object in a temporary slot as populateRange expects to load the
+        // object from a slot (as it is also invoked within split methods). Note that this also
+        // helps optimistic continuations to handle the stack in case an optimistic assumption
+        // fails during initialization (see JDK-8079269).
+        final int objectSlot = method.getUsedSlotsWithLiveTemporaries();
+        final Type objectType = method.peekType();
+        method.storeTemp(objectType, objectSlot);
+        populateRange(method, objectType, objectSlot, 0, tuples.size());
+    }
+
+    /**
+     * Generate code for creating and initializing the object.
+     * @param method the method emitter
+     */
+    protected abstract void createObject(final MethodEmitter method);
 
     /**
      * Construct the property map appropriate for the object.
@@ -125,6 +141,12 @@
     }
 
     /**
+     * Get the class of objects created by this ObjectCreator
+     * @return class of created object
+     */
+    abstract protected Class<? extends ScriptObject> getAllocatorClass();
+
+    /**
      * Technique for loading an initial value. Defined by anonymous subclasses in code gen.
      *
      * @param value Value to load.
@@ -145,29 +167,4 @@
     MethodEmitter loadTuple(final MethodEmitter method, final MapTuple<T> tuple) {
         return loadTuple(method, tuple, true);
     }
-
-    /**
-     * If using optimistic typing, let the code generator realize that the newly created object on the stack
-     * when DUP-ed will be the same value. Basically: {NEW, DUP, INVOKESPECIAL init, DUP} will leave a stack
-     * load specification {unknown, unknown} on stack (that is "there's two values on the stack, but neither
-     * comes from a known local load"). If there's an optimistic operation in the literal initializer,
-     * OptimisticOperation.storeStack will allocate two temporary locals for it and store them as
-     * {ASTORE 4, ASTORE 3}. If we instead do {NEW, DUP, INVOKESPECIAL init, ASTORE 3, ALOAD 3, DUP} we end up
-     * with stack load specification {ALOAD 3, ALOAD 3} (as DUP can track that the value it duplicated came
-     * from a local load), so if/when a continuation needs to be recreated from it, it'll be
-     * able to emit ALOAD 3, ALOAD 3 to recreate the stack. If we didn't do this, deoptimization within an
-     * object literal initialization could in rare cases cause an incompatible change in the shape of the
-     * local variable table for the temporaries, e.g. in the following snippet where a variable is reassigned
-     * to a wider type in an object initializer:
-     * <code>var m = 1; var obj = {p0: m, p1: m = "foo", p2: m}</code>
-     * @param method the current method emitter.
-     */
-    void helpOptimisticRecognizeDuplicateIdentity(final MethodEmitter method) {
-        if (codegen.useOptimisticTypes()) {
-            final Type objectType = method.peekType();
-            final int tempSlot = method.defineTemporaryLocalVariable(objectType.getSlots());
-            method.storeHidden(objectType, tempSlot);
-            method.load(objectType, tempSlot);
-        }
-    }
 }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/ReplaceCompileUnits.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/ReplaceCompileUnits.java	Wed Jul 05 20:51:27 2017 +0200
@@ -27,13 +27,15 @@
 
 import java.util.ArrayList;
 import java.util.List;
+
 import jdk.nashorn.internal.ir.CompileUnitHolder;
 import jdk.nashorn.internal.ir.FunctionNode;
 import jdk.nashorn.internal.ir.LexicalContext;
 import jdk.nashorn.internal.ir.LiteralNode;
 import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode;
-import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode.ArrayUnit;
 import jdk.nashorn.internal.ir.Node;
+import jdk.nashorn.internal.ir.ObjectNode;
+import jdk.nashorn.internal.ir.Splittable;
 import jdk.nashorn.internal.ir.visitor.NodeVisitor;
 
 /**
@@ -70,15 +72,28 @@
     public Node leaveLiteralNode(final LiteralNode<?> node) {
         if (node instanceof ArrayLiteralNode) {
             final ArrayLiteralNode aln = (ArrayLiteralNode)node;
-            if (aln.getUnits() == null) {
+            if (aln.getSplitRanges() == null) {
                 return node;
             }
-            final List<ArrayUnit> newArrayUnits = new ArrayList<>();
-            for (final ArrayUnit au : aln.getUnits()) {
-                newArrayUnits.add(new ArrayUnit(getExistingReplacement(au), au.getLo(), au.getHi()));
+            final List<Splittable.SplitRange> newArrayUnits = new ArrayList<>();
+            for (final Splittable.SplitRange au : aln.getSplitRanges()) {
+                newArrayUnits.add(new Splittable.SplitRange(getExistingReplacement(au), au.getLow(), au.getHigh()));
             }
-            return aln.setUnits(lc, newArrayUnits);
+            return aln.setSplitRanges(lc, newArrayUnits);
         }
         return node;
     }
+
+    @Override
+    public Node leaveObjectNode(final ObjectNode objectNode) {
+        final List<Splittable.SplitRange> ranges = objectNode.getSplitRanges();
+        if (ranges != null) {
+            final List<Splittable.SplitRange> newRanges = new ArrayList<>();
+            for (final Splittable.SplitRange range : ranges) {
+                newRanges.add(new Splittable.SplitRange(getExistingReplacement(range), range.getLow(), range.getHigh()));
+            }
+            return objectNode.setSplitRanges(lc, newRanges);
+        }
+        return super.leaveObjectNode(objectNode);
+    }
 }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/SpillObjectCreator.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/SpillObjectCreator.java	Wed Jul 05 20:51:27 2017 +0200
@@ -61,7 +61,7 @@
     }
 
     @Override
-    protected void makeObject(final MethodEmitter method) {
+    public void createObject(final MethodEmitter method) {
         assert !isScope() : "spill scope objects are not currently supported";
 
         final int          length        = tuples.size();
@@ -69,9 +69,7 @@
         final int          spillLength   = ScriptObject.spillAllocationLength(length);
         final long[]       jpresetValues = dualFields ? new long[spillLength] : null;
         final Object[]     opresetValues = new Object[spillLength];
-        final Set<Integer> postsetValues = new LinkedHashSet<>();
-        final int          callSiteFlags = codegen.getCallSiteFlags();
-        final Class<?>     objectClass   = dualFields ? JD.class : JO.class;
+        final Class<?>     objectClass   = getAllocatorClass();
         ArrayData          arrayData     = ArrayData.allocate(ScriptRuntime.EMPTY_ARRAY);
 
         // Compute constant property values
@@ -85,9 +83,7 @@
 
             if (value != null) {
                 final Object constantValue = LiteralNode.objectAsConstant(value);
-                if (constantValue == LiteralNode.POSTSET_MARKER) {
-                    postsetValues.add(pos);
-                } else {
+                if (constantValue != LiteralNode.POSTSET_MARKER) {
                     final Property property = propertyMap.findProperty(key);
                     if (property != null) {
                         // normal property key
@@ -146,25 +142,34 @@
         // instantiate the script object with spill objects
         method.invoke(constructorNoLookup(objectClass, PropertyMap.class, long[].class, Object[].class));
 
-        helpOptimisticRecognizeDuplicateIdentity(method);
-
         // Set prefix array data if any
         if (arrayData.length() > 0) {
             method.dup();
             codegen.loadConstant(arrayData);
             method.invoke(virtualCallNoLookup(ScriptObject.class, "setArray", void.class, ArrayData.class));
         }
+    }
+
+    @Override
+    public void populateRange(final MethodEmitter method, final Type objectType, final int objectSlot, final int start, final int end) {
+        final int  callSiteFlags = codegen.getCallSiteFlags();
+        method.load(objectType, objectSlot);
 
         // set postfix values
-        for (final int i : postsetValues) {
+        for (int i = start; i < end; i++) {
             final MapTuple<Expression> tuple = tuples.get(i);
+
+            if (LiteralNode.isConstant(tuple.value)) {
+                continue;
+            }
+
             final Property property = propertyMap.findProperty(tuple.key);
+
             if (property == null) {
                 final int index = ArrayIndex.getArrayIndex(tuple.key);
                 assert ArrayIndex.isValidArrayIndex(index);
                 method.dup();
                 method.load(ArrayIndex.toLongIndex(index));
-                //method.println("putting " + tuple + " into arraydata");
                 loadTuple(method, tuple);
                 method.dynamicSetIndex(callSiteFlags);
             } else {
@@ -178,8 +183,7 @@
     @Override
     protected PropertyMap makeMap() {
         assert propertyMap == null : "property map already initialized";
-        final boolean dualFields = codegen.useDualFields();
-        final Class<? extends ScriptObject> clazz = dualFields ? JD.class : JO.class;
+        final Class<? extends ScriptObject> clazz = getAllocatorClass();
         propertyMap = new MapCreator<>(clazz, tuples).makeSpillMap(false, codegen.useDualFields());
         return propertyMap;
     }
@@ -188,4 +192,9 @@
     protected void loadValue(final Expression expr, final Type type) {
         codegen.loadExpressionAsType(expr, type);
     }
+
+    @Override
+    protected Class<? extends ScriptObject> getAllocatorClass() {
+        return codegen.useDualFields() ? JD.class : JO.class;
+    }
 }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/Splitter.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/Splitter.java	Wed Jul 05 20:51:27 2017 +0200
@@ -36,9 +36,11 @@
 import jdk.nashorn.internal.ir.LexicalContext;
 import jdk.nashorn.internal.ir.LiteralNode;
 import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode;
-import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode.ArrayUnit;
 import jdk.nashorn.internal.ir.Node;
+import jdk.nashorn.internal.ir.ObjectNode;
+import jdk.nashorn.internal.ir.PropertyNode;
 import jdk.nashorn.internal.ir.SplitNode;
+import jdk.nashorn.internal.ir.Splittable;
 import jdk.nashorn.internal.ir.Statement;
 import jdk.nashorn.internal.ir.visitor.NodeVisitor;
 import jdk.nashorn.internal.runtime.Context;
@@ -295,7 +297,7 @@
             final ArrayLiteralNode arrayLiteralNode = (ArrayLiteralNode) literal;
             final Node[]           value            = arrayLiteralNode.getValue();
             final int[]            postsets         = arrayLiteralNode.getPostsets();
-            final List<ArrayUnit>  units            = new ArrayList<>();
+            final List<Splittable.SplitRange> ranges = new ArrayList<>();
 
             long totalWeight = 0;
             int  lo          = 0;
@@ -309,7 +311,7 @@
 
                 if (totalWeight >= SPLIT_THRESHOLD) {
                     final CompileUnit unit = compiler.findUnit(totalWeight - weight);
-                    units.add(new ArrayUnit(unit, lo, i));
+                    ranges.add(new Splittable.SplitRange(unit, lo, i));
                     lo = i;
                     totalWeight = weight;
                 }
@@ -317,16 +319,59 @@
 
             if (lo != postsets.length) {
                 final CompileUnit unit = compiler.findUnit(totalWeight);
-                units.add(new ArrayUnit(unit, lo, postsets.length));
+                ranges.add(new Splittable.SplitRange(unit, lo, postsets.length));
             }
 
-            return arrayLiteralNode.setUnits(lc, units);
+            return arrayLiteralNode.setSplitRanges(lc, ranges);
         }
 
         return literal;
     }
 
     @Override
+    public Node leaveObjectNode(final ObjectNode objectNode) {
+        long weight = WeighNodes.weigh(objectNode);
+
+        if (weight < SPLIT_THRESHOLD) {
+            return objectNode;
+        }
+
+        final FunctionNode functionNode = lc.getCurrentFunction();
+        lc.setFlag(functionNode, FunctionNode.IS_SPLIT);
+
+        final List<Splittable.SplitRange> ranges        = new ArrayList<>();
+        final List<PropertyNode>          properties    = objectNode.getElements();
+        final boolean                     isSpillObject = properties.size() > CodeGenerator.OBJECT_SPILL_THRESHOLD;
+        long totalWeight = 0;
+        int  lo          = 0;
+
+        for (int i = 0; i < properties.size(); i++) {
+
+            final PropertyNode property = properties.get(i);
+            final boolean isConstant = LiteralNode.isConstant(property.getValue());
+
+            if (!isConstant || !isSpillObject) {
+                weight = isConstant ? 0 : WeighNodes.weigh(property.getValue());
+                totalWeight += WeighNodes.AASTORE_WEIGHT + weight;
+
+                if (totalWeight >= SPLIT_THRESHOLD) {
+                    final CompileUnit unit = compiler.findUnit(totalWeight - weight);
+                    ranges.add(new Splittable.SplitRange(unit, lo, i));
+                    lo = i;
+                    totalWeight = weight;
+                }
+            }
+        }
+
+        if (lo != properties.size()) {
+            final CompileUnit unit = compiler.findUnit(totalWeight);
+            ranges.add(new Splittable.SplitRange(unit, lo, properties.size()));
+        }
+
+        return objectNode.setSplitRanges(lc, ranges);
+    }
+
+    @Override
     public boolean enterFunctionNode(final FunctionNode node) {
         //only go into the function node for this splitter. any subfunctions are rejected
         return node == outermost;
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/WeighNodes.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/WeighNodes.java	Wed Jul 05 20:51:27 2017 +0200
@@ -44,12 +44,13 @@
 import jdk.nashorn.internal.ir.LexicalContext;
 import jdk.nashorn.internal.ir.LiteralNode;
 import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode;
-import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode.ArrayUnit;
 import jdk.nashorn.internal.ir.Node;
+import jdk.nashorn.internal.ir.ObjectNode;
 import jdk.nashorn.internal.ir.PropertyNode;
 import jdk.nashorn.internal.ir.ReturnNode;
 import jdk.nashorn.internal.ir.RuntimeNode;
 import jdk.nashorn.internal.ir.SplitNode;
+import jdk.nashorn.internal.ir.Splittable;
 import jdk.nashorn.internal.ir.SwitchNode;
 import jdk.nashorn.internal.ir.ThrowNode;
 import jdk.nashorn.internal.ir.TryNode;
@@ -88,6 +89,8 @@
     static final long THROW_WEIGHT     =  2;
     static final long VAR_WEIGHT       = 40;
     static final long WITH_WEIGHT      =  8;
+    static final long OBJECT_WEIGHT    = 16;
+    static final long SETPROP_WEIGHT   =  5;
 
     /** Accumulated weight. */
     private long weight;
@@ -213,7 +216,7 @@
             final ArrayLiteralNode arrayLiteralNode = (ArrayLiteralNode)literalNode;
             final Node[]           value            = arrayLiteralNode.getValue();
             final int[]            postsets         = arrayLiteralNode.getPostsets();
-            final List<ArrayUnit>  units            = arrayLiteralNode.getUnits();
+            final List<Splittable.SplitRange>  units            = arrayLiteralNode.getSplitRanges();
 
             if (units == null) {
                 for (final int postset : postsets) {
@@ -233,6 +236,27 @@
     }
 
     @Override
+    public boolean enterObjectNode(final ObjectNode objectNode) {
+        weight += OBJECT_WEIGHT;
+        final List<PropertyNode> properties = objectNode.getElements();
+        final boolean isSpillObject = properties.size() > CodeGenerator.OBJECT_SPILL_THRESHOLD;
+
+        for (final PropertyNode property : properties) {
+            if (!LiteralNode.isConstant(property.getValue())) {
+                weight += SETPROP_WEIGHT;
+                property.getValue().accept(this);
+            } else if (!isSpillObject) {
+                // constants in spill object are set via preset spill array,
+                // but fields objects need to set constants.
+                weight += SETPROP_WEIGHT;
+            }
+
+        }
+
+        return false;
+    }
+
+    @Override
     public Node leavePropertyNode(final PropertyNode propertyNode) {
         weight += LITERAL_WEIGHT;
         return propertyNode;
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/types/Type.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/types/Type.java	Wed Jul 05 20:51:27 2017 +0200
@@ -65,6 +65,7 @@
 import jdk.internal.org.objectweb.asm.Handle;
 import jdk.internal.org.objectweb.asm.MethodVisitor;
 import jdk.nashorn.internal.codegen.CompilerConstants.Call;
+import jdk.nashorn.internal.runtime.Context;
 import jdk.nashorn.internal.runtime.ScriptObject;
 import jdk.nashorn.internal.runtime.Undefined;
 import jdk.nashorn.internal.runtime.linker.Bootstrap;
@@ -256,6 +257,9 @@
         case jdk.internal.org.objectweb.asm.Type.DOUBLE:
             return NUMBER;
         case jdk.internal.org.objectweb.asm.Type.OBJECT:
+            if (Context.isStructureClass(itype.getClassName())) {
+                return SCRIPT_OBJECT;
+            }
             try {
                 return Type.typeFor(Class.forName(itype.getClassName()));
             } catch(final ClassNotFoundException e) {
@@ -949,7 +953,7 @@
     /**
      * This is the singleton for integer arrays
      */
-    public static final ArrayType INT_ARRAY = new ArrayType(int[].class) {
+    public static final ArrayType INT_ARRAY = putInCache(new ArrayType(int[].class) {
         private static final long serialVersionUID = 1L;
 
         @Override
@@ -973,12 +977,12 @@
         public Type getElementType() {
             return INT;
         }
-    };
+    });
 
     /**
      * This is the singleton for long arrays
      */
-    public static final ArrayType LONG_ARRAY = new ArrayType(long[].class) {
+    public static final ArrayType LONG_ARRAY = putInCache(new ArrayType(long[].class) {
         private static final long serialVersionUID = 1L;
 
         @Override
@@ -1002,12 +1006,12 @@
         public Type getElementType() {
             return LONG;
         }
-    };
+    });
 
     /**
      * This is the singleton for numeric arrays
      */
-    public static final ArrayType NUMBER_ARRAY = new ArrayType(double[].class) {
+    public static final ArrayType NUMBER_ARRAY = putInCache(new ArrayType(double[].class) {
         private static final long serialVersionUID = 1L;
 
         @Override
@@ -1031,13 +1035,7 @@
         public Type getElementType() {
             return NUMBER;
         }
-    };
-
-    /** Singleton for method handle arrays used for properties etc. */
-    public static final ArrayType METHODHANDLE_ARRAY = putInCache(new ArrayType(MethodHandle[].class));
-
-    /** This is the singleton for string arrays */
-    public static final ArrayType STRING_ARRAY = putInCache(new ArrayType(String[].class));
+    });
 
     /** This is the singleton for object arrays */
     public static final ArrayType OBJECT_ARRAY = putInCache(new ArrayType(Object[].class));
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/LiteralNode.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/LiteralNode.java	Wed Jul 05 20:51:27 2017 +0200
@@ -25,11 +25,9 @@
 
 package jdk.nashorn.internal.ir;
 
-import java.io.Serializable;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
-import jdk.nashorn.internal.codegen.CompileUnit;
 import jdk.nashorn.internal.codegen.types.ArrayType;
 import jdk.nashorn.internal.codegen.types.Type;
 import jdk.nashorn.internal.ir.annotations.Immutable;
@@ -583,6 +581,15 @@
         return POSTSET_MARKER;
     }
 
+    /**
+     * Test whether {@code object} represents a constant value.
+     * @param object a node or value object
+     * @return true if object is a constant value
+     */
+    public static boolean isConstant(final Object object) {
+        return objectAsConstant(object) != POSTSET_MARKER;
+    }
+
     private static final class NullLiteralNode extends PrimitiveLiteralNode<Object> {
         private static final long serialVersionUID = 1L;
 
@@ -614,7 +621,7 @@
      * Array literal node class.
      */
     @Immutable
-    public static final class ArrayLiteralNode extends LiteralNode<Expression[]> implements LexicalContextNode {
+    public static final class ArrayLiteralNode extends LiteralNode<Expression[]> implements LexicalContextNode, Splittable {
         private static final long serialVersionUID = 1L;
 
         /** Array element type. */
@@ -626,8 +633,8 @@
         /** Indices of array elements requiring computed post sets. */
         private final int[] postsets;
 
-        /** Sub units with indexes ranges, in which to split up code generation, for large literals */
-        private final List<ArrayUnit> units;
+        /** Ranges for splitting up large literals in code generation */
+        private final List<Splittable.SplitRange> splitRanges;
 
         @Override
         public boolean isArray() {
@@ -635,64 +642,13 @@
         }
 
 
-        /**
-         * An ArrayUnit is a range in an ArrayLiteral. ArrayLiterals can
-         * be split if they are too large, for bytecode generation reasons
-         */
-        public static final class ArrayUnit implements CompileUnitHolder, Serializable {
-            private static final long serialVersionUID = 1L;
-
-            /** Compile unit associated with the postsets range. */
-            private final CompileUnit compileUnit;
-
-            /** postsets range associated with the unit (hi not inclusive). */
-            private final int lo, hi;
-
-            /**
-             * Constructor
-             * @param compileUnit compile unit
-             * @param lo lowest array index in unit
-             * @param hi highest array index in unit + 1
-             */
-            public ArrayUnit(final CompileUnit compileUnit, final int lo, final int hi) {
-                this.compileUnit = compileUnit;
-                this.lo   = lo;
-                this.hi   = hi;
-            }
-
-            /**
-             * Get the high index position of the ArrayUnit (non inclusive)
-             * @return high index position
-             */
-            public int getHi() {
-                return hi;
-            }
-
-            /**
-             * Get the low index position of the ArrayUnit (inclusive)
-             * @return low index position
-             */
-            public int getLo() {
-                return lo;
-            }
-
-            /**
-             * The array compile unit
-             * @return array compile unit
-             */
-            @Override
-            public CompileUnit getCompileUnit() {
-                return compileUnit;
-            }
-        }
-
         private static final class ArrayLiteralInitializer {
 
             static ArrayLiteralNode initialize(final ArrayLiteralNode node) {
                 final Type elementType = computeElementType(node.value);
                 final int[] postsets = computePostsets(node.value);
                 final Object presets = computePresets(node.value, elementType, postsets);
-                return new ArrayLiteralNode(node, node.value, elementType, postsets, presets, node.units);
+                return new ArrayLiteralNode(node, node.value, elementType, postsets, presets, node.splitRanges);
             }
 
             private static Type computeElementType(final Expression[] value) {
@@ -725,7 +681,7 @@
 
                 for (int i = 0; i < value.length; i++) {
                     final Expression element = value[i];
-                    if (element == null || objectAsConstant(element) == POSTSET_MARKER) {
+                    if (element == null || !isConstant(element)) {
                         computed[nComputed++] = i;
                     }
                 }
@@ -842,19 +798,19 @@
             this.elementType = Type.UNKNOWN;
             this.presets     = null;
             this.postsets    = null;
-            this.units       = null;
+            this.splitRanges = null;
         }
 
         /**
          * Copy constructor
          * @param node source array literal node
          */
-        private ArrayLiteralNode(final ArrayLiteralNode node, final Expression[] value, final Type elementType, final int[] postsets, final Object presets, final List<ArrayUnit> units) {
+        private ArrayLiteralNode(final ArrayLiteralNode node, final Expression[] value, final Type elementType, final int[] postsets, final Object presets, final List<Splittable.SplitRange> splitRanges) {
             super(node, value);
             this.elementType = elementType;
             this.postsets    = postsets;
             this.presets     = presets;
-            this.units       = units;
+            this.splitRanges = splitRanges;
         }
 
         /**
@@ -946,26 +902,27 @@
         }
 
         /**
-         * Get the array units that make up this ArrayLiteral
-         * @see ArrayUnit
-         * @return list of array units
+         * Get the split ranges for this ArrayLiteral, or null if this array does not have to be split.
+         * @see Splittable.SplitRange
+         * @return list of split ranges
          */
-        public List<ArrayUnit> getUnits() {
-            return units == null ? null : Collections.unmodifiableList(units);
+        @Override
+        public List<Splittable.SplitRange> getSplitRanges() {
+            return splitRanges == null ? null : Collections.unmodifiableList(splitRanges);
         }
 
         /**
-         * Set the ArrayUnits that make up this ArrayLiteral
+         * Set the SplitRanges that make up this ArrayLiteral
          * @param lc lexical context
-         * @see ArrayUnit
-         * @param units list of array units
-         * @return new or changed arrayliteralnode
+         * @see Splittable.SplitRange
+         * @param splitRanges list of split ranges
+         * @return new or changed node
          */
-        public ArrayLiteralNode setUnits(final LexicalContext lc, final List<ArrayUnit> units) {
-            if (this.units == units) {
+        public ArrayLiteralNode setSplitRanges(final LexicalContext lc, final List<Splittable.SplitRange> splitRanges) {
+            if (this.splitRanges == splitRanges) {
                 return this;
             }
-            return Node.replaceInLexicalContext(lc, this, new ArrayLiteralNode(this, value, elementType, postsets, presets, units));
+            return Node.replaceInLexicalContext(lc, this, new ArrayLiteralNode(this, value, elementType, postsets, presets, splitRanges));
         }
 
         @Override
@@ -987,7 +944,7 @@
             if (this.value == value) {
                 return this;
             }
-            return Node.replaceInLexicalContext(lc, this, new ArrayLiteralNode(this, value, elementType, postsets, presets, units));
+            return Node.replaceInLexicalContext(lc, this, new ArrayLiteralNode(this, value, elementType, postsets, presets, splitRanges));
         }
 
         private ArrayLiteralNode setValue(final LexicalContext lc, final List<Expression> value) {
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/ObjectNode.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/ObjectNode.java	Wed Jul 05 20:51:27 2017 +0200
@@ -27,6 +27,7 @@
 
 import java.util.Collections;
 import java.util.List;
+import java.util.RandomAccess;
 import jdk.nashorn.internal.codegen.types.Type;
 import jdk.nashorn.internal.ir.annotations.Immutable;
 import jdk.nashorn.internal.ir.visitor.NodeVisitor;
@@ -35,12 +36,15 @@
  * IR representation of an object literal.
  */
 @Immutable
-public final class ObjectNode extends Expression {
+public final class ObjectNode extends Expression implements LexicalContextNode, Splittable {
     private static final long serialVersionUID = 1L;
 
     /** Literal elements. */
     private final List<PropertyNode> elements;
 
+    /** Ranges for splitting large literals over multiple compile units in codegen. */
+    private final List<Splittable.SplitRange> splitRanges;
+
     /**
      * Constructor
      *
@@ -51,19 +55,27 @@
     public ObjectNode(final long token, final int finish, final List<PropertyNode> elements) {
         super(token, finish);
         this.elements = elements;
+        this.splitRanges = null;
+        assert elements instanceof RandomAccess : "Splitting requires random access lists";
     }
 
-    private ObjectNode(final ObjectNode objectNode, final List<PropertyNode> elements) {
+    private ObjectNode(final ObjectNode objectNode, final List<PropertyNode> elements,
+                       final List<Splittable.SplitRange> splitRanges ) {
         super(objectNode);
         this.elements = elements;
+        this.splitRanges = splitRanges;
     }
 
     @Override
     public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
+        return Acceptor.accept(this, visitor);
+    }
+
+    @Override
+    public Node accept(final LexicalContext lc, final NodeVisitor<? extends LexicalContext> visitor) {
         if (visitor.enterObjectNode(this)) {
-            return visitor.leaveObjectNode(setElements(Node.accept(visitor, elements)));
+            return visitor.leaveObjectNode(setElements(lc, Node.accept(visitor, elements)));
         }
-
         return this;
     }
 
@@ -102,10 +114,35 @@
         return Collections.unmodifiableList(elements);
     }
 
-    private ObjectNode setElements(final List<PropertyNode> elements) {
+    private ObjectNode setElements(final LexicalContext lc, final List<PropertyNode> elements) {
         if (this.elements == elements) {
             return this;
         }
-        return new ObjectNode(this, elements);
+        return Node.replaceInLexicalContext(lc, this, new ObjectNode(this, elements, this.splitRanges));
     }
+
+    /**
+     * Set the split ranges for this ObjectNode
+     * @see Splittable.SplitRange
+     * @param lc the lexical context
+     * @param splitRanges list of split ranges
+     * @return new or changed object node
+     */
+    public ObjectNode setSplitRanges(final LexicalContext lc, final List<Splittable.SplitRange> splitRanges) {
+        if (this.splitRanges == splitRanges) {
+            return this;
+        }
+        return Node.replaceInLexicalContext(lc, this, new ObjectNode(this, elements, splitRanges));
+    }
+
+    /**
+     * Get the split ranges for this ObjectNode, or null if the object is not split.
+     * @see Splittable.SplitRange
+     * @return list of split ranges
+     */
+    @Override
+    public List<Splittable.SplitRange> getSplitRanges() {
+        return splitRanges == null ? null : Collections.unmodifiableList(splitRanges);
+    }
+
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/Splittable.java	Wed Jul 05 20:51:27 2017 +0200
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.nashorn.internal.ir;
+
+import java.io.Serializable;
+import java.util.List;
+import jdk.nashorn.internal.codegen.CompileUnit;
+
+/**
+ * An interface for splittable expressions.
+ */
+public interface Splittable {
+
+    /**
+     * Get a list of split ranges for this splittable expression, or null
+     * if the expression should not be split.
+     *
+     * @return a list of split ranges
+     */
+    List<SplitRange> getSplitRanges();
+
+    /**
+     * A SplitRange is a range in a splittable expression. It defines the
+     * boundaries of the split range and provides a compile unit for code generation.
+     */
+    final class SplitRange implements CompileUnitHolder, Serializable {
+        private static final long serialVersionUID = 1L;
+
+        /** Compile unit associated with the postsets range. */
+        private final CompileUnit compileUnit;
+
+        /** postsets range associated with the unit (hi not inclusive). */
+        private final int low, high;
+
+        /**
+         * Constructor
+         * @param compileUnit compile unit
+         * @param low lowest array index in unit
+         * @param high highest array index in unit + 1
+         */
+        public SplitRange(final CompileUnit compileUnit, final int low, final int high) {
+            this.compileUnit = compileUnit;
+            this.low   = low;
+            this.high   = high;
+        }
+
+        /**
+         * Get the high index position of the ArrayUnit (exclusive)
+         * @return high index position
+         */
+        public int getHigh() {
+            return high;
+        }
+
+        /**
+         * Get the low index position of the ArrayUnit (inclusive)
+         * @return low index position
+         */
+        public int getLow() {
+            return low;
+        }
+
+        /**
+         * The array compile unit
+         * @return array compile unit
+         */
+        @Override
+        public CompileUnit getCompileUnit() {
+            return compileUnit;
+        }
+    }
+}
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Context.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Context.java	Wed Jul 05 20:51:27 2017 +0200
@@ -64,7 +64,6 @@
 import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.Objects;
-import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.concurrent.atomic.LongAdder;
@@ -301,7 +300,47 @@
         }
     }
 
-    private final Map<CodeSource, Reference<Class<?>>> anonymousHostClasses = new ConcurrentHashMap<>();
+    private final Map<CodeSource, HostClassReference> anonymousHostClasses = new HashMap<>();
+    private final ReferenceQueue<Class<?>> anonymousHostClassesRefQueue = new ReferenceQueue<>();
+
+    private static class HostClassReference extends WeakReference<Class<?>> {
+        final CodeSource codeSource;
+
+        HostClassReference(final CodeSource codeSource, final Class<?> clazz, final ReferenceQueue<Class<?>> refQueue) {
+            super(clazz, refQueue);
+            this.codeSource = codeSource;
+        }
+    }
+
+    private synchronized Class<?> getAnonymousHostClass(final CodeSource codeSource) {
+        // Remove cleared entries
+        for(;;) {
+            final HostClassReference clearedRef = (HostClassReference)anonymousHostClassesRefQueue.poll();
+            if (clearedRef == null) {
+                break;
+            }
+            anonymousHostClasses.remove(clearedRef.codeSource, clearedRef);
+        }
+
+        // Try to find an existing host class
+        final Reference<Class<?>> ref = anonymousHostClasses.get(codeSource);
+        if (ref != null) {
+            final Class<?> existingHostClass = ref.get();
+            if (existingHostClass != null) {
+                return existingHostClass;
+            }
+        }
+
+        // Define a new host class if existing is not found
+        final Class<?> newHostClass = createNewLoader().installClass(
+                // NOTE: we're defining these constants in AnonymousContextCodeInstaller so they are not
+                // initialized if we don't use AnonymousContextCodeInstaller. As this method is only ever
+                // invoked from AnonymousContextCodeInstaller, this is okay.
+                AnonymousContextCodeInstaller.ANONYMOUS_HOST_CLASS_NAME,
+                AnonymousContextCodeInstaller.ANONYMOUS_HOST_CLASS_BYTES, codeSource);
+        anonymousHostClasses.put(codeSource, new HostClassReference(codeSource, newHostClass, anonymousHostClassesRefQueue));
+        return newHostClass;
+    }
 
     private static final class AnonymousContextCodeInstaller extends ContextCodeInstaller {
         private static final Unsafe UNSAFE = getUnsafe();
@@ -310,9 +349,9 @@
 
         private final Class<?> hostClass;
 
-        private AnonymousContextCodeInstaller(final Context context, final CodeSource codeSource) {
+        private AnonymousContextCodeInstaller(final Context context, final CodeSource codeSource, final Class<?> hostClass) {
             super(context, codeSource);
-            hostClass = getAnonymousHostClass();
+            this.hostClass = hostClass;
         }
 
         @Override
@@ -335,19 +374,6 @@
             return new NamedContextCodeInstaller(context, codeSource, context.createNewLoader());
         }
 
-        private Class<?> getAnonymousHostClass() {
-            final Reference<Class<?>> ref = context.anonymousHostClasses.get(codeSource);
-            if (ref != null) {
-                final Class<?> existingHostClass = ref.get();
-                if (existingHostClass != null) {
-                    return existingHostClass;
-                }
-            }
-            final Class<?> newHostClass = context.createNewLoader().installClass(ANONYMOUS_HOST_CLASS_NAME, ANONYMOUS_HOST_CLASS_BYTES, codeSource);
-            context.anonymousHostClasses.put(codeSource, new WeakReference<>(newHostClass));
-            return newHostClass;
-        }
-
         private static final byte[] getAnonymousHostClassBytes() {
             final ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
             cw.visit(V1_7, Opcodes.ACC_INTERFACE | Opcodes.ACC_ABSTRACT, ANONYMOUS_HOST_CLASS_NAME.replace('.', '/'), null, "java/lang/Object", null);
@@ -1034,6 +1060,16 @@
     }
 
     /**
+     * Is {@code className} the name of a structure class?
+     *
+     * @param className a class name
+     * @return true if className is a structure class name
+     */
+    public static boolean isStructureClass(final String className) {
+        return StructureLoader.isStructureClass(className);
+    }
+
+    /**
      * Checks that the given Class can be accessed from no permissions context.
      *
      * @param clazz Class object
@@ -1404,7 +1440,7 @@
             final ScriptLoader loader = env._loader_per_compile ? createNewLoader() : scriptLoader;
             installer = new NamedContextCodeInstaller(this, cs, loader);
         } else {
-            installer = new AnonymousContextCodeInstaller(this, cs);
+            installer = new AnonymousContextCodeInstaller(this, cs, getAnonymousHostClass(cs));
         }
 
         if (storedScript == null) {
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/JavaAdapterBytecodeGenerator.java	Sat Sep 26 09:22:24 2015 -0700
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/JavaAdapterBytecodeGenerator.java	Wed Jul 05 20:51:27 2017 +0200
@@ -203,6 +203,8 @@
 
     // This is the superclass for our generated adapter.
     private final Class<?> superClass;
+    // Interfaces implemented by our generated adapter.
+    private final List<Class<?>> interfaces;
     // Class loader used as the parent for the class loader we'll create to load the generated class. It will be a class
     // loader that has the visibility of all original types (class to extend and interfaces to implement) and of the
     // Nashorn classes.
@@ -254,6 +256,7 @@
         assert interfaces != null;
 
         this.superClass = superClass;
+        this.interfaces = interfaces;
         this.classOverride = classOverride;
         this.commonLoader = commonLoader;
         cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS) {
@@ -1031,6 +1034,24 @@
         endMethod(mv);
     }
 
+    // find the appropriate super type to use for invokespecial on the given interface
+    private Class<?> findInvokespecialOwnerFor(final Class<?> cl) {
+        assert Modifier.isInterface(cl.getModifiers()) : cl + " is not an interface";
+
+        if (cl.isAssignableFrom(superClass)) {
+            return superClass;
+        }
+
+        for (final Class<?> iface : interfaces) {
+             if (cl.isAssignableFrom(iface)) {
+                 return iface;
+             }
+        }
+
+        // we better that interface that extends the given interface!
+        throw new AssertionError("can't find the class/interface that extends " + cl);
+    }
+
     private void emitSuperCall(final InstructionAdapter mv, final Class<?> owner, final String name, final String methodDesc) {
         mv.visitVarInsn(ALOAD, 0);
         int nextParam = 1;
@@ -1042,7 +1063,9 @@
 
         // default method - non-abstract, interface method
         if (Modifier.isInterface(owner.getModifiers())) {
-            mv.invokespecial(Type.getInternalName(owner), name, methodDesc, false);
+            // we should call default method on the immediate "super" type - not on (possibly)
+            // the indirectly inherited interface class!
+            mv.invokespecial(Type.getInternalName(findInvokespecialOwnerFor(owner)), name, methodDesc, false);
         } else {
             mv.invokespecial(superClassName, name, methodDesc, false);
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8134488.js	Wed Jul 05 20:51:27 2017 +0200
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8134488: var statement in if(false) block incorrectly evacuated into enclosing function
+ *
+ * @test
+ * @run
+ */
+
+var x = "string"; 
+print(x); 
+
+(function f1() { 
+    (function f2() { 
+        // If it finds both 'print' and 'x', it'll print 'string'.
+        print(x); 
+    })(); 
+
+    if (false) { 
+        (function f3() { 
+            var x; 
+        })(); 
+    } 
+
+})(); 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8134488.js.EXPECTED	Wed Jul 05 20:51:27 2017 +0200
@@ -0,0 +1,2 @@
+string
+string
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8134490.js	Wed Jul 05 20:51:27 2017 +0200
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8134490: Dead var statement evacuation incorrectly descends into nested functions
+ *
+ * @test
+ * @run
+ */
+
+var v1; 
+
+function f1() 
+{ 
+v1 = 1; 
+return true; 
+(function () { var v1; })(); 
+} 
+
+f1(); 
+// If it executes without throwing an exception in code generator, it's working.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8135190.js	Wed Jul 05 20:51:27 2017 +0200
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8135190: Method code too large in Babel browser.js script
+ *
+ * @test
+ * @run
+ */
+
+// Make sure huge object literals are parsed correctly and don't throw
+// (using buildObject -> JSON.stringify -> eval -> testObject)
+
+function buildObject(n, d) {
+    if (n < 2) {
+        return {name: "property", type: "identifier"};
+    }
+    var obj = {};
+    for (var i = 0; i < n; i++) {
+        obj["expr" + i] = buildObject(Math.floor(n / d), d);
+    }
+    return obj;
+}
+
+function testObject(obj, n, d) {
+    var keys = Object.keys(obj);
+    if (n < 2) {
+        Assert.assertTrue(keys.length === 2);
+        Assert.assertTrue(keys[0] === "name");
+        Assert.assertTrue(keys[1] === "type");
+    } else {
+        Assert.assertTrue(keys.length === n);
+        for (var i = 0; i < n; i++) {
+            Assert.assertTrue(keys[i] === "expr" + i);
+        }
+    }
+    if (n >= 2) {
+        for (var k in keys) {
+            testObject(obj[keys[k]], Math.floor(n / d), d)
+        }
+    }
+}
+
+var fieldObject = (eval("(" + JSON.stringify(buildObject(25, 2)) + ")"));
+testObject(fieldObject, 25, 2);
+var spillObject = (eval("(" + JSON.stringify(buildObject(1000, 100)) + ")"));
+testObject(spillObject, 1000, 100);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8137134.js	Wed Jul 05 20:51:27 2017 +0200
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8137134: invokespecial on indirect super interface is generated by Java adapter generator
+ *
+ * @test
+ * @run
+ */
+
+var B = Java.type("jdk.nashorn.test.models.B");
+var b1 = new B() {}
+print(b1.a());
+print(b1.b());
+
+var b2 = new B() {
+    b: function() {
+        return "from B.b in script";
+    }
+};
+
+print(b2.a());
+print(b2.b());
+
+var b3 = new B() {
+    a: function() {
+        return "from A.a in script";
+    },
+    b: function() {
+        return "from B.b in script";
+    }
+};
+
+print(b3.a());
+print(b3.b());
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8137134.js.EXPECTED	Wed Jul 05 20:51:27 2017 +0200
@@ -0,0 +1,6 @@
+from A.a
+from B.b
+from A.a
+from B.b in script
+from A.a in script
+from B.b in script
--- a/nashorn/test/script/currently-failing/gettersetter.js	Sat Sep 26 09:22:24 2015 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/**
- * @test
- * @option -Dnashorn.debug=true
- * @fork
- */
-
-load(__DIR__ + "maputil.js");
-
-function Foo() {
-    return {
-       get foo() { return 42; },
-       set foo(x) {}
-    }
-}
-
-var obj1 = Foo();
-var obj2 = Foo();
-
-assertSameMap(obj1, obj2, "Object literals before change");
-
-Object.defineProperty(obj2, "foo", { get: function() { return 'hello' } });
-assertSameMap(obj1, obj2);
-
-Object.defineProperty(obj2, "foo", { set: function(x) { print(x) } });
-assertSameMap(obj1, obj2);
--- a/nashorn/test/script/currently-failing/property_delete.js	Sat Sep 26 09:22:24 2015 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/**
- * @test
- * @option -Dnashorn.debug=true
- * @fork
- */
-
-load(__DIR__ + "maputil.js");
-
-function Foo() {
-    this.x = 33;
-}
-
-var obj1 = new Foo();
-var obj2 = new Foo();
-
-assertSameMap(obj1, obj2);
-
-// property deletion at same callsite
-function deleteX(obj) {
-   delete obj.x;
-}
-deleteX(obj1);
-deleteX(obj2);
-
-assertSameMap(obj1, obj2);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/maptests/gettersetter.js	Wed Jul 05 20:51:27 2017 +0200
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @option -Dnashorn.debug=true
+ * @fork
+ */
+
+load(__DIR__ + "maputil.js");
+
+function Foo() {
+    return {
+       get foo() { return 42; },
+       set foo(x) {}
+    }
+}
+
+var obj1 = Foo();
+var obj2 = Foo();
+
+assertSameMap(obj1, obj2, "Object literals before change");
+
+Object.defineProperty(obj2, "foo", { get: function() { return 'hello' } });
+assertSameMap(obj1, obj2);
+
+Object.defineProperty(obj2, "foo", { set: function(x) { print(x) } });
+assertSameMap(obj1, obj2);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/maptests/property_delete.js	Wed Jul 05 20:51:27 2017 +0200
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @option -Dnashorn.debug=true
+ * @fork
+ */
+
+load(__DIR__ + "maputil.js");
+
+function Foo() {
+    this.x = 33;
+}
+
+var obj1 = new Foo();
+var obj2 = new Foo();
+
+assertSameMap(obj1, obj2);
+
+// property deletion at same callsite
+function deleteX(obj) {
+   delete obj.x;
+}
+deleteX(obj1);
+deleteX(obj2);
+
+assertEqualWithoutTypeMap(obj1, obj2);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/src/jdk/nashorn/test/models/A.java	Wed Jul 05 20:51:27 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 jdk.nashorn.test.models;
+
+public interface A {
+    default String a() {
+        return "from A.a";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/src/jdk/nashorn/test/models/B.java	Wed Jul 05 20:51:27 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 jdk.nashorn.test.models;
+
+public interface B extends A {
+    default String b() {
+        return "from B.b";
+    }
+}