Merge
authorcoleenp
Wed, 08 Nov 2017 16:03:35 -0500
changeset 47813 fedbf1b866a7
parent 47812 b140fe4ff916 (current diff)
parent 47811 d76a6042f5d7 (diff)
child 47814 19fad4c04a15
Merge
src/java.base/share/classes/jdk/internal/module/ClassFileAttributes.java
src/java.desktop/unix/legal/fontconfig.md
src/java.desktop/unix/native/common/awt/fontconfig.h
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/ArrayCopySlowPathNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/ArrayCopyUnrollNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/UnsafeArrayCopyNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/UnsafeArrayCopySnippets.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/DivNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/BasicIdealGraphPrinter.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/IdealGraphPrinter.java
src/jdk.rmic/share/classes/sun/rmi/rmic/newrmic/BatchEnvironment.java
src/jdk.rmic/share/classes/sun/rmi/rmic/newrmic/Constants.java
src/jdk.rmic/share/classes/sun/rmi/rmic/newrmic/Generator.java
src/jdk.rmic/share/classes/sun/rmi/rmic/newrmic/IndentingWriter.java
src/jdk.rmic/share/classes/sun/rmi/rmic/newrmic/Main.java
src/jdk.rmic/share/classes/sun/rmi/rmic/newrmic/Resources.java
src/jdk.rmic/share/classes/sun/rmi/rmic/newrmic/jrmp/Constants.java
src/jdk.rmic/share/classes/sun/rmi/rmic/newrmic/jrmp/JrmpGenerator.java
src/jdk.rmic/share/classes/sun/rmi/rmic/newrmic/jrmp/RemoteClass.java
src/jdk.rmic/share/classes/sun/rmi/rmic/newrmic/jrmp/StubSkeletonWriter.java
src/jdk.rmic/share/classes/sun/rmi/rmic/newrmic/jrmp/Util.java
test/jdk/com/sun/awt/Translucency/WindowOpacity.java
test/jdk/javax/swing/JTextPane/bug8025082.java
test/jdk/sun/rmi/rmic/newrmic/equivalence/Agent.java
test/jdk/sun/rmi/rmic/newrmic/equivalence/AgentServer.java
test/jdk/sun/rmi/rmic/newrmic/equivalence/AgentServerImpl.java
test/jdk/sun/rmi/rmic/newrmic/equivalence/Apple.java
test/jdk/sun/rmi/rmic/newrmic/equivalence/AppleEvent.java
test/jdk/sun/rmi/rmic/newrmic/equivalence/AppleImpl.java
test/jdk/sun/rmi/rmic/newrmic/equivalence/AppleUser.java
test/jdk/sun/rmi/rmic/newrmic/equivalence/AppleUserImpl.java
test/jdk/sun/rmi/rmic/newrmic/equivalence/Callback.java
test/jdk/sun/rmi/rmic/newrmic/equivalence/ComputeServer.java
test/jdk/sun/rmi/rmic/newrmic/equivalence/ComputeServerImpl.java
test/jdk/sun/rmi/rmic/newrmic/equivalence/CountInterface.java
test/jdk/sun/rmi/rmic/newrmic/equivalence/CountServerImpl.java
test/jdk/sun/rmi/rmic/newrmic/equivalence/DayTimeInterface.java
test/jdk/sun/rmi/rmic/newrmic/equivalence/DayTimeServerImpl.java
test/jdk/sun/rmi/rmic/newrmic/equivalence/G1.java
test/jdk/sun/rmi/rmic/newrmic/equivalence/G1Impl.java
test/jdk/sun/rmi/rmic/newrmic/equivalence/MyObject.java
test/jdk/sun/rmi/rmic/newrmic/equivalence/MyObjectImpl.java
test/jdk/sun/rmi/rmic/newrmic/equivalence/NotActivatableInterface.java
test/jdk/sun/rmi/rmic/newrmic/equivalence/NotActivatableServerImpl.java
test/jdk/sun/rmi/rmic/newrmic/equivalence/Orange.java
test/jdk/sun/rmi/rmic/newrmic/equivalence/OrangeEcho.java
test/jdk/sun/rmi/rmic/newrmic/equivalence/OrangeEchoImpl.java
test/jdk/sun/rmi/rmic/newrmic/equivalence/OrangeImpl.java
test/jdk/sun/rmi/rmic/newrmic/equivalence/Server.java
test/jdk/sun/rmi/rmic/newrmic/equivalence/ServerImpl.java
test/jdk/sun/rmi/rmic/newrmic/equivalence/Task.java
test/jdk/sun/rmi/rmic/newrmic/equivalence/TestInterface.java
test/jdk/sun/rmi/rmic/newrmic/equivalence/batch.sh
test/jdk/sun/rmi/rmic/newrmic/equivalence/run.sh
test/langtools/tools/javac/diags/examples/PatchModuleWithRelease/PatchModuleWithRelease.java
test/langtools/tools/javac/diags/examples/PatchModuleWithRelease/patchmodule/java.base/java/lang/Test.java
--- a/.hgtags	Mon Nov 06 19:45:47 2017 +0100
+++ b/.hgtags	Wed Nov 08 16:03:35 2017 -0500
@@ -454,3 +454,4 @@
 b87d7b5d5dedc1185e5929470f945b7378cdb3ad jdk-10+27
 92f08900cb3c0d694e5c529a676c1c9e5909193f jdk-10+28
 a6e591e12f122768f675428e1e5a838fd0e9c7ec jdk-10+29
+8fee80b92e65149f7414250fd5e34b6f35d417b4 jdk-10+30
--- a/make/CompileToolsHotspot.gmk	Mon Nov 06 19:45:47 2017 +0100
+++ b/make/CompileToolsHotspot.gmk	Wed Nov 08 16:03:35 2017 -0500
@@ -67,6 +67,7 @@
           $(SRC_DIR)/org.graalvm.compiler.phases.common/src \
           $(SRC_DIR)/org.graalvm.compiler.serviceprovider/src \
           $(SRC_DIR)/org.graalvm.compiler.virtual/src \
+          $(SRC_DIR)/org.graalvm.graphio/src \
           $(SRC_DIR)/org.graalvm.util/src \
           $(VM_CI_SRC_DIR)/jdk.vm.ci.code/src \
           $(VM_CI_SRC_DIR)/jdk.vm.ci.common/src \
@@ -125,6 +126,7 @@
           $(SRC_DIR)/org.graalvm.compiler.nodeinfo/src \
           $(SRC_DIR)/org.graalvm.compiler.options/src \
           $(SRC_DIR)/org.graalvm.compiler.serviceprovider/src \
+          $(SRC_DIR)/org.graalvm.graphio/src \
           $(SRC_DIR)/org.graalvm.util/src \
           $(VM_CI_SRC_DIR)/jdk.vm.ci.code/src \
           $(VM_CI_SRC_DIR)/jdk.vm.ci.common/src \
--- a/make/autoconf/basics.m4	Mon Nov 06 19:45:47 2017 +0100
+++ b/make/autoconf/basics.m4	Wed Nov 08 16:03:35 2017 -0500
@@ -639,6 +639,14 @@
         elif test -d "$DEVKIT_ROOT/$host/sys-root"; then
           SYSROOT="$DEVKIT_ROOT/$host/sys-root"
         fi
+
+        if test "x$DEVKIT_ROOT" != x; then
+          DEVKIT_LIB_DIR="$DEVKIT_ROOT/lib"
+          if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then
+            DEVKIT_LIB_DIR="$DEVKIT_ROOT/lib64"
+          fi
+          AC_SUBST(DEVKIT_LIB_DIR)
+        fi
       ]
   )
 
--- a/make/autoconf/configure.ac	Mon Nov 06 19:45:47 2017 +0100
+++ b/make/autoconf/configure.ac	Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
 SRC#
-# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -203,6 +203,9 @@
 JDKOPT_SETUP_DEBUG_SYMBOLS
 JDKOPT_SETUP_CODE_COVERAGE
 
+# AddressSanitizer
+JDKOPT_SETUP_ADDRESS_SANITIZER
+
 # Need toolchain to setup dtrace
 HOTSPOT_SETUP_DTRACE
 HOTSPOT_ENABLE_DISABLE_AOT
--- a/make/autoconf/generated-configure.sh	Mon Nov 06 19:45:47 2017 +0100
+++ b/make/autoconf/generated-configure.sh	Wed Nov 08 16:03:35 2017 -0500
@@ -690,6 +690,7 @@
 FREETYPE_BUNDLE_LIB_PATH
 FREETYPE_LIBS
 FREETYPE_CFLAGS
+FONTCONFIG_CFLAGS
 CUPS_CFLAGS
 X_EXTRA_LIBS
 X_LIBS
@@ -704,6 +705,7 @@
 BUILD_GTEST
 ENABLE_CDS
 ENABLE_AOT
+ASAN_ENABLED
 GCOV_ENABLED
 ZIP_EXTERNAL_DEBUG_SYMBOLS
 COPY_DEBUG_SYMBOLS
@@ -958,6 +960,7 @@
 SPEC
 SDKROOT
 XCODEBUILD
+DEVKIT_LIB_DIR
 JVM_VARIANT_MAIN
 VALID_JVM_VARIANTS
 JVM_VARIANTS
@@ -1171,6 +1174,7 @@
 enable_debug_symbols
 enable_zip_debug_info
 enable_native_coverage
+enable_asan
 enable_dtrace
 enable_aot
 enable_cds
@@ -1181,6 +1185,8 @@
 with_x
 with_cups
 with_cups_include
+with_fontconfig
+with_fontconfig_include
 with_freetype
 with_freetype_include
 with_freetype_lib
@@ -1976,6 +1982,7 @@
   --enable-native-coverage
                           enable native compilation with code coverage
                           data[disabled]
+  --enable-asan           enable AddressSanitizer if possible [disabled]
   --enable-dtrace[=yes/no/auto]
                           enable dtrace. Default is auto, where dtrace is
                           enabled if all dependencies are present.
@@ -2109,6 +2116,10 @@
   --with-cups             specify prefix directory for the cups package
                           (expecting the headers under PATH/include)
   --with-cups-include     specify directory for the cups include files
+  --with-fontconfig       specify prefix directory for the fontconfig package
+                          (expecting the headers under PATH/include)
+  --with-fontconfig-include
+                          specify directory for the fontconfig include files
   --with-freetype         specify prefix directory for the freetype package
                           (expecting the libraries under PATH/lib and the
                           headers under PATH/include)
@@ -4166,6 +4177,8 @@
       PKGHANDLER_COMMAND="sudo apt-get install libasound2-dev" ;;
     cups)
       PKGHANDLER_COMMAND="sudo apt-get install libcups2-dev" ;;
+    fontconfig)
+      PKGHANDLER_COMMAND="sudo apt-get install libfontconfig1-dev" ;;
     freetype)
       PKGHANDLER_COMMAND="sudo apt-get install libfreetype6-dev" ;;
     ffi)
@@ -4189,6 +4202,8 @@
       PKGHANDLER_COMMAND="sudo yum install alsa-lib-devel" ;;
     cups)
       PKGHANDLER_COMMAND="sudo yum install cups-devel" ;;
+    fontconfig)
+      PKGHANDLER_COMMAND="sudo yum install fontconfig-devel" ;;
     freetype)
       PKGHANDLER_COMMAND="sudo yum install freetype-devel" ;;
     x11)
@@ -4403,6 +4418,12 @@
 #
 
 
+###############################################################################
+#
+# AddressSanitizer
+#
+
+
 ################################################################################
 #
 # Static build support.  When enabled will generate static
@@ -4746,6 +4767,36 @@
 ################################################################################
 
 
+#
+# Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+# 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.
+#
+
+################################################################################
+# Setup fontconfig
+################################################################################
+
+
 
 ################################################################################
 # Determine which libraries are needed for this configuration
@@ -5115,7 +5166,7 @@
 #CUSTOM_AUTOCONF_INCLUDE
 
 # Do not change or remove the following line, it is needed for consistency checks:
-DATE_WHEN_GENERATED=1509013542
+DATE_WHEN_GENERATED=1509128484
 
 ###############################################################################
 #
@@ -17273,6 +17324,14 @@
           SYSROOT="$DEVKIT_ROOT/$host/sys-root"
         fi
 
+        if test "x$DEVKIT_ROOT" != x; then
+          DEVKIT_LIB_DIR="$DEVKIT_ROOT/lib"
+          if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then
+            DEVKIT_LIB_DIR="$DEVKIT_ROOT/lib64"
+          fi
+
+        fi
+
 
 fi
 
@@ -54169,6 +54228,49 @@
 
 
 
+# AddressSanitizer
+
+  # Check whether --enable-asan was given.
+if test "${enable_asan+set}" = set; then :
+  enableval=$enable_asan;
+fi
+
+  ASAN_ENABLED="no"
+  if test "x$enable_asan" = "xyes"; then
+    case $TOOLCHAIN_TYPE in
+      gcc | clang)
+        { $as_echo "$as_me:${as_lineno-$LINENO}: checking if asan is enabled" >&5
+$as_echo_n "checking if asan is enabled... " >&6; }
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+        ASAN_CFLAGS="-fsanitize=address -fno-omit-frame-pointer"
+        ASAN_LDFLAGS="-fsanitize=address"
+        JVM_CFLAGS="$JVM_CFLAGS $ASAN_CFLAGS"
+        JVM_LDFLAGS="$JVM_LDFLAGS $ASAN_LDFLAGS"
+        CFLAGS_JDKLIB="$CFLAGS_JDKLIB $ASAN_CFLAGS"
+        CFLAGS_JDKEXE="$CFLAGS_JDKEXE $ASAN_CFLAGS"
+        CXXFLAGS_JDKLIB="$CXXFLAGS_JDKLIB $ASAN_CFLAGS"
+        CXXFLAGS_JDKEXE="$CXXFLAGS_JDKEXE $ASAN_CFLAGS"
+        LDFLAGS_JDKLIB="$LDFLAGS_JDKLIB $ASAN_LDFLAGS"
+        LDFLAGS_JDKEXE="$LDFLAGS_JDKEXE $ASAN_LDFLAGS"
+        ASAN_ENABLED="yes"
+        ;;
+      *)
+        as_fn_error $? "--enable-asan only works with toolchain type gcc or clang" "$LINENO" 5
+        ;;
+    esac
+  elif test "x$enable_asan" = "xno"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking if asan is enabled" >&5
+$as_echo_n "checking if asan is enabled... " >&6; }
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+  elif test "x$enable_asan" != "x"; then
+    as_fn_error $? "--enable-asan can only be assigned \"yes\" or \"no\"" "$LINENO" 5
+  fi
+
+
+
+
 # Need toolchain to setup dtrace
 
   # Test for dtrace dependencies
@@ -54480,6 +54582,16 @@
     NEEDS_LIB_X11=true
   fi
 
+  # Check if fontconfig is needed
+  if test "x$OPENJDK_TARGET_OS" = xwindows || test "x$OPENJDK_TARGET_OS" = xmacosx; then
+    # No fontconfig support on windows or macosx
+    NEEDS_LIB_FONTCONFIG=false
+  else
+    # All other instances need fontconfig, even if building headless only,
+    # libawt still needs fontconfig headers.
+    NEEDS_LIB_FONTCONFIG=true
+  fi
+
   # Check if cups is needed
   if test "x$OPENJDK_TARGET_OS" = xwindows; then
     # Windows have a separate print system
@@ -58297,6 +58409,116 @@
 
 
 
+# Check whether --with-fontconfig was given.
+if test "${with_fontconfig+set}" = set; then :
+  withval=$with_fontconfig;
+fi
+
+
+# Check whether --with-fontconfig-include was given.
+if test "${with_fontconfig_include+set}" = set; then :
+  withval=$with_fontconfig_include;
+fi
+
+
+  if test "x$NEEDS_LIB_FONTCONFIG" = xfalse; then
+    if (test "x${with_fontconfig}" != x && test "x${with_fontconfig}" != xno) || \
+        (test "x${with_fontconfig_include}" != x && test "x${with_fontconfig_include}" != xno); then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: fontconfig not used, so --with-fontconfig[-*] is ignored" >&5
+$as_echo "$as_me: WARNING: fontconfig not used, so --with-fontconfig[-*] is ignored" >&2;}
+    fi
+    FONTCONFIG_CFLAGS=
+  else
+    FONTCONFIG_FOUND=no
+
+    if test "x${with_fontconfig}" = xno || test "x${with_fontconfig_include}" = xno; then
+      as_fn_error $? "It is not possible to disable the use of fontconfig. Remove the --without-fontconfig option." "$LINENO" 5
+    fi
+
+    if test "x${with_fontconfig}" != x; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fontconfig headers" >&5
+$as_echo_n "checking for fontconfig headers... " >&6; }
+      if test -s "${with_fontconfig}/include/fontconfig/fontconfig.h"; then
+        FONTCONFIG_CFLAGS="-I${with_fontconfig}/include"
+        FONTCONFIG_FOUND=yes
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: $FONTCONFIG_FOUND" >&5
+$as_echo "$FONTCONFIG_FOUND" >&6; }
+      else
+        as_fn_error $? "Can't find 'include/fontconfig/fontconfig.h' under ${with_fontconfig} given with the --with-fontconfig option." "$LINENO" 5
+      fi
+    fi
+    if test "x${with_fontconfig_include}" != x; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fontconfig headers" >&5
+$as_echo_n "checking for fontconfig headers... " >&6; }
+      if test -s "${with_fontconfig_include}/fontconfig/fontconfig.h"; then
+        FONTCONFIG_CFLAGS="-I${with_fontconfig_include}"
+        FONTCONFIG_FOUND=yes
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: $FONTCONFIG_FOUND" >&5
+$as_echo "$FONTCONFIG_FOUND" >&6; }
+      else
+        as_fn_error $? "Can't find 'fontconfig/fontconfig.h' under ${with_fontconfig_include} given with the --with-fontconfig-include option." "$LINENO" 5
+      fi
+    fi
+    if test "x$FONTCONFIG_FOUND" = xno; then
+      # Are the fontconfig headers installed in the default /usr/include location?
+      for ac_header in fontconfig/fontconfig.h
+do :
+  ac_fn_cxx_check_header_mongrel "$LINENO" "fontconfig/fontconfig.h" "ac_cv_header_fontconfig_fontconfig_h" "$ac_includes_default"
+if test "x$ac_cv_header_fontconfig_fontconfig_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_FONTCONFIG_FONTCONFIG_H 1
+_ACEOF
+
+          FONTCONFIG_FOUND=yes
+          FONTCONFIG_CFLAGS=
+          DEFAULT_FONTCONFIG=yes
+
+fi
+
+done
+
+    fi
+    if test "x$FONTCONFIG_FOUND" = xno; then
+
+  # Print a helpful message on how to acquire the necessary build dependency.
+  # fontconfig is the help tag: freetype, cups, alsa etc
+  MISSING_DEPENDENCY=fontconfig
+
+  if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then
+    cygwin_help $MISSING_DEPENDENCY
+  elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then
+    msys_help $MISSING_DEPENDENCY
+  else
+    PKGHANDLER_COMMAND=
+
+    case $PKGHANDLER in
+      apt-get)
+        apt_help     $MISSING_DEPENDENCY ;;
+      yum)
+        yum_help     $MISSING_DEPENDENCY ;;
+      brew)
+        brew_help    $MISSING_DEPENDENCY ;;
+      port)
+        port_help    $MISSING_DEPENDENCY ;;
+      pkgutil)
+        pkgutil_help $MISSING_DEPENDENCY ;;
+      pkgadd)
+        pkgadd_help  $MISSING_DEPENDENCY ;;
+    esac
+
+    if test "x$PKGHANDLER_COMMAND" != x; then
+      HELP_MSG="You might be able to fix this by running '$PKGHANDLER_COMMAND'."
+    fi
+  fi
+
+      as_fn_error $? "Could not find fontconfig! $HELP_MSG " "$LINENO" 5
+    fi
+  fi
+
+
+
+
+
 # Check whether --with-freetype was given.
 if test "${with_freetype+set}" = set; then :
   withval=$with_freetype;
@@ -65831,6 +66053,7 @@
 
 
 
+
 # Hotspot setup depends on lib checks.
 
 
--- a/make/autoconf/help.m4	Mon Nov 06 19:45:47 2017 +0100
+++ b/make/autoconf/help.m4	Wed Nov 08 16:03:35 2017 -0500
@@ -113,6 +113,8 @@
       PKGHANDLER_COMMAND="sudo apt-get install libasound2-dev" ;;
     cups)
       PKGHANDLER_COMMAND="sudo apt-get install libcups2-dev" ;;
+    fontconfig)
+      PKGHANDLER_COMMAND="sudo apt-get install libfontconfig1-dev" ;;
     freetype)
       PKGHANDLER_COMMAND="sudo apt-get install libfreetype6-dev" ;;
     ffi)
@@ -136,6 +138,8 @@
       PKGHANDLER_COMMAND="sudo yum install alsa-lib-devel" ;;
     cups)
       PKGHANDLER_COMMAND="sudo yum install cups-devel" ;;
+    fontconfig)
+      PKGHANDLER_COMMAND="sudo yum install fontconfig-devel" ;;
     freetype)
       PKGHANDLER_COMMAND="sudo yum install freetype-devel" ;;
     x11)
--- a/make/autoconf/jdk-options.m4	Mon Nov 06 19:45:47 2017 +0100
+++ b/make/autoconf/jdk-options.m4	Wed Nov 08 16:03:35 2017 -0500
@@ -399,6 +399,46 @@
   AC_SUBST(GCOV_ENABLED)
 ])
 
+###############################################################################
+#
+# AddressSanitizer
+#
+AC_DEFUN_ONCE([JDKOPT_SETUP_ADDRESS_SANITIZER],
+[
+  AC_ARG_ENABLE(asan, [AS_HELP_STRING([--enable-asan],
+      [enable AddressSanitizer if possible @<:@disabled@:>@])])
+  ASAN_ENABLED="no"
+  if test "x$enable_asan" = "xyes"; then
+    case $TOOLCHAIN_TYPE in
+      gcc | clang)
+        AC_MSG_CHECKING([if asan is enabled])
+        AC_MSG_RESULT([yes])
+        ASAN_CFLAGS="-fsanitize=address -fno-omit-frame-pointer"
+        ASAN_LDFLAGS="-fsanitize=address"
+        JVM_CFLAGS="$JVM_CFLAGS $ASAN_CFLAGS"
+        JVM_LDFLAGS="$JVM_LDFLAGS $ASAN_LDFLAGS"
+        CFLAGS_JDKLIB="$CFLAGS_JDKLIB $ASAN_CFLAGS"
+        CFLAGS_JDKEXE="$CFLAGS_JDKEXE $ASAN_CFLAGS"
+        CXXFLAGS_JDKLIB="$CXXFLAGS_JDKLIB $ASAN_CFLAGS"
+        CXXFLAGS_JDKEXE="$CXXFLAGS_JDKEXE $ASAN_CFLAGS"
+        LDFLAGS_JDKLIB="$LDFLAGS_JDKLIB $ASAN_LDFLAGS"
+        LDFLAGS_JDKEXE="$LDFLAGS_JDKEXE $ASAN_LDFLAGS"
+        ASAN_ENABLED="yes"
+        ;;
+      *)
+        AC_MSG_ERROR([--enable-asan only works with toolchain type gcc or clang])
+        ;;
+    esac
+  elif test "x$enable_asan" = "xno"; then
+    AC_MSG_CHECKING([if asan is enabled])
+    AC_MSG_RESULT([no])
+  elif test "x$enable_asan" != "x"; then
+    AC_MSG_ERROR([--enable-asan can only be assigned "yes" or "no"])
+  fi
+
+  AC_SUBST(ASAN_ENABLED)
+])
+
 ################################################################################
 #
 # Static build support.  When enabled will generate static
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/autoconf/lib-fontconfig.m4	Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,85 @@
+#
+# Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+# 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.
+#
+
+################################################################################
+# Setup fontconfig
+################################################################################
+AC_DEFUN_ONCE([LIB_SETUP_FONTCONFIG],
+[
+  AC_ARG_WITH(fontconfig, [AS_HELP_STRING([--with-fontconfig],
+      [specify prefix directory for the fontconfig package
+      (expecting the headers under PATH/include)])])
+  AC_ARG_WITH(fontconfig-include, [AS_HELP_STRING([--with-fontconfig-include],
+      [specify directory for the fontconfig include files])])
+
+  if test "x$NEEDS_LIB_FONTCONFIG" = xfalse; then
+    if (test "x${with_fontconfig}" != x && test "x${with_fontconfig}" != xno) || \
+        (test "x${with_fontconfig_include}" != x && test "x${with_fontconfig_include}" != xno); then
+      AC_MSG_WARN([[fontconfig not used, so --with-fontconfig[-*] is ignored]])
+    fi
+    FONTCONFIG_CFLAGS=
+  else
+    FONTCONFIG_FOUND=no
+
+    if test "x${with_fontconfig}" = xno || test "x${with_fontconfig_include}" = xno; then
+      AC_MSG_ERROR([It is not possible to disable the use of fontconfig. Remove the --without-fontconfig option.])
+    fi
+
+    if test "x${with_fontconfig}" != x; then
+      AC_MSG_CHECKING([for fontconfig headers])
+      if test -s "${with_fontconfig}/include/fontconfig/fontconfig.h"; then
+        FONTCONFIG_CFLAGS="-I${with_fontconfig}/include"
+        FONTCONFIG_FOUND=yes
+        AC_MSG_RESULT([$FONTCONFIG_FOUND])
+      else
+        AC_MSG_ERROR([Can't find 'include/fontconfig/fontconfig.h' under ${with_fontconfig} given with the --with-fontconfig option.])
+      fi
+    fi
+    if test "x${with_fontconfig_include}" != x; then
+      AC_MSG_CHECKING([for fontconfig headers])
+      if test -s "${with_fontconfig_include}/fontconfig/fontconfig.h"; then
+        FONTCONFIG_CFLAGS="-I${with_fontconfig_include}"
+        FONTCONFIG_FOUND=yes
+        AC_MSG_RESULT([$FONTCONFIG_FOUND])
+      else
+        AC_MSG_ERROR([Can't find 'fontconfig/fontconfig.h' under ${with_fontconfig_include} given with the --with-fontconfig-include option.])
+      fi
+    fi
+    if test "x$FONTCONFIG_FOUND" = xno; then
+      # Are the fontconfig headers installed in the default /usr/include location?
+      AC_CHECK_HEADERS([fontconfig/fontconfig.h], [
+          FONTCONFIG_FOUND=yes
+          FONTCONFIG_CFLAGS=
+          DEFAULT_FONTCONFIG=yes
+      ])
+    fi
+    if test "x$FONTCONFIG_FOUND" = xno; then
+      HELP_MSG_MISSING_DEPENDENCY([fontconfig])
+      AC_MSG_ERROR([Could not find fontconfig! $HELP_MSG ])
+    fi
+  fi
+
+  AC_SUBST(FONTCONFIG_CFLAGS)
+])
--- a/make/autoconf/libraries.m4	Mon Nov 06 19:45:47 2017 +0100
+++ b/make/autoconf/libraries.m4	Wed Nov 08 16:03:35 2017 -0500
@@ -31,6 +31,7 @@
 m4_include([lib-freetype.m4])
 m4_include([lib-std.m4])
 m4_include([lib-x11.m4])
+m4_include([lib-fontconfig.m4])
 
 ################################################################################
 # Determine which libraries are needed for this configuration
@@ -47,6 +48,16 @@
     NEEDS_LIB_X11=true
   fi
 
+  # Check if fontconfig is needed
+  if test "x$OPENJDK_TARGET_OS" = xwindows || test "x$OPENJDK_TARGET_OS" = xmacosx; then
+    # No fontconfig support on windows or macosx
+    NEEDS_LIB_FONTCONFIG=false
+  else
+    # All other instances need fontconfig, even if building headless only,
+    # libawt still needs fontconfig headers.
+    NEEDS_LIB_FONTCONFIG=true
+  fi
+
   # Check if cups is needed
   if test "x$OPENJDK_TARGET_OS" = xwindows; then
     # Windows have a separate print system
@@ -83,6 +94,7 @@
   LIB_SETUP_STD_LIBS
   LIB_SETUP_X11
   LIB_SETUP_CUPS
+  LIB_SETUP_FONTCONFIG
   LIB_SETUP_FREETYPE
   LIB_SETUP_ALSA
   LIB_SETUP_LIBFFI
--- a/make/autoconf/spec.gmk.in	Mon Nov 06 19:45:47 2017 +0100
+++ b/make/autoconf/spec.gmk.in	Wed Nov 08 16:03:35 2017 -0500
@@ -311,6 +311,16 @@
 
 GCOV_ENABLED=@GCOV_ENABLED@
 
+# AddressSanitizer
+export ASAN_ENABLED:=@ASAN_ENABLED@
+export DEVKIT_LIB_DIR:=@DEVKIT_LIB_DIR@
+ifeq ($(ASAN_ENABLED), yes)
+  export ASAN_OPTIONS="handle_segv=0 detect_leaks=0"
+  ifneq ($(DEVKIT_LIB_DIR),)
+    export LD_LIBRARY_PATH:=$(LD_LIBRARY_PATH):$(DEVKIT_LIB_DIR)
+  endif
+endif
+
 # Necessary additional compiler flags to compile X11
 X_CFLAGS:=@X_CFLAGS@
 X_LIBS:=@X_LIBS@
--- a/make/conf/jib-profiles.js	Mon Nov 06 19:45:47 2017 +0100
+++ b/make/conf/jib-profiles.js	Wed Nov 08 16:03:35 2017 -0500
@@ -1060,7 +1060,7 @@
         jtreg: {
             server: "javare",
             revision: "4.2",
-            build_number: "b09",
+            build_number: "b10",
             checksum_file: "MD5_VALUES",
             file: "jtreg_bin-4.2.zip",
             environment_name: "JT_HOME",
--- a/make/lib/Awt2dLibraries.gmk	Mon Nov 06 19:45:47 2017 +0100
+++ b/make/lib/Awt2dLibraries.gmk	Wed Nov 08 16:03:35 2017 -0500
@@ -317,6 +317,7 @@
 
     LIBAWT_XAWT_CFLAGS += -DXAWT -DXAWT_HACK \
         -DPACKAGE_PATH=\"$(PACKAGE_PATH)\" \
+        $(FONTCONFIG_CFLAGS) \
         $(CUPS_CFLAGS)
 
     ifeq ($(OPENJDK_TARGET_OS), solaris)
@@ -555,6 +556,7 @@
           -DHEADLESS=true \
           -DPACKAGE_PATH=\"$(PACKAGE_PATH)\" \
           $(CUPS_CFLAGS) \
+          $(FONTCONFIG_CFLAGS) \
           $(X_CFLAGS) \
           $(LIBAWT_HEADLESS_CFLAGS), \
       DISABLED_WARNINGS_xlc := 1506-356, \
--- a/src/hotspot/cpu/aarch64/frame_aarch64.cpp	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/cpu/aarch64/frame_aarch64.cpp	Wed Nov 08 16:03:35 2017 -0500
@@ -431,11 +431,11 @@
   // This is the sp before any possible extension (adapter/locals).
   intptr_t* unextended_sp = interpreter_frame_sender_sp();
 
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
   if (map->update_map()) {
     update_map_with_saved_link(map, (intptr_t**) addr_at(link_offset));
   }
-#endif // COMPILER2 || INCLUDE_JVMCI
+#endif // COMPILER2_OR_JVMCI
 
   return frame(sender_sp, unextended_sp, link(), sender_pc());
 }
--- a/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp	Wed Nov 08 16:03:35 2017 -0500
@@ -41,7 +41,7 @@
 #ifdef COMPILER1
 #include "c1/c1_Runtime1.hpp"
 #endif
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
 #include "adfiles/ad_aarch64.hpp"
 #include "opto/runtime.hpp"
 #endif
@@ -114,7 +114,7 @@
 };
 
 OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_frame_words, int* total_frame_words, bool save_vectors) {
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
   if (save_vectors) {
     // Save upper half of vector registers
     int vect_words = 32 * 8 / wordSize;
@@ -2688,7 +2688,7 @@
   return 0;
 }
 
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
 //------------------------------generate_uncommon_trap_blob--------------------
 void SharedRuntime::generate_uncommon_trap_blob() {
   // Allocate space for the code
@@ -2894,7 +2894,7 @@
   }
 #endif
 }
-#endif // COMPILER2
+#endif // COMPILER2_OR_JVMCI
 
 
 //------------------------------generate_handler_blob------
@@ -3070,8 +3070,7 @@
   return RuntimeStub::new_runtime_stub(name, &buffer, frame_complete, frame_size_in_words, oop_maps, true);
 }
 
-
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
 // This is here instead of runtime_x86_64.cpp because it uses SimpleRuntimeFrame
 //
 //------------------------------generate_exception_blob---------------------------
@@ -3200,4 +3199,4 @@
   // Set exception blob
   _exception_blob =  ExceptionBlob::create(&buffer, oop_maps, SimpleRuntimeFrame::framesize >> 1);
 }
-#endif // COMPILER2
+#endif // COMPILER2_OR_JVMCI
--- a/src/hotspot/cpu/arm/compiledIC_arm.cpp	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/cpu/arm/compiledIC_arm.cpp	Wed Nov 08 16:03:35 2017 -0500
@@ -33,7 +33,7 @@
 #include "runtime/safepoint.hpp"
 
 // ----------------------------------------------------------------------------
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
 #define __ _masm.
 // emit call stub, compiled java to interpreter
 address CompiledStaticCall::emit_to_interp_stub(CodeBuffer &cbuf, address mark) {
@@ -89,7 +89,7 @@
 int CompiledStaticCall::reloc_to_interp_stub() {
   return 10;  // 4 in emit_to_interp_stub + 1 in Java_Static_Call
 }
-#endif // COMPILER2 || JVMCI
+#endif // COMPILER2_OR_JVMCI
 
 // size of C2 call stub, compiled java to interpretor
 int CompiledStaticCall::to_interp_stub_size() {
--- a/src/hotspot/cpu/x86/frame_x86.cpp	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/cpu/x86/frame_x86.cpp	Wed Nov 08 16:03:35 2017 -0500
@@ -436,11 +436,11 @@
   // This is the sp before any possible extension (adapter/locals).
   intptr_t* unextended_sp = interpreter_frame_sender_sp();
 
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
   if (map->update_map()) {
     update_map_with_saved_link(map, (intptr_t**) addr_at(link_offset));
   }
-#endif // COMPILER2 || INCLUDE_JVMCI
+#endif // COMPILER2_OR_JVMCI
 
   return frame(sender_sp, unextended_sp, link(), sender_pc());
 }
--- a/src/hotspot/cpu/x86/globals_x86.hpp	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/cpu/x86/globals_x86.hpp	Wed Nov 08 16:03:35 2017 -0500
@@ -46,11 +46,11 @@
 // the the vep is aligned at CodeEntryAlignment whereas c2 only aligns
 // the uep and the vep doesn't get real alignment but just slops on by
 // only assured that the entry instruction meets the 5 byte size requirement.
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
 define_pd_global(intx, CodeEntryAlignment,       32);
 #else
 define_pd_global(intx, CodeEntryAlignment,       16);
-#endif // COMPILER2
+#endif // COMPILER2_OR_JVMCI
 define_pd_global(intx, OptoLoopAlignment,        16);
 define_pd_global(intx, InlineFrequencyCount,     100);
 define_pd_global(intx, InlineSmallCode,          1000);
--- a/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp	Wed Nov 08 16:03:35 2017 -0500
@@ -151,7 +151,7 @@
   if (UseAVX < 3) {
     num_xmm_regs = num_xmm_regs/2;
   }
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
   if (save_vectors) {
     assert(UseAVX > 0, "Vectors larger than 16 byte long are supported only with AVX");
     assert(MaxVectorSize <= 64, "Only up to 64 byte long vectors are supported");
@@ -260,7 +260,7 @@
     }
   }
 
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
   if (save_vectors) {
     off = ymm0_off;
     int delta = ymm1_off - off;
@@ -270,7 +270,7 @@
       off += delta;
     }
   }
-#endif // COMPILER2 || INCLUDE_JVMCI
+#endif // COMPILER2_OR_JVMCI
 
   // %%% These should all be a waste but we'll keep things as they were for now
   if (true) {
@@ -323,7 +323,7 @@
     __ addptr(rsp, frame::arg_reg_save_area_bytes);
   }
 
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
   if (restore_vectors) {
     assert(UseAVX > 0, "Vectors larger than 16 byte long are supported only with AVX");
     assert(MaxVectorSize <= 64, "Only up to 64 byte long vectors are supported");
--- a/src/hotspot/cpu/x86/stubGenerator_x86_32.cpp	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/cpu/x86/stubGenerator_x86_32.cpp	Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -3433,6 +3433,8 @@
   }
 
  address generate_libmExp() {
+    StubCodeMark mark(this, "StubRoutines", "libmExp");
+
     address start = __ pc();
 
     const XMMRegister x0  = xmm0;
@@ -3458,6 +3460,8 @@
   }
 
  address generate_libmLog() {
+   StubCodeMark mark(this, "StubRoutines", "libmLog");
+
    address start = __ pc();
 
    const XMMRegister x0 = xmm0;
@@ -3483,6 +3487,8 @@
  }
 
  address generate_libmLog10() {
+   StubCodeMark mark(this, "StubRoutines", "libmLog10");
+
    address start = __ pc();
 
    const XMMRegister x0 = xmm0;
@@ -3508,6 +3514,8 @@
  }
 
  address generate_libmPow() {
+   StubCodeMark mark(this, "StubRoutines", "libmPow");
+
    address start = __ pc();
 
    const XMMRegister x0 = xmm0;
@@ -3533,6 +3541,8 @@
  }
 
  address generate_libm_reduce_pi04l() {
+   StubCodeMark mark(this, "StubRoutines", "libm_reduce_pi04l");
+
    address start = __ pc();
 
    BLOCK_COMMENT("Entry:");
@@ -3543,6 +3553,8 @@
  }
 
  address generate_libm_sin_cos_huge() {
+   StubCodeMark mark(this, "StubRoutines", "libm_sin_cos_huge");
+
    address start = __ pc();
 
    const XMMRegister x0 = xmm0;
@@ -3556,6 +3568,8 @@
  }
 
  address generate_libmSin() {
+   StubCodeMark mark(this, "StubRoutines", "libmSin");
+
    address start = __ pc();
 
    const XMMRegister x0 = xmm0;
@@ -3579,6 +3593,8 @@
  }
 
  address generate_libmCos() {
+   StubCodeMark mark(this, "StubRoutines", "libmCos");
+
    address start = __ pc();
 
    const XMMRegister x0 = xmm0;
@@ -3604,6 +3620,8 @@
  }
 
  address generate_libm_tan_cot_huge() {
+   StubCodeMark mark(this, "StubRoutines", "libm_tan_cot_huge");
+
    address start = __ pc();
 
    const XMMRegister x0 = xmm0;
@@ -3617,6 +3635,8 @@
  }
 
  address generate_libmTan() {
+   StubCodeMark mark(this, "StubRoutines", "libmTan");
+
    address start = __ pc();
 
    const XMMRegister x0 = xmm0;
--- a/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp	Wed Nov 08 16:03:35 2017 -0500
@@ -4619,6 +4619,8 @@
   }
 
   address generate_libmExp() {
+    StubCodeMark mark(this, "StubRoutines", "libmExp");
+
     address start = __ pc();
 
     const XMMRegister x0  = xmm0;
@@ -4646,6 +4648,8 @@
   }
 
   address generate_libmLog() {
+    StubCodeMark mark(this, "StubRoutines", "libmLog");
+
     address start = __ pc();
 
     const XMMRegister x0 = xmm0;
@@ -4674,6 +4678,8 @@
   }
 
   address generate_libmLog10() {
+    StubCodeMark mark(this, "StubRoutines", "libmLog10");
+
     address start = __ pc();
 
     const XMMRegister x0 = xmm0;
@@ -4701,6 +4707,8 @@
   }
 
   address generate_libmPow() {
+    StubCodeMark mark(this, "StubRoutines", "libmPow");
+
     address start = __ pc();
 
     const XMMRegister x0 = xmm0;
@@ -4731,6 +4739,8 @@
   }
 
   address generate_libmSin() {
+    StubCodeMark mark(this, "StubRoutines", "libmSin");
+
     address start = __ pc();
 
     const XMMRegister x0 = xmm0;
@@ -4770,6 +4780,8 @@
   }
 
   address generate_libmCos() {
+    StubCodeMark mark(this, "StubRoutines", "libmCos");
+
     address start = __ pc();
 
     const XMMRegister x0 = xmm0;
@@ -4809,6 +4821,8 @@
   }
 
   address generate_libmTan() {
+    StubCodeMark mark(this, "StubRoutines", "libmTan");
+
     address start = __ pc();
 
     const XMMRegister x0 = xmm0;
--- a/src/hotspot/cpu/x86/vm_version_x86.cpp	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/cpu/x86/vm_version_x86.cpp	Wed Nov 08 16:03:35 2017 -0500
@@ -944,7 +944,7 @@
     }
   }
 #endif
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
   if (MaxVectorSize > 0) {
     if (!is_power_of_2(MaxVectorSize)) {
       warning("MaxVectorSize must be a power of 2");
@@ -996,7 +996,7 @@
     }
 #endif // COMPILER2 && ASSERT
   }
-#endif // COMPILER2 || INCLUDE_JVMCI
+#endif // COMPILER2_OR_JVMCI
 
 #ifdef COMPILER2
 #ifdef _LP64
--- a/src/hotspot/os_cpu/bsd_x86/thread_bsd_x86.cpp	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/os_cpu/bsd_x86/thread_bsd_x86.cpp	Wed Nov 08 16:03:35 2017 -0500
@@ -73,7 +73,7 @@
 
     frame ret_frame(ret_sp, ret_fp, addr.pc());
     if (!ret_frame.safe_for_sender(jt)) {
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
       // C2 and JVMCI use ebp as a general register see if NULL fp helps
       frame ret_frame2(ret_sp, NULL, addr.pc());
       if (!ret_frame2.safe_for_sender(jt)) {
@@ -84,7 +84,7 @@
 #else
       // nothing else to try if the frame isn't good
       return false;
-#endif /* COMPILER2 || INCLUDE_JVMCI */
+#endif // COMPILER2_OR_JVMCI
     }
     *fr_addr = ret_frame;
     return true;
--- a/src/hotspot/os_cpu/linux_x86/thread_linux_x86.cpp	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/os_cpu/linux_x86/thread_linux_x86.cpp	Wed Nov 08 16:03:35 2017 -0500
@@ -74,7 +74,7 @@
 
     frame ret_frame(ret_sp, ret_fp, addr.pc());
     if (!ret_frame.safe_for_sender(jt)) {
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
       // C2 and JVMCI use ebp as a general register see if NULL fp helps
       frame ret_frame2(ret_sp, NULL, addr.pc());
       if (!ret_frame2.safe_for_sender(jt)) {
@@ -85,7 +85,7 @@
 #else
       // nothing else to try if the frame isn't good
       return false;
-#endif /* COMPILER2 || INCLUDE_JVMCI */
+#endif // COMPILER2_OR_JVMCI
     }
     *fr_addr = ret_frame;
     return true;
--- a/src/hotspot/os_cpu/windows_x86/thread_windows_x86.cpp	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/os_cpu/windows_x86/thread_windows_x86.cpp	Wed Nov 08 16:03:35 2017 -0500
@@ -81,7 +81,7 @@
 
     frame ret_frame(ret_sp, ret_fp, addr.pc());
     if (!ret_frame.safe_for_sender(jt)) {
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
       // C2 and JVMCI use ebp as a general register see if NULL fp helps
       frame ret_frame2(ret_sp, NULL, addr.pc());
       if (!ret_frame2.safe_for_sender(jt)) {
@@ -92,7 +92,7 @@
 #else
       // nothing else to try if the frame isn't good
       return false;
-#endif /* COMPILER2 || INCLUDE_JVMCI */
+#endif // COMPILER2_OR_JVMCI
     }
     *fr_addr = ret_frame;
     return true;
--- a/src/hotspot/share/aot/aotCodeHeap.cpp	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/aot/aotCodeHeap.cpp	Wed Nov 08 16:03:35 2017 -0500
@@ -490,6 +490,8 @@
 
     SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_stub_routines_checkcast_arraycopy", address, StubRoutines::_checkcast_arraycopy);
 
+    SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_stub_routines_generic_arraycopy", address, StubRoutines::_generic_arraycopy);
+
     SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_stub_routines_aescrypt_encryptBlock", address, StubRoutines::_aescrypt_encryptBlock);
     SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_stub_routines_aescrypt_decryptBlock", address, StubRoutines::_aescrypt_decryptBlock);
     SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_stub_routines_cipherBlockChaining_encryptAESCrypt", address, StubRoutines::_cipherBlockChaining_encryptAESCrypt);
--- a/src/hotspot/share/code/scopeDesc.cpp	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/code/scopeDesc.cpp	Wed Nov 08 16:03:35 2017 -0500
@@ -228,7 +228,7 @@
     }
   }
 
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
   if (NOT_JVMCI(DoEscapeAnalysis &&) is_top() && _objects != NULL) {
     st->print_cr("   Objects");
     for (int i = 0; i < _objects->length(); i++) {
@@ -239,7 +239,7 @@
       st->cr();
     }
   }
-#endif // COMPILER2 || INCLUDE_JVMCI
+#endif // COMPILER2_OR_JVMCI
 }
 
 #endif
--- a/src/hotspot/share/compiler/oopMap.cpp	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/compiler/oopMap.cpp	Wed Nov 08 16:03:35 2017 -0500
@@ -268,9 +268,9 @@
 #if !defined(TIERED) && !defined(INCLUDE_JVMCI)
   COMPILER1_PRESENT(ShouldNotReachHere();)
 #endif // !defined(TIERED) && !defined(INCLUDE_JVMCI)
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
   DerivedPointerTable::add(derived, base);
-#endif // COMPILER2 || INCLUDE_JVMCI
+#endif // COMPILER2_OR_JVMCI
 }
 
 
@@ -461,12 +461,12 @@
 #if !defined(TIERED) && !defined(INCLUDE_JVMCI)
   COMPILER1_PRESENT(return false);
 #endif // !TIERED
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
   OopMapStream oms(this,OopMapValue::derived_oop_value);
   return oms.is_done();
 #else
   return false;
-#endif // COMPILER2 || INCLUDE_JVMCI
+#endif // COMPILER2_OR_JVMCI
 }
 
 #endif //PRODUCT
@@ -726,7 +726,7 @@
 
 //------------------------------DerivedPointerTable---------------------------
 
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
 
 class DerivedPointerEntry : public CHeapObj<mtCompiler> {
  private:
@@ -819,4 +819,4 @@
   _active = false;
 }
 
-#endif // COMPILER2 || INCLUDE_JVMCI
+#endif // COMPILER2_OR_JVMCI
--- a/src/hotspot/share/compiler/oopMap.hpp	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/compiler/oopMap.hpp	Wed Nov 08 16:03:35 2017 -0500
@@ -427,7 +427,7 @@
 // oops, it is filled in with references to all locations that contains a
 // derived oop (assumed to be very few).  When the GC is complete, the derived
 // pointers are updated based on their base pointers new value and an offset.
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
 class DerivedPointerTable : public AllStatic {
   friend class VMStructs;
  private:
@@ -463,6 +463,6 @@
     }
   }
 };
-#endif // COMPILER2 || INCLUDE_JVMCI
+#endif // COMPILER2_OR_JVMCI
 
 #endif // SHARE_VM_COMPILER_OOPMAP_HPP
--- a/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp	Wed Nov 08 16:03:35 2017 -0500
@@ -2296,7 +2296,7 @@
   // way with the marking information used by GC.
   NoRefDiscovery no_discovery(ref_processor());
 
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
   DerivedPointerTableDeactivate dpt_deact;
 #endif
 
@@ -2869,7 +2869,7 @@
   print_eden_and_survivor_chunk_arrays();
 
   {
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
     DerivedPointerTableDeactivate dpt_deact;
 #endif
     if (CMSParallelInitialMarkEnabled) {
@@ -4171,7 +4171,7 @@
   print_eden_and_survivor_chunk_arrays();
 
   {
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
     DerivedPointerTableDeactivate dpt_deact;
 #endif
 
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp	Wed Nov 08 16:03:35 2017 -0500
@@ -2597,7 +2597,7 @@
   // FIXME: what is this about?
   // I'm ignoring the "fill_newgen()" call if "alloc_event_enabled"
   // is set.
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
   assert(DerivedPointerTable::is_empty(), "derived pointer present");
 #endif
   // always_do_update_barrier = true;
@@ -3010,7 +3010,7 @@
 
       _verifier->check_bitmaps("GC Start");
 
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
       DerivedPointerTable::clear();
 #endif
 
@@ -4439,7 +4439,7 @@
   purge_code_root_memory();
 
   redirty_logged_cards();
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
   double start = os::elapsedTime();
   DerivedPointerTable::update_pointers();
   g1_policy()->phase_times()->record_derived_pointer_table_update_time((os::elapsedTime() - start) * 1000.0);
--- a/src/hotspot/share/gc/g1/g1GCPhaseTimes.cpp	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/gc/g1/g1GCPhaseTimes.cpp	Wed Nov 08 16:03:35 2017 -0500
@@ -414,7 +414,7 @@
 
   debug_time("Redirty Cards", _recorded_redirty_logged_cards_time_ms);
   trace_phase(_gc_par_phases[RedirtyCards]);
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
   debug_time("DerivedPointerTable Update", _cur_derived_pointer_table_update_time_ms);
 #endif
 
--- a/src/hotspot/share/gc/g1/g1MarkSweep.cpp	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/gc/g1/g1MarkSweep.cpp	Wed Nov 08 16:03:35 2017 -0500
@@ -62,7 +62,7 @@
   assert(SafepointSynchronize::is_at_safepoint(), "must be at a safepoint");
   HandleMark hm;  // Discard invalid handles created during gc
 
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
   DerivedPointerTable::clear();
 #endif
 #ifdef ASSERT
@@ -96,7 +96,7 @@
   // Prepare compaction.
   mark_sweep_phase2();
 
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
   // Don't add any more derived pointers during phase3
   DerivedPointerTable::set_active(false);
 #endif
@@ -111,7 +111,7 @@
   BiasedLocking::restore_marks();
   GenMarkSweep::deallocate_stacks();
 
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
   // Now update the derived pointers.
   DerivedPointerTable::update_pointers();
 #endif
@@ -204,7 +204,7 @@
 
   if (VerifyDuringGC) {
     HandleMark hm;  // handle scope
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
     DerivedPointerTableDeactivate dpt_deact;
 #endif
     g1h->prepare_for_verify();
--- a/src/hotspot/share/gc/parallel/psMarkSweep.cpp	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/gc/parallel/psMarkSweep.cpp	Wed Nov 08 16:03:35 2017 -0500
@@ -192,7 +192,7 @@
 
     allocate_stacks();
 
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
     DerivedPointerTable::clear();
 #endif
 
@@ -203,7 +203,7 @@
 
     mark_sweep_phase2();
 
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
     // Don't add any more derived pointers during phase3
     assert(DerivedPointerTable::is_active(), "Sanity");
     DerivedPointerTable::set_active(false);
@@ -252,7 +252,7 @@
     CodeCache::gc_epilogue();
     JvmtiExport::gc_epilogue();
 
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
     DerivedPointerTable::update_pointers();
 #endif
 
--- a/src/hotspot/share/gc/parallel/psParallelCompact.cpp	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/gc/parallel/psParallelCompact.cpp	Wed Nov 08 16:03:35 2017 -0500
@@ -1032,7 +1032,7 @@
   CodeCache::gc_epilogue();
   JvmtiExport::gc_epilogue();
 
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
   DerivedPointerTable::update_pointers();
 #endif
 
@@ -1783,7 +1783,7 @@
 
     CodeCache::gc_prologue();
 
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
     DerivedPointerTable::clear();
 #endif
 
@@ -1799,7 +1799,7 @@
       && GCCause::is_user_requested_gc(gc_cause);
     summary_phase(vmthread_cm, maximum_heap_compaction || max_on_system_gc);
 
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
     assert(DerivedPointerTable::is_active(), "Sanity");
     DerivedPointerTable::set_active(false);
 #endif
--- a/src/hotspot/share/gc/parallel/psScavenge.cpp	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/gc/parallel/psScavenge.cpp	Wed Nov 08 16:03:35 2017 -0500
@@ -331,7 +331,7 @@
 
     save_to_space_top_before_gc();
 
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
     DerivedPointerTable::clear();
 #endif
 
@@ -601,7 +601,7 @@
       assert(young_gen->to_space()->is_empty(), "to space should be empty now");
     }
 
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
     DerivedPointerTable::update_pointers();
 #endif
 
--- a/src/hotspot/share/gc/serial/genMarkSweep.cpp	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/gc/serial/genMarkSweep.cpp	Wed Nov 08 16:03:35 2017 -0500
@@ -92,7 +92,7 @@
   mark_sweep_phase2();
 
   // Don't add any more derived pointers during phase3
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
   assert(DerivedPointerTable::is_active(), "Sanity");
   DerivedPointerTable::set_active(false);
 #endif
--- a/src/hotspot/share/gc/shared/collectedHeap.cpp	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/gc/shared/collectedHeap.cpp	Wed Nov 08 16:03:35 2017 -0500
@@ -241,7 +241,7 @@
 void CollectedHeap::pre_initialize() {
   // Used for ReduceInitialCardMarks (when COMPILER2 is used);
   // otherwise remains unused.
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
   _defer_initial_card_mark = is_server_compilation_mode_vm() &&  ReduceInitialCardMarks && can_elide_tlab_store_barriers()
                              && (DeferInitialCardMark || card_mark_must_follow_store());
 #else
@@ -545,7 +545,7 @@
          " to threads list is doomed to failure!");
   for (JavaThread *thread = Threads::first(); thread; thread = thread->next()) {
      if (use_tlab) thread->tlab().make_parsable(retire_tlabs);
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
      // The deferred store barriers must all have been flushed to the
      // card-table (or other remembered set structure) before GC starts
      // processing the card-table (or other remembered set).
--- a/src/hotspot/share/gc/shared/genCollectedHeap.cpp	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/gc/shared/genCollectedHeap.cpp	Wed Nov 08 16:03:35 2017 -0500
@@ -1067,11 +1067,11 @@
 };
 
 void GenCollectedHeap::gc_epilogue(bool full) {
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
   assert(DerivedPointerTable::is_empty(), "derived pointer present");
   size_t actual_gap = pointer_delta((HeapWord*) (max_uintx-3), *(end_addr()));
   guarantee(is_client_compilation_mode_vm() || actual_gap > (size_t)FastAllocateSizeLimit, "inline allocation wraps");
-#endif /* COMPILER2 || INCLUDE_JVMCI */
+#endif // COMPILER2_OR_JVMCI
 
   resize_all_tlabs();
 
--- a/src/hotspot/share/interpreter/interpreterRuntime.cpp	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/interpreter/interpreterRuntime.cpp	Wed Nov 08 16:03:35 2017 -0500
@@ -921,6 +921,14 @@
     int bci = method->bci_from(last_frame.bcp());
     nm = method->lookup_osr_nmethod_for(bci, CompLevel_none, false);
   }
+  if (nm != NULL && thread->is_interp_only_mode()) {
+    // Normally we never get an nm if is_interp_only_mode() is true, because
+    // policy()->event has a check for this and won't compile the method when
+    // true. However, it's possible for is_interp_only_mode() to become true
+    // during the compilation. We don't want to return the nm in that case
+    // because we want to continue to execute interpreted.
+    nm = NULL;
+  }
 #ifndef PRODUCT
   if (TraceOnStackReplacement) {
     if (nm != NULL) {
--- a/src/hotspot/share/jvmci/jvmciCompiler.hpp	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/jvmci/jvmciCompiler.hpp	Wed Nov 08 16:03:35 2017 -0500
@@ -55,10 +55,13 @@
 public:
   JVMCICompiler();
 
-  static JVMCICompiler* instance(TRAPS) {
+  static JVMCICompiler* instance(bool require_non_null, TRAPS) {
     if (!EnableJVMCI) {
       THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), "JVMCI is not enabled")
     }
+    if (_instance == NULL && require_non_null) {
+      THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), "The JVMCI compiler instance has not been created");
+    }
     return _instance;
   }
 
--- a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp	Wed Nov 08 16:03:35 2017 -0500
@@ -1018,7 +1018,7 @@
   Handle installed_code_handle(THREAD, JNIHandles::resolve(installed_code));
   Handle speculation_log_handle(THREAD, JNIHandles::resolve(speculation_log));
 
-  JVMCICompiler* compiler = JVMCICompiler::instance(CHECK_JNI_ERR);
+  JVMCICompiler* compiler = JVMCICompiler::instance(true, CHECK_JNI_ERR);
 
   TraceTime install_time("installCode", JVMCICompiler::codeInstallTimer());
   bool is_immutable_PIC = HotSpotCompiledCode::isImmutablePIC(compiled_code_handle) > 0;
@@ -1136,7 +1136,7 @@
 C2V_END
 
 C2V_VMENTRY(void, resetCompilationStatistics, (JNIEnv *jniEnv, jobject))
-  JVMCICompiler* compiler = JVMCICompiler::instance(CHECK);
+  JVMCICompiler* compiler = JVMCICompiler::instance(true, CHECK);
   CompilerStatistics* stats = compiler->stats();
   stats->_standard.reset();
   stats->_osr.reset();
--- a/src/hotspot/share/jvmci/jvmciRuntime.cpp	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/jvmci/jvmciRuntime.cpp	Wed Nov 08 16:03:35 2017 -0500
@@ -821,7 +821,7 @@
 }
 
 CompLevel JVMCIRuntime::adjust_comp_level_inner(const methodHandle& method, bool is_osr, CompLevel level, JavaThread* thread) {
-  JVMCICompiler* compiler = JVMCICompiler::instance(thread);
+  JVMCICompiler* compiler = JVMCICompiler::instance(false, thread);
   if (compiler != NULL && compiler->is_bootstrapping()) {
     return level;
   }
--- a/src/hotspot/share/memory/metachunk.cpp	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/memory/metachunk.cpp	Wed Nov 08 16:03:35 2017 -0500
@@ -55,8 +55,8 @@
     _container(container)
 {
   _top = initial_top();
+  set_is_tagged_free(false);
 #ifdef ASSERT
-  set_is_tagged_free(false);
   mangle(uninitMetaWordVal);
 #endif
 }
--- a/src/hotspot/share/memory/metachunk.hpp	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/memory/metachunk.hpp	Wed Nov 08 16:03:35 2017 -0500
@@ -102,7 +102,7 @@
   // Current allocation top.
   MetaWord* _top;
 
-  DEBUG_ONLY(bool _is_tagged_free;)
+  bool _is_tagged_free;
 
   MetaWord* initial_top() const { return (MetaWord*)this + overhead(); }
   MetaWord* top() const         { return _top; }
@@ -138,10 +138,8 @@
   size_t used_word_size() const;
   size_t free_word_size() const;
 
-#ifdef ASSERT
   bool is_tagged_free() { return _is_tagged_free; }
   void set_is_tagged_free(bool v) { _is_tagged_free = v; }
-#endif
 
   bool contains(const void* ptr) { return bottom() <= ptr && ptr < _top; }
 
--- a/src/hotspot/share/memory/metaspace.cpp	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/memory/metaspace.cpp	Wed Nov 08 16:03:35 2017 -0500
@@ -108,6 +108,18 @@
   return (ChunkIndex) (i+1);
 }
 
+static const char* scale_unit(size_t scale) {
+  switch(scale) {
+    case 1: return "BYTES";
+    case K: return "KB";
+    case M: return "MB";
+    case G: return "GB";
+    default:
+      ShouldNotReachHere();
+      return NULL;
+  }
+}
+
 volatile intptr_t MetaspaceGC::_capacity_until_GC = 0;
 uint MetaspaceGC::_shrink_factor = 0;
 bool MetaspaceGC::_should_concurrent_collect = false;
@@ -176,7 +188,7 @@
 
   void locked_get_statistics(ChunkManagerStatistics* stat) const;
   void get_statistics(ChunkManagerStatistics* stat) const;
-  static void print_statistics(const ChunkManagerStatistics* stat, outputStream* out);
+  static void print_statistics(const ChunkManagerStatistics* stat, outputStream* out, size_t scale);
 
  public:
 
@@ -283,7 +295,7 @@
 
   // Prints composition for both non-class and (if available)
   // class chunk manager.
-  static void print_all_chunkmanagers(outputStream* out);
+  static void print_all_chunkmanagers(outputStream* out, size_t scale = 1);
 };
 
 class SmallBlocks : public CHeapObj<mtClass> {
@@ -480,6 +492,7 @@
 #endif
 
   void print_on(outputStream* st) const;
+  void print_map(outputStream* st, bool is_class) const;
 };
 
 #define assert_is_aligned(value, alignment)                  \
@@ -531,6 +544,94 @@
   }
 }
 
+void VirtualSpaceNode::print_map(outputStream* st, bool is_class) const {
+
+  // Format:
+  // <ptr>
+  // <ptr>  . .. .               .  ..
+  //        SSxSSMMMMMMMMMMMMMMMMsssXX
+  //        112114444444444444444
+  // <ptr>  . .. .               .  ..
+  //        SSxSSMMMMMMMMMMMMMMMMsssXX
+  //        112114444444444444444
+
+  if (bottom() == top()) {
+    return;
+  }
+
+  // First line: dividers for every med-chunk-sized interval
+  // Second line: a dot for the start of a chunk
+  // Third line: a letter per chunk type (x,s,m,h), uppercase if in use.
+
+  const size_t spec_chunk_size = is_class ? ClassSpecializedChunk : SpecializedChunk;
+  const size_t small_chunk_size = is_class ? ClassSmallChunk : SmallChunk;
+  const size_t med_chunk_size = is_class ? ClassMediumChunk : MediumChunk;
+
+  int line_len = 100;
+  const size_t section_len = align_up(spec_chunk_size * line_len, med_chunk_size);
+  line_len = (int)(section_len / spec_chunk_size);
+
+  char* line1 = (char*)os::malloc(line_len, mtInternal);
+  char* line2 = (char*)os::malloc(line_len, mtInternal);
+  char* line3 = (char*)os::malloc(line_len, mtInternal);
+  int pos = 0;
+  const MetaWord* p = bottom();
+  const Metachunk* chunk = (const Metachunk*)p;
+  const MetaWord* chunk_end = p + chunk->word_size();
+  while (p < top()) {
+    if (pos == line_len) {
+      pos = 0;
+      st->fill_to(22);
+      st->print_raw(line1, line_len);
+      st->cr();
+      st->fill_to(22);
+      st->print_raw(line2, line_len);
+      st->cr();
+    }
+    if (pos == 0) {
+      st->print(PTR_FORMAT ":", p2i(p));
+    }
+    if (p == chunk_end) {
+      chunk = (Metachunk*)p;
+      chunk_end = p + chunk->word_size();
+    }
+    if (p == (const MetaWord*)chunk) {
+      // chunk starts.
+      line1[pos] = '.';
+    } else {
+      line1[pos] = ' ';
+    }
+    // Line 2: chunk type (x=spec, s=small, m=medium, h=humongous), uppercase if
+    // chunk is in use.
+    const bool chunk_is_free = ((Metachunk*)chunk)->is_tagged_free();
+    if (chunk->word_size() == spec_chunk_size) {
+      line2[pos] = chunk_is_free ? 'x' : 'X';
+    } else if (chunk->word_size() == small_chunk_size) {
+      line2[pos] = chunk_is_free ? 's' : 'S';
+    } else if (chunk->word_size() == med_chunk_size) {
+      line2[pos] = chunk_is_free ? 'm' : 'M';
+   } else if (chunk->word_size() > med_chunk_size) {
+      line2[pos] = chunk_is_free ? 'h' : 'H';
+    } else {
+      ShouldNotReachHere();
+    }
+    p += spec_chunk_size;
+    pos ++;
+  }
+  if (pos > 0) {
+    st->fill_to(22);
+    st->print_raw(line1, pos);
+    st->cr();
+    st->fill_to(22);
+    st->print_raw(line2, pos);
+    st->cr();
+  }
+  os::free(line1);
+  os::free(line2);
+  os::free(line3);
+}
+
+
 #ifdef ASSERT
 uintx VirtualSpaceNode::container_count_slow() {
   uintx count = 0;
@@ -637,6 +738,7 @@
   void purge(ChunkManager* chunk_manager);
 
   void print_on(outputStream* st) const;
+  void print_map(outputStream* st) const;
 
   class VirtualSpaceListIterator : public StackObj {
     VirtualSpaceNode* _virtual_spaces;
@@ -1449,6 +1551,18 @@
   }
 }
 
+void VirtualSpaceList::print_map(outputStream* st) const {
+  VirtualSpaceNode* list = virtual_space_list();
+  VirtualSpaceListIterator iter(list);
+  unsigned i = 0;
+  while (iter.repeat()) {
+    st->print_cr("Node %u:", i);
+    VirtualSpaceNode* node = iter.get_next();
+    node->print_map(st, this->is_class());
+    i ++;
+  }
+}
+
 // MetaspaceGC methods
 
 // VM_CollectForMetadataAllocation is the vm operation used to GC.
@@ -1724,7 +1838,6 @@
 #endif
 
 // ChunkManager methods
-
 size_t ChunkManager::free_chunks_total_words() {
   return _free_chunks_total;
 }
@@ -1923,11 +2036,10 @@
   // Remove it from the links to this freelist
   chunk->set_next(NULL);
   chunk->set_prev(NULL);
-#ifdef ASSERT
+
   // Chunk is no longer on any freelist. Setting to false make container_count_slow()
   // work.
   chunk->set_is_tagged_free(false);
-#endif
   chunk->container()->inc_container_count();
 
   slow_locked_verify();
@@ -1995,7 +2107,7 @@
         chunk_size_name(index), p2i(chunk), chunk->word_size());
   }
   chunk->container()->dec_container_count();
-  DEBUG_ONLY(chunk->set_is_tagged_free(true);)
+  chunk->set_is_tagged_free(true);
 
   // Chunk has been added; update counters.
   account_for_added_chunk(chunk);
@@ -2057,22 +2169,45 @@
   locked_get_statistics(stat);
 }
 
-void ChunkManager::print_statistics(const ChunkManagerStatistics* stat, outputStream* out) {
+void ChunkManager::print_statistics(const ChunkManagerStatistics* stat, outputStream* out, size_t scale) {
   size_t total = 0;
+  assert(scale == 1 || scale == K || scale == M || scale == G, "Invalid scale");
+
+  const char* unit = scale_unit(scale);
   for (ChunkIndex i = ZeroIndex; i < NumberOfFreeLists; i = next_chunk_index(i)) {
-    out->print_cr("  " SIZE_FORMAT " %s (" SIZE_FORMAT " bytes) chunks, total " SIZE_FORMAT " bytes",
-                 stat->num_by_type[i], chunk_size_name(i),
-                 stat->single_size_by_type[i],
-                 stat->total_size_by_type[i]);
+    out->print("  " SIZE_FORMAT " %s (" SIZE_FORMAT " bytes) chunks, total ",
+                   stat->num_by_type[i], chunk_size_name(i),
+                   stat->single_size_by_type[i]);
+    if (scale == 1) {
+      out->print_cr(SIZE_FORMAT " bytes", stat->total_size_by_type[i]);
+    } else {
+      out->print_cr("%.2f%s", (float)stat->total_size_by_type[i] / scale, unit);
+    }
+
     total += stat->total_size_by_type[i];
   }
-  out->print_cr("  " SIZE_FORMAT " humongous chunks, total " SIZE_FORMAT " bytes",
-               stat->num_humongous_chunks, stat->total_size_humongous_chunks);
+
+
   total += stat->total_size_humongous_chunks;
-  out->print_cr("  total size: " SIZE_FORMAT ".", total);
+
+  if (scale == 1) {
+    out->print_cr("  " SIZE_FORMAT " humongous chunks, total " SIZE_FORMAT " bytes",
+    stat->num_humongous_chunks, stat->total_size_humongous_chunks);
+
+    out->print_cr("  total size: " SIZE_FORMAT " bytes.", total);
+  } else {
+    out->print_cr("  " SIZE_FORMAT " humongous chunks, total %.2f%s",
+    stat->num_humongous_chunks,
+    (float)stat->total_size_humongous_chunks / scale, unit);
+
+    out->print_cr("  total size: %.2f%s.", (float)total / scale, unit);
+  }
+
 }
 
-void ChunkManager::print_all_chunkmanagers(outputStream* out) {
+void ChunkManager::print_all_chunkmanagers(outputStream* out, size_t scale) {
+  assert(scale == 1 || scale == K || scale == M || scale == G, "Invalid scale");
+
   // Note: keep lock protection only to retrieving statistics; keep printing
   // out of lock protection
   ChunkManagerStatistics stat;
@@ -2080,7 +2215,7 @@
   const ChunkManager* const non_class_cm = Metaspace::chunk_manager_metadata();
   if (non_class_cm != NULL) {
     non_class_cm->get_statistics(&stat);
-    ChunkManager::print_statistics(&stat, out);
+    ChunkManager::print_statistics(&stat, out, scale);
   } else {
     out->print_cr("unavailable.");
   }
@@ -2088,7 +2223,7 @@
   const ChunkManager* const class_cm = Metaspace::chunk_manager_class();
   if (class_cm != NULL) {
     class_cm->get_statistics(&stat);
-    ChunkManager::print_statistics(&stat, out);
+    ChunkManager::print_statistics(&stat, out, scale);
   } else {
     out->print_cr("unavailable.");
   }
@@ -2911,9 +3046,9 @@
   size_t free_bytes = free_bytes_slow(mdtype);
   size_t used_and_free = used_bytes + free_bytes +
                            free_chunks_capacity_bytes;
-  out->print_cr("  Chunk accounting: used in chunks " SIZE_FORMAT
+  out->print_cr("  Chunk accounting: (used in chunks " SIZE_FORMAT
              "K + unused in chunks " SIZE_FORMAT "K  + "
-             " capacity in free chunks " SIZE_FORMAT "K = " SIZE_FORMAT
+             " capacity in free chunks " SIZE_FORMAT "K) = " SIZE_FORMAT
              "K  capacity in allocated chunks " SIZE_FORMAT "K",
              used_bytes / K,
              free_bytes / K,
@@ -2981,6 +3116,194 @@
   }
 }
 
+class MetadataStats VALUE_OBJ_CLASS_SPEC {
+private:
+  size_t _capacity;
+  size_t _used;
+  size_t _free;
+  size_t _waste;
+
+public:
+  MetadataStats() : _capacity(0), _used(0), _free(0), _waste(0) { }
+  MetadataStats(size_t capacity, size_t used, size_t free, size_t waste)
+  : _capacity(capacity), _used(used), _free(free), _waste(waste) { }
+
+  void add(const MetadataStats& stats) {
+    _capacity += stats.capacity();
+    _used += stats.used();
+    _free += stats.free();
+    _waste += stats.waste();
+  }
+
+  size_t capacity() const { return _capacity; }
+  size_t used() const     { return _used; }
+  size_t free() const     { return _free; }
+  size_t waste() const    { return _waste; }
+
+  void print_on(outputStream* out, size_t scale) const;
+};
+
+
+void MetadataStats::print_on(outputStream* out, size_t scale) const {
+  const char* unit = scale_unit(scale);
+  out->print_cr("capacity=%10.2f%s used=%10.2f%s free=%10.2f%s waste=%10.2f%s",
+    (float)capacity() / scale, unit,
+    (float)used() / scale, unit,
+    (float)free() / scale, unit,
+    (float)waste() / scale, unit);
+}
+
+class PrintCLDMetaspaceInfoClosure : public CLDClosure {
+private:
+  outputStream*  _out;
+  size_t         _scale;
+
+  size_t         _total_count;
+  MetadataStats  _total_metadata;
+  MetadataStats  _total_class;
+
+  size_t         _total_anon_count;
+  MetadataStats  _total_anon_metadata;
+  MetadataStats  _total_anon_class;
+
+public:
+  PrintCLDMetaspaceInfoClosure(outputStream* out, size_t scale = K)
+  : _out(out), _scale(scale), _total_count(0), _total_anon_count(0) { }
+
+  ~PrintCLDMetaspaceInfoClosure() {
+    print_summary();
+  }
+
+  void do_cld(ClassLoaderData* cld) {
+    assert(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint");
+
+    if (cld->is_unloading()) return;
+    Metaspace* msp = cld->metaspace_or_null();
+    if (msp == NULL) {
+      return;
+    }
+
+    bool anonymous = false;
+    if (cld->is_anonymous()) {
+      _out->print_cr("ClassLoader: for anonymous class");
+      anonymous = true;
+    } else {
+      ResourceMark rm;
+      _out->print_cr("ClassLoader: %s", cld->loader_name());
+    }
+
+    print_metaspace(msp, anonymous);
+    _out->cr();
+  }
+
+private:
+  void print_metaspace(Metaspace* msp, bool anonymous);
+  void print_summary() const;
+};
+
+void PrintCLDMetaspaceInfoClosure::print_metaspace(Metaspace* msp, bool anonymous){
+  assert(msp != NULL, "Sanity");
+  SpaceManager* vsm = msp->vsm();
+  const char* unit = scale_unit(_scale);
+
+  size_t capacity = vsm->sum_capacity_in_chunks_in_use() * BytesPerWord;
+  size_t used = vsm->sum_used_in_chunks_in_use() * BytesPerWord;
+  size_t free = vsm->sum_free_in_chunks_in_use() * BytesPerWord;
+  size_t waste = vsm->sum_waste_in_chunks_in_use() * BytesPerWord;
+
+  _total_count ++;
+  MetadataStats metadata_stats(capacity, used, free, waste);
+  _total_metadata.add(metadata_stats);
+
+  if (anonymous) {
+    _total_anon_count ++;
+    _total_anon_metadata.add(metadata_stats);
+  }
+
+  _out->print("  Metadata   ");
+  metadata_stats.print_on(_out, _scale);
+
+  if (Metaspace::using_class_space()) {
+    vsm = msp->class_vsm();
+
+    capacity = vsm->sum_capacity_in_chunks_in_use() * BytesPerWord;
+    used = vsm->sum_used_in_chunks_in_use() * BytesPerWord;
+    free = vsm->sum_free_in_chunks_in_use() * BytesPerWord;
+    waste = vsm->sum_waste_in_chunks_in_use() * BytesPerWord;
+
+    MetadataStats class_stats(capacity, used, free, waste);
+    _total_class.add(class_stats);
+
+    if (anonymous) {
+      _total_anon_class.add(class_stats);
+    }
+
+    _out->print("  Class data ");
+    class_stats.print_on(_out, _scale);
+  }
+}
+
+void PrintCLDMetaspaceInfoClosure::print_summary() const {
+  const char* unit = scale_unit(_scale);
+  _out->cr();
+  _out->print_cr("Summary:");
+
+  MetadataStats total;
+  total.add(_total_metadata);
+  total.add(_total_class);
+
+  _out->print("  Total class loaders=" SIZE_FORMAT_W(6) " ", _total_count);
+  total.print_on(_out, _scale);
+
+  _out->print("                    Metadata ");
+  _total_metadata.print_on(_out, _scale);
+
+  if (Metaspace::using_class_space()) {
+    _out->print("                  Class data ");
+    _total_class.print_on(_out, _scale);
+  }
+  _out->cr();
+
+  MetadataStats total_anon;
+  total_anon.add(_total_anon_metadata);
+  total_anon.add(_total_anon_class);
+
+  _out->print("For anonymous classes=" SIZE_FORMAT_W(6) " ", _total_anon_count);
+  total_anon.print_on(_out, _scale);
+
+  _out->print("                    Metadata ");
+  _total_anon_metadata.print_on(_out, _scale);
+
+  if (Metaspace::using_class_space()) {
+    _out->print("                  Class data ");
+    _total_anon_class.print_on(_out, _scale);
+  }
+}
+
+void MetaspaceAux::print_metadata_for_nmt(outputStream* out, size_t scale) {
+  const char* unit = scale_unit(scale);
+  out->print_cr("Metaspaces:");
+  out->print_cr("  Metadata space: reserved=" SIZE_FORMAT_W(10) "%s committed=" SIZE_FORMAT_W(10) "%s",
+    reserved_bytes(Metaspace::NonClassType) / scale, unit,
+    committed_bytes(Metaspace::NonClassType) / scale, unit);
+  if (Metaspace::using_class_space()) {
+    out->print_cr("  Class    space: reserved=" SIZE_FORMAT_W(10) "%s committed=" SIZE_FORMAT_W(10) "%s",
+    reserved_bytes(Metaspace::ClassType) / scale, unit,
+    committed_bytes(Metaspace::ClassType) / scale, unit);
+  }
+
+  out->cr();
+  ChunkManager::print_all_chunkmanagers(out, scale);
+
+  out->cr();
+  out->print_cr("Per-classloader metadata:");
+  out->cr();
+
+  PrintCLDMetaspaceInfoClosure cl(out, scale);
+  ClassLoaderDataGraph::cld_do(&cl);
+}
+
+
 // Dump global metaspace things from the end of ClassLoaderDataGraph
 void MetaspaceAux::dump(outputStream* out) {
   out->print_cr("All Metaspace:");
@@ -2989,6 +3312,31 @@
   print_waste(out);
 }
 
+// Prints an ASCII representation of the given space.
+void MetaspaceAux::print_metaspace_map(outputStream* out, Metaspace::MetadataType mdtype) {
+  MutexLockerEx cl(SpaceManager::expand_lock(), Mutex::_no_safepoint_check_flag);
+  const bool for_class = mdtype == Metaspace::ClassType ? true : false;
+  VirtualSpaceList* const vsl = for_class ? Metaspace::class_space_list() : Metaspace::space_list();
+  if (vsl != NULL) {
+    if (for_class) {
+      if (!Metaspace::using_class_space()) {
+        out->print_cr("No Class Space.");
+        return;
+      }
+      out->print_raw("---- Metaspace Map (Class Space) ----");
+    } else {
+      out->print_raw("---- Metaspace Map (Non-Class Space) ----");
+    }
+    // Print legend:
+    out->cr();
+    out->print_cr("Chunk Types (uppercase chunks are in use): x-specialized, s-small, m-medium, h-humongous.");
+    out->cr();
+    VirtualSpaceList* const vsl = for_class ? Metaspace::class_space_list() : Metaspace::space_list();
+    vsl->print_map(out);
+    out->cr();
+  }
+}
+
 void MetaspaceAux::verify_free_chunks() {
   Metaspace::chunk_manager_metadata()->verify();
   if (Metaspace::using_class_space()) {
@@ -3627,6 +3975,7 @@
     }
     LogStream ls(log.info());
     MetaspaceAux::dump(&ls);
+    MetaspaceAux::print_metaspace_map(&ls, mdtype);
     ChunkManager::print_all_chunkmanagers(&ls);
   }
 
--- a/src/hotspot/share/memory/metaspace.hpp	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/memory/metaspace.hpp	Wed Nov 08 16:03:35 2017 -0500
@@ -63,6 +63,7 @@
 class MetaWord;
 class Mutex;
 class outputStream;
+class PrintCLDMetaspaceInfoClosure;
 class SpaceManager;
 class VirtualSpaceList;
 
@@ -87,6 +88,7 @@
   friend class MetaspaceAux;
   friend class MetaspaceShared;
   friend class CollectorPolicy;
+  friend class PrintCLDMetaspaceInfoClosure;
 
  public:
   enum MetadataType {
@@ -347,6 +349,8 @@
     return min_chunk_size_words() * BytesPerWord;
   }
 
+  static void print_metadata_for_nmt(outputStream* out, size_t scale = K);
+
   static bool has_chunk_free_list(Metaspace::MetadataType mdtype);
   static MetaspaceChunkFreeListSummary chunk_free_list_summary(Metaspace::MetadataType mdtype);
 
@@ -357,6 +361,10 @@
 
   static void print_class_waste(outputStream* out);
   static void print_waste(outputStream* out);
+
+  // Prints an ASCII representation of the given space.
+  static void print_metaspace_map(outputStream* out, Metaspace::MetadataType mdtype);
+
   static void dump(outputStream* out);
   static void verify_free_chunks();
   // Checks that the values returned by allocated_capacity_bytes() and
--- a/src/hotspot/share/oops/constantPool.cpp	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/oops/constantPool.cpp	Wed Nov 08 16:03:35 2017 -0500
@@ -305,14 +305,9 @@
 
   constantPoolHandle cp(THREAD, this);
   for (int index = 1; index < length(); index++) { // Index 0 is unused
-    if (tag_at(index).is_string()) {
-      Symbol* sym = cp->unresolved_string_at(index);
-      // Look up only. Only resolve references to already interned strings.
-      oop str = StringTable::lookup(sym);
-      if (str != NULL) {
-        int cache_index = cp->cp_to_object_index(index);
-        cp->string_at_put(index, cache_index, str);
-      }
+    if (tag_at(index).is_string() && !cp->is_pseudo_string_at(index)) {
+      int cache_index = cp->cp_to_object_index(index);
+      string_at_impl(cp, index, cache_index, CHECK);
     }
   }
 }
--- a/src/hotspot/share/oops/method.hpp	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/oops/method.hpp	Wed Nov 08 16:03:35 2017 -0500
@@ -271,7 +271,7 @@
   int highest_osr_comp_level() const;
   void set_highest_osr_comp_level(int level);
 
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
   // Count of times method was exited via exception while interpreting
   void interpreter_throwout_increment(TRAPS) {
     MethodCounters* mcs = get_method_counters(CHECK);
@@ -426,7 +426,7 @@
       return (mcs == NULL) ? 0 : mcs->interpreter_invocation_count();
     }
   }
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
   int increment_interpreter_invocation_count(TRAPS) {
     if (TieredCompilation) ShouldNotReachHere();
     MethodCounters* mcs = get_method_counters(CHECK_0);
--- a/src/hotspot/share/oops/methodCounters.hpp	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/oops/methodCounters.hpp	Wed Nov 08 16:03:35 2017 -0500
@@ -40,7 +40,7 @@
 #if INCLUDE_AOT
   Method*           _method;                     // Back link to Method
 #endif
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
   int               _interpreter_invocation_count; // Count of times invoked (reused as prev_event_count in tiered)
   u2                _interpreter_throwout_count; // Count of times method was exited via exception while interpreting
 #endif
@@ -130,7 +130,7 @@
   MetaspaceObj::Type type() const { return MethodCountersType; }
   void clear_counters();
 
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
 
   int interpreter_invocation_count() {
     return _interpreter_invocation_count;
@@ -154,7 +154,7 @@
     _interpreter_throwout_count = count;
   }
 
-#else // defined(COMPILER2) || INCLUDE_JVMCI
+#else // COMPILER2_OR_JVMCI
 
   int interpreter_invocation_count() {
     return 0;
@@ -170,7 +170,7 @@
     assert(count == 0, "count must be 0");
   }
 
-#endif // defined(COMPILER2) || INCLUDE_JVMCI
+#endif // COMPILER2_OR_JVMCI
 
 #if INCLUDE_JVMTI
   u2   number_of_breakpoints() const   { return _number_of_breakpoints; }
@@ -213,7 +213,7 @@
     return byte_offset_of(MethodCounters, _nmethod_age);
   }
 
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
 
   static ByteSize interpreter_invocation_counter_offset() {
     return byte_offset_of(MethodCounters, _interpreter_invocation_count);
@@ -223,14 +223,14 @@
     return offset_of(MethodCounters, _interpreter_invocation_count);
   }
 
-#else // defined(COMPILER2) || INCLUDE_JVMCI
+#else // COMPILER2_OR_JVMCI
 
   static ByteSize interpreter_invocation_counter_offset() {
     ShouldNotReachHere();
     return in_ByteSize(0);
   }
 
-#endif // defined(COMPILER2) || INCLUDE_JVMCI
+#endif // COMPILER2_OR_JVMCI
 
   static ByteSize invocation_counter_offset()    {
     return byte_offset_of(MethodCounters, _invocation_counter);
--- a/src/hotspot/share/prims/jni.cpp	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/prims/jni.cpp	Wed Nov 08 16:03:35 2017 -0500
@@ -3949,7 +3949,7 @@
         // JVMCI is initialized on a CompilerThread
         if (BootstrapJVMCI) {
           JavaThread* THREAD = thread;
-          JVMCICompiler* compiler = JVMCICompiler::instance(CATCH);
+          JVMCICompiler* compiler = JVMCICompiler::instance(true, CATCH);
           compiler->bootstrap(THREAD);
           if (HAS_PENDING_EXCEPTION) {
             HandleMark hm;
--- a/src/hotspot/share/prims/whitebox.cpp	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/prims/whitebox.cpp	Wed Nov 08 16:03:35 2017 -0500
@@ -1715,6 +1715,10 @@
   }
 WB_END
 
+WB_ENTRY(jboolean, WB_AreOpenArchiveHeapObjectsMapped(JNIEnv* env))
+  return MetaspaceShared::open_archive_heap_region_mapped();
+WB_END
+
 WB_ENTRY(jboolean, WB_IsCDSIncludedInVmBuild(JNIEnv* env))
 #if INCLUDE_CDS
   return true;
@@ -2031,6 +2035,7 @@
   {CC"isSharedClass",      CC"(Ljava/lang/Class;)Z",  (void*)&WB_IsSharedClass },
   {CC"areSharedStringsIgnored",           CC"()Z",    (void*)&WB_AreSharedStringsIgnored },
   {CC"getResolvedReferences", CC"(Ljava/lang/Class;)Ljava/lang/Object;", (void*)&WB_GetResolvedReferences},
+  {CC"areOpenArchiveHeapObjectsMapped",   CC"()Z",    (void*)&WB_AreOpenArchiveHeapObjectsMapped},
   {CC"isCDSIncludedInVmBuild",            CC"()Z",    (void*)&WB_IsCDSIncludedInVmBuild },
   {CC"clearInlineCaches0",  CC"(Z)V",                 (void*)&WB_ClearInlineCaches },
   {CC"addCompilerDirective",    CC"(Ljava/lang/String;)I",
--- a/src/hotspot/share/runtime/arguments.cpp	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/runtime/arguments.cpp	Wed Nov 08 16:03:35 2017 -0500
@@ -396,6 +396,10 @@
   { "MinSleepInterval",              JDK_Version::jdk(9),      JDK_Version::jdk(10), JDK_Version::jdk(11) },
   { "PermSize",                      JDK_Version::undefined(), JDK_Version::jdk(8),  JDK_Version::undefined() },
   { "MaxPermSize",                   JDK_Version::undefined(), JDK_Version::jdk(8),  JDK_Version::undefined() },
+  { "SharedReadWriteSize",           JDK_Version::undefined(), JDK_Version::jdk(10), JDK_Version::undefined() },
+  { "SharedReadOnlySize",            JDK_Version::undefined(), JDK_Version::jdk(10), JDK_Version::undefined() },
+  { "SharedMiscDataSize",            JDK_Version::undefined(), JDK_Version::jdk(10), JDK_Version::undefined() },
+  { "SharedMiscCodeSize",            JDK_Version::undefined(), JDK_Version::jdk(10), JDK_Version::undefined() },
 
 #ifdef TEST_VERIFY_SPECIAL_JVM_FLAGS
   { "dep > obs",                    JDK_Version::jdk(9), JDK_Version::jdk(8), JDK_Version::undefined() },
@@ -1860,7 +1864,7 @@
 #endif
   select_gc();
 
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
   // Shared spaces work fine with other GCs but causes bytecode rewriting
   // to be disabled, which hurts interpreter performance and decreases
   // server performance.  When -server is specified, keep the default off
@@ -2089,9 +2093,10 @@
   // respecting the maximum and minimum sizes of the heap.
   if (FLAG_IS_DEFAULT(MaxHeapSize)) {
     julong reasonable_max = (julong)((phys_mem * MaxRAMPercentage) / 100);
-    if (phys_mem <= (julong)((MaxHeapSize * MinRAMPercentage) / 100)) {
+    const julong reasonable_min = (julong)((phys_mem * MinRAMPercentage) / 100);
+    if (reasonable_min < MaxHeapSize) {
       // Small physical memory, so use a minimum fraction of it for the heap
-      reasonable_max = (julong)((phys_mem * MinRAMPercentage) / 100);
+      reasonable_max = reasonable_min;
     } else {
       // Not-small physical memory, so require a heap at least
       // as large as MaxHeapSize
--- a/src/hotspot/share/runtime/deoptimization.cpp	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/runtime/deoptimization.cpp	Wed Nov 08 16:03:35 2017 -0500
@@ -192,7 +192,7 @@
 
   bool realloc_failures = false;
 
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
   // Reallocate the non-escaping objects and restore their fields. Then
   // relock objects if synchronization on them was eliminated.
 #ifndef INCLUDE_JVMCI
@@ -282,7 +282,7 @@
     }
   }
 #endif // INCLUDE_JVMCI
-#endif // COMPILER2 || INCLUDE_JVMCI
+#endif // COMPILER2_OR_JVMCI
 
   ScopeDesc* trap_scope = chunk->at(0)->scope();
   Handle exceptionObject;
@@ -303,7 +303,7 @@
   NoSafepointVerifier no_safepoint;
 
   vframeArray* array = create_vframeArray(thread, deoptee, &map, chunk, realloc_failures);
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
   if (realloc_failures) {
     pop_frames_failed_reallocs(thread, array);
   }
@@ -792,7 +792,7 @@
 Deoptimization::DeoptAction Deoptimization::_unloaded_action
   = Deoptimization::Action_reinterpret;
 
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
 bool Deoptimization::realloc_objects(JavaThread* thread, frame* fr, GrowableArray<ScopeValue*>* objects, TRAPS) {
   Handle pending_exception(THREAD, thread->pending_exception());
   const char* exception_file = thread->exception_file();
@@ -1151,7 +1151,7 @@
   }
 }
 #endif
-#endif // COMPILER2 || INCLUDE_JVMCI
+#endif // COMPILER2_OR_JVMCI
 
 vframeArray* Deoptimization::create_vframeArray(JavaThread* thread, frame fr, RegisterMap *reg_map, GrowableArray<compiledVFrame*>* chunk, bool realloc_failures) {
   Events::log(thread, "DEOPT PACKING pc=" INTPTR_FORMAT " sp=" INTPTR_FORMAT, p2i(fr.pc()), p2i(fr.sp()));
@@ -1211,7 +1211,7 @@
   return array;
 }
 
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
 void Deoptimization::pop_frames_failed_reallocs(JavaThread* thread, vframeArray* array) {
   // Reallocation of some scalar replaced objects failed. Record
   // that we need to pop all the interpreter frames for the
@@ -1443,7 +1443,7 @@
   return mdo;
 }
 
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
 void Deoptimization::load_class_by_index(const constantPoolHandle& constant_pool, int index, TRAPS) {
   // in case of an unresolved klass entry, load the class.
   if (constant_pool->tag_at(index).is_unresolved_klass()) {
@@ -2350,7 +2350,7 @@
     if (xtty != NULL)  xtty->tail("statistics");
   }
 }
-#else // COMPILER2 || INCLUDE_JVMCI
+#else // COMPILER2_OR_JVMCI
 
 
 // Stubs for C1 only system.
@@ -2386,4 +2386,4 @@
   return buf;
 }
 
-#endif // COMPILER2 || INCLUDE_JVMCI
+#endif // COMPILER2_OR_JVMCI
--- a/src/hotspot/share/runtime/deoptimization.hpp	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/runtime/deoptimization.hpp	Wed Nov 08 16:03:35 2017 -0500
@@ -151,7 +151,7 @@
   // executing in a particular CodeBlob if UseBiasedLocking is enabled
   static void revoke_biases_of_monitors(CodeBlob* cb);
 
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
 JVMCI_ONLY(public:)
 
   // Support for restoring non-escaping objects
@@ -162,7 +162,7 @@
   static void relock_objects(GrowableArray<MonitorInfo*>* monitors, JavaThread* thread, bool realloc_failures);
   static void pop_frames_failed_reallocs(JavaThread* thread, vframeArray* array);
   NOT_PRODUCT(static void print_objects(GrowableArray<ScopeValue*>* objects, bool realloc_failures);)
-#endif // COMPILER2 || INCLUDE_JVMCI
+#endif // COMPILER2_OR_JVMCI
 
   public:
   static vframeArray* create_vframeArray(JavaThread* thread, frame fr, RegisterMap *reg_map, GrowableArray<compiledVFrame*>* chunk, bool realloc_failures);
--- a/src/hotspot/share/runtime/frame.cpp	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/runtime/frame.cpp	Wed Nov 08 16:03:35 2017 -0500
@@ -1148,7 +1148,7 @@
       // make sure we have the right receiver type
     }
   }
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
   assert(DerivedPointerTable::is_empty(), "must be empty before verify");
 #endif
   oops_do_internal(&VerifyOopClosure::verify_oop, NULL, (RegisterMap*)map, false);
--- a/src/hotspot/share/runtime/globals.hpp	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/runtime/globals.hpp	Wed Nov 08 16:03:35 2017 -0500
@@ -99,11 +99,11 @@
 #define CI_COMPILER_COUNT 0
 #else
 
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
 #define CI_COMPILER_COUNT 2
 #else
 #define CI_COMPILER_COUNT 1
-#endif // COMPILER2 || INCLUDE_JVMCI
+#endif // COMPILER2_OR_JVMCI
 
 #endif // no compilers
 
@@ -3901,18 +3901,6 @@
           "If PrintSharedArchiveAndExit is true, also print the shared "    \
           "dictionary")                                                     \
                                                                             \
-  product(size_t, SharedReadWriteSize, 0,                                   \
-          "Deprecated")                                                     \
-                                                                            \
-  product(size_t, SharedReadOnlySize, 0,                                    \
-          "Deprecated")                                                     \
-                                                                            \
-  product(size_t, SharedMiscDataSize,  0,                                   \
-          "Deprecated")                                                     \
-                                                                            \
-  product(size_t, SharedMiscCodeSize,  0,                                   \
-          "Deprecated")                                                     \
-                                                                            \
   product(size_t, SharedBaseAddress, LP64_ONLY(32*G)                        \
           NOT_LP64(LINUX_ONLY(2*G) NOT_LINUX(0)),                           \
           "Address to allocate shared memory region for class data")        \
--- a/src/hotspot/share/runtime/rframe.cpp	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/runtime/rframe.cpp	Wed Nov 08 16:03:35 2017 -0500
@@ -155,7 +155,7 @@
 
 void RFrame::print(const char* kind) {
 #ifndef PRODUCT
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
   int cnt = top_method()->interpreter_invocation_count();
 #else
   int cnt = top_method()->invocation_count();
--- a/src/hotspot/share/runtime/sharedRuntime.cpp	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/runtime/sharedRuntime.cpp	Wed Nov 08 16:03:35 2017 -0500
@@ -102,13 +102,13 @@
   _resolve_static_call_blob            = generate_resolve_blob(CAST_FROM_FN_PTR(address, SharedRuntime::resolve_static_call_C),        "resolve_static_call");
   _resolve_static_call_entry           = _resolve_static_call_blob->entry_point();
 
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
   // Vectors are generated only by C2 and JVMCI.
   bool support_wide = is_wide_vector(MaxVectorSize);
   if (support_wide) {
     _polling_page_vectors_safepoint_handler_blob = generate_handler_blob(CAST_FROM_FN_PTR(address, SafepointSynchronize::handle_polling_page_exception), POLL_AT_VECTOR_LOOP);
   }
-#endif // COMPILER2 || INCLUDE_JVMCI
+#endif // COMPILER2_OR_JVMCI
   _polling_page_safepoint_handler_blob = generate_handler_blob(CAST_FROM_FN_PTR(address, SafepointSynchronize::handle_polling_page_exception), POLL_AT_LOOP);
   _polling_page_return_handler_blob    = generate_handler_blob(CAST_FROM_FN_PTR(address, SafepointSynchronize::handle_polling_page_exception), POLL_AT_RETURN);
 
--- a/src/hotspot/share/runtime/thread.cpp	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/runtime/thread.cpp	Wed Nov 08 16:03:35 2017 -0500
@@ -3724,7 +3724,7 @@
   }
 
   // initialize compiler(s)
-#if defined(COMPILER1) || defined(COMPILER2) || INCLUDE_JVMCI
+#if defined(COMPILER1) || COMPILER2_OR_JVMCI
   CompileBroker::compilation_init(CHECK_JNI_ERR);
 #endif
 
--- a/src/hotspot/share/runtime/vm_operations.cpp	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/runtime/vm_operations.cpp	Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -230,6 +230,10 @@
   JNIHandles::print_on(_out);
 }
 
+void VM_PrintMetadata::doit() {
+  MetaspaceAux::print_metadata_for_nmt(_out, _scale);
+}
+
 VM_FindDeadlocks::~VM_FindDeadlocks() {
   if (_deadlocks != NULL) {
     DeadlockCycle* cycle = _deadlocks;
--- a/src/hotspot/share/runtime/vm_operations.hpp	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/runtime/vm_operations.hpp	Wed Nov 08 16:03:35 2017 -0500
@@ -111,6 +111,7 @@
   template(ThreadsSuspendJVMTI)                   \
   template(ICBufferFull)                          \
   template(ScavengeMonitors)                      \
+  template(PrintMetadata)                         \
 
 class VM_Operation: public CHeapObj<mtInternal> {
  public:
@@ -374,6 +375,17 @@
   void doit();
 };
 
+class VM_PrintMetadata : public VM_Operation {
+ private:
+  outputStream* _out;
+  size_t        _scale;
+ public:
+  VM_PrintMetadata(outputStream* out, size_t scale) : _out(out), _scale(scale) {};
+
+  VMOp_Type type() const  { return VMOp_PrintMetadata; }
+  void doit();
+};
+
 class DeadlockCycle;
 class VM_FindDeadlocks: public VM_Operation {
  private:
--- a/src/hotspot/share/services/nmtDCmd.cpp	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/services/nmtDCmd.cpp	Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,8 @@
 #include "precompiled.hpp"
 #include "memory/resourceArea.hpp"
 #include "runtime/mutexLocker.hpp"
+#include "runtime/vmThread.hpp"
+#include "runtime/vm_operations.hpp"
 #include "services/nmtDCmd.hpp"
 #include "services/memReporter.hpp"
 #include "services/memTracker.hpp"
@@ -38,6 +40,8 @@
   _detail("detail", "request runtime to report memory allocation >= "
            "1K by each callsite.",
            "BOOLEAN", false, "false"),
+  _metadata("metadata", "request runtime to report metadata information",
+           "BOOLEAN", false, "false"),
   _baseline("baseline", "request runtime to baseline current memory usage, " \
             "so it can be compared against in later time.",
             "BOOLEAN", false, "false"),
@@ -57,6 +61,7 @@
        "STRING", false, "KB") {
   _dcmdparser.add_dcmd_option(&_summary);
   _dcmdparser.add_dcmd_option(&_detail);
+  _dcmdparser.add_dcmd_option(&_metadata);
   _dcmdparser.add_dcmd_option(&_baseline);
   _dcmdparser.add_dcmd_option(&_summary_diff);
   _dcmdparser.add_dcmd_option(&_detail_diff);
@@ -92,6 +97,7 @@
   int nopt = 0;
   if (_summary.is_set() && _summary.value()) { ++nopt; }
   if (_detail.is_set() && _detail.value()) { ++nopt; }
+  if (_metadata.is_set() && _metadata.value()) { ++nopt; }
   if (_baseline.is_set() && _baseline.value()) { ++nopt; }
   if (_summary_diff.is_set() && _summary_diff.value()) { ++nopt; }
   if (_detail_diff.is_set() && _detail_diff.value()) { ++nopt; }
@@ -100,7 +106,7 @@
 
   if (nopt > 1) {
       output()->print_cr("At most one of the following option can be specified: " \
-        "summary, detail, baseline, summary.diff, detail.diff, shutdown");
+        "summary, detail, metadata, baseline, summary.diff, detail.diff, shutdown");
       return;
   } else if (nopt == 0) {
     if (_summary.is_set()) {
@@ -118,9 +124,13 @@
     report(true, scale_unit);
   } else if (_detail.value()) {
     if (!check_detail_tracking_level(output())) {
-    return;
-  }
+      return;
+    }
     report(false, scale_unit);
+  } else if (_metadata.value()) {
+      size_t scale = get_scale(_scale.value());
+      VM_PrintMetadata op(output(), scale);
+      VMThread::execute(&op);
   } else if (_baseline.value()) {
     MemBaseline& baseline = MemTracker::get_baseline();
     if (!baseline.baseline(MemTracker::tracking_level() != NMT_detail)) {
--- a/src/hotspot/share/services/nmtDCmd.hpp	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/hotspot/share/services/nmtDCmd.hpp	Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -39,6 +39,7 @@
  protected:
   DCmdArgument<bool>  _summary;
   DCmdArgument<bool>  _detail;
+  DCmdArgument<bool>  _metadata;
   DCmdArgument<bool>  _baseline;
   DCmdArgument<bool>  _summary_diff;
   DCmdArgument<bool>  _detail_diff;
--- a/src/java.base/share/classes/java/io/FilePermission.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/java/io/FilePermission.java	Wed Nov 08 16:03:35 2017 -0500
@@ -698,7 +698,7 @@
             if (p2.equals(EMPTY_PATH)) {
                 return 0;
             } else if (p2.getName(0).equals(DOTDOT_PATH)) {
-                // "." contains p2 iif p2 has no "..". Since a
+                // "." contains p2 iff p2 has no "..". Since
                 // a normalized path can only have 0 or more
                 // ".." at the beginning. We only need to look
                 // at the head.
@@ -711,7 +711,7 @@
         } else if (p2.equals(EMPTY_PATH)) {
             int c1 = p1.getNameCount();
             if (!p1.getName(c1 - 1).equals(DOTDOT_PATH)) {
-                // "." is inside p1 iif p1 is 1 or more "..".
+                // "." is inside p1 iff p1 is 1 or more "..".
                 // For the same reason above, we only need to
                 // look at the tail.
                 return -1;
--- a/src/java.base/share/classes/java/lang/Module.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/java/lang/Module.java	Wed Nov 08 16:03:35 2017 -0500
@@ -57,8 +57,6 @@
 import jdk.internal.loader.BuiltinClassLoader;
 import jdk.internal.loader.BootLoader;
 import jdk.internal.loader.ClassLoaders;
-import jdk.internal.misc.JavaLangAccess;
-import jdk.internal.misc.SharedSecrets;
 import jdk.internal.module.IllegalAccessLogger;
 import jdk.internal.module.ModuleLoaderMap;
 import jdk.internal.module.ServicesCatalog;
@@ -68,6 +66,7 @@
 import jdk.internal.org.objectweb.asm.ClassReader;
 import jdk.internal.org.objectweb.asm.ClassVisitor;
 import jdk.internal.org.objectweb.asm.ClassWriter;
+import jdk.internal.org.objectweb.asm.ModuleVisitor;
 import jdk.internal.org.objectweb.asm.Opcodes;
 import jdk.internal.reflect.CallerSensitive;
 import jdk.internal.reflect.Reflection;
@@ -1432,7 +1431,7 @@
         ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS
                                          + ClassWriter.COMPUTE_FRAMES);
 
-        ClassVisitor cv = new ClassVisitor(Opcodes.ASM5, cw) {
+        ClassVisitor cv = new ClassVisitor(Opcodes.ASM6, cw) {
             @Override
             public void visit(int version,
                               int access,
@@ -1458,6 +1457,11 @@
             public void visitAttribute(Attribute attr) {
                 // drop non-annotation attributes
             }
+            @Override
+            public ModuleVisitor visitModule(String name, int flags, String version) {
+                // drop Module attribute
+                return null;
+            }
         };
 
         ClassReader cr = new ClassReader(in);
--- a/src/java.base/share/classes/java/lang/System.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/java/lang/System.java	Wed Nov 08 16:03:35 2017 -0500
@@ -1937,7 +1937,7 @@
         // initialization. So make sure the "props" is available at the
         // very beginning of the initialization and all system properties to
         // be put into it directly.
-        props = new Properties();
+        props = new Properties(84);
         initProperties(props);  // initialized by the VM
 
         // There are certain system configurations that may be controlled by
--- a/src/java.base/share/classes/java/lang/invoke/MethodHandle.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/java/lang/invoke/MethodHandle.java	Wed Nov 08 16:03:35 2017 -0500
@@ -765,7 +765,7 @@
      * In every other case, all conversions are applied <em>pairwise</em>,
      * which means that each argument or return value is converted to
      * exactly one argument or return value (or no return value).
-     * The applied conversions are defined by consulting the
+     * The applied conversions are defined by consulting
      * the corresponding component types of the old and new
      * method handle types.
      * <p>
--- a/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java	Wed Nov 08 16:03:35 2017 -0500
@@ -194,7 +194,7 @@
     static {
         // In case we need to double-back onto the StringConcatFactory during this
         // static initialization, make sure we have the reasonable defaults to complete
-        // the static initialization properly. After that, actual users would use the
+        // the static initialization properly. After that, actual users would use
         // the proper values we have read from the properties.
         STRATEGY = DEFAULT_STRATEGY;
         // CACHE_ENABLE = false; // implied
--- a/src/java.base/share/classes/java/lang/invoke/VarHandle.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/java/lang/invoke/VarHandle.java	Wed Nov 08 16:03:35 2017 -0500
@@ -205,7 +205,7 @@
  * and {@code double} on 32-bit platforms.
  *
  * <p>Access modes will override any memory ordering effects specified at
- * the declaration site of a variable.  For example, a VarHandle accessing a
+ * the declaration site of a variable.  For example, a VarHandle accessing
  * a field using the {@code get} access mode will access the field as
  * specified <em>by its access mode</em> even if that field is declared
  * {@code volatile}.  When mixed access is performed extreme care should be
@@ -423,7 +423,7 @@
  * {@link java.lang.invoke.MethodHandles#varHandleInvoker}.
  *
  * <h1>Interoperation between VarHandles and Java generics</h1>
- * A VarHandle can be obtained for a variable, such as a a field, which is
+ * A VarHandle can be obtained for a variable, such as a field, which is
  * declared with Java generic types.  As with the Core Reflection API, the
  * VarHandle's variable type will be constructed from the erasure of the
  * source-level type.  When a VarHandle access mode method is invoked, the
--- a/src/java.base/share/classes/java/net/DatagramSocket.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/java/net/DatagramSocket.java	Wed Nov 08 16:03:35 2017 -0500
@@ -988,7 +988,7 @@
 
     /**
      * Sets the SO_RCVBUF option to the specified value for this
-     * {@code DatagramSocket}. The SO_RCVBUF option is used by the
+     * {@code DatagramSocket}. The SO_RCVBUF option is used by
      * the network implementation as a hint to size the underlying
      * network I/O buffers. The SO_RCVBUF setting may also be used
      * by the network implementation to determine the maximum size
--- a/src/java.base/share/classes/java/net/Inet4Address.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/java/net/Inet4Address.java	Wed Nov 08 16:03:35 2017 -0500
@@ -143,7 +143,7 @@
         /**
          * Prior to 1.4 an InetAddress was created with a family
          * based on the platform AF_INET value (usually 2).
-         * For compatibility reasons we must therefore write the
+         * For compatibility reasons we must therefore write
          * the InetAddress with this family.
          */
         inet.holder().family = 2;
--- a/src/java.base/share/classes/java/net/SocketImpl.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/java/net/SocketImpl.java	Wed Nov 08 16:03:35 2017 -0500
@@ -333,7 +333,7 @@
      * latency, and low latency above short connection time, then it could
      * invoke this method with the values {@code (0, 1, 2)}.
      *
-     * By default, this method does nothing, unless it is overridden in a
+     * By default, this method does nothing, unless it is overridden in
      * a sub-class.
      *
      * @param  connectionTime
--- a/src/java.base/share/classes/java/net/SocksSocketImpl.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/java/net/SocksSocketImpl.java	Wed Nov 08 16:03:35 2017 -0500
@@ -657,7 +657,7 @@
 
     /**
      * Sends the Bind request to the SOCKS proxy. In the SOCKS protocol, bind
-     * means "accept incoming connection from", so the SocketAddress is the
+     * means "accept incoming connection from", so the SocketAddress is
      * the one of the host we do accept connection from.
      *
      * @param      saddr   the Socket address of the remote host.
--- a/src/java.base/share/classes/java/net/URLConnection.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/java/net/URLConnection.java	Wed Nov 08 16:03:35 2017 -0500
@@ -785,7 +785,7 @@
      * required to make the connection. By default, this method
      * returns {@code java.security.AllPermission}. Subclasses
      * should override this method and return the permission
-     * that best represents the permission required to make a
+     * that best represents the permission required to make
      * a connection to the URL. For example, a {@code URLConnection}
      * representing a {@code file:} URL would return a
      * {@code java.io.FilePermission} object.
--- a/src/java.base/share/classes/java/nio/channels/AsynchronousFileChannel.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/java/nio/channels/AsynchronousFileChannel.java	Wed Nov 08 16:03:35 2017 -0500
@@ -165,7 +165,7 @@
      * <tr>
      *   <th scope="row" > {@link StandardOpenOption#DELETE_ON_CLOSE DELETE_ON_CLOSE} </th>
      *   <td> When this option is present then the implementation makes a
-     *   <em>best effort</em> attempt to delete the file when closed by the
+     *   <em>best effort</em> attempt to delete the file when closed by
      *   the {@link #close close} method. If the {@code close} method is not
      *   invoked then a <em>best effort</em> attempt is made to delete the file
      *   when the Java virtual machine terminates. </td>
--- a/src/java.base/share/classes/java/nio/channels/Channels.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/java/nio/channels/Channels.java	Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -368,6 +368,10 @@
 
         @Override
         public int read(ByteBuffer dst) throws IOException {
+            if (!isOpen()) {
+                throw new ClosedChannelException();
+            }
+
             int len = dst.remaining();
             int totalRead = 0;
             int bytesRead = 0;
@@ -442,6 +446,10 @@
 
         @Override
         public int write(ByteBuffer src) throws IOException {
+            if (!isOpen()) {
+                throw new ClosedChannelException();
+            }
+
             int len = src.remaining();
             int totalWritten = 0;
             synchronized (writeLock) {
--- a/src/java.base/share/classes/java/nio/channels/FileChannel.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/java/nio/channels/FileChannel.java	Wed Nov 08 16:03:35 2017 -0500
@@ -216,7 +216,7 @@
      * <tr>
      *   <th scope="row" > {@link StandardOpenOption#DELETE_ON_CLOSE DELETE_ON_CLOSE} </th>
      *   <td> When this option is present then the implementation makes a
-     *   <em>best effort</em> attempt to delete the file when closed by the
+     *   <em>best effort</em> attempt to delete the file when closed by
      *   the {@link #close close} method. If the {@code close} method is not
      *   invoked then a <em>best effort</em> attempt is made to delete the file
      *   when the Java virtual machine terminates. </td>
--- a/src/java.base/share/classes/java/nio/file/Files.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/java/nio/file/Files.java	Wed Nov 08 16:03:35 2017 -0500
@@ -2401,7 +2401,7 @@
      *
      * <p> Note that the result of this method is immediately outdated. If this
      * method indicates the file exists then there is no guarantee that a
-     * subsequence access will succeed. Care should be taken when using this
+     * subsequent access will succeed. Care should be taken when using this
      * method in security sensitive applications.
      *
      * @param   path
@@ -2458,7 +2458,7 @@
      * or not then both methods return {@code false}. As with the {@code exists}
      * method, the result of this method is immediately outdated. If this
      * method indicates the file does exist then there is no guarantee that a
-     * subsequence attempt to create the file will succeed. Care should be taken
+     * subsequent attempt to create the file will succeed. Care should be taken
      * when using this method in security sensitive applications.
      *
      * @param   path
@@ -3301,7 +3301,7 @@
     }
 
     /**
-     * Writes bytes to a file. The {@code options} parameter specifies how the
+     * Writes bytes to a file. The {@code options} parameter specifies how
      * the file is created or opened. If no options are present then this method
      * works as if the {@link StandardOpenOption#CREATE CREATE}, {@link
      * StandardOpenOption#TRUNCATE_EXISTING TRUNCATE_EXISTING}, and {@link
--- a/src/java.base/share/classes/java/security/KeyPairGenerator.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/java/security/KeyPairGenerator.java	Wed Nov 08 16:03:35 2017 -0500
@@ -84,7 +84,7 @@
  * exists (e.g., so-called <i>community parameters</i> in DSA), there are two
  * {@link #initialize(java.security.spec.AlgorithmParameterSpec)
  * initialize} methods that have an {@code AlgorithmParameterSpec}
- * argument. One also has a {@code SecureRandom} argument, while the
+ * argument. One also has a {@code SecureRandom} argument, while
  * the other uses the {@code SecureRandom}
  * implementation of the highest-priority installed provider as the source
  * of randomness. (If none of the installed providers supply an implementation
--- a/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java	Wed Nov 08 16:03:35 2017 -0500
@@ -4775,7 +4775,7 @@
     //-----------------------------------------------------------------------
     /**
      * Prints or parses a localized pattern from a localized field.
-     * The specific formatter and parameters is not selected until the
+     * The specific formatter and parameters is not selected until
      * the field is to be printed or parsed.
      * The locale is needed to select the proper WeekFields from which
      * the field for day-of-week, week-of-month, or week-of-year is selected.
--- a/src/java.base/share/classes/java/time/temporal/WeekFields.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/java/time/temporal/WeekFields.java	Wed Nov 08 16:03:35 2017 -0500
@@ -311,7 +311,7 @@
      * the new month or year.
      * <p>
      * WeekFields instances are singletons; for each unique combination
-     * of {@code firstDayOfWeek} and {@code minimalDaysInFirstWeek} the
+     * of {@code firstDayOfWeek} and {@code minimalDaysInFirstWeek}
      * the same instance will be returned.
      *
      * @param firstDayOfWeek  the first day of the week, not null
--- a/src/java.base/share/classes/java/util/Base64.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/java/util/Base64.java	Wed Nov 08 16:03:35 2017 -0500
@@ -56,7 +56,7 @@
  *     base64 alphabet.</p></li>
  *
  * <li><a id="mime"><b>MIME</b></a>
- * <p> Uses the "The Base64 Alphabet" as specified in Table 1 of
+ * <p> Uses "The Base64 Alphabet" as specified in Table 1 of
  *     RFC 2045 for encoding and decoding operation. The encoded output
  *     must be represented in lines of no more than 76 characters each
  *     and uses a carriage return {@code '\r'} followed immediately by
--- a/src/java.base/share/classes/java/util/DoubleSummaryStatistics.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/java/util/DoubleSummaryStatistics.java	Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
 
 import java.util.function.DoubleConsumer;
 import java.util.stream.Collector;
+import java.util.stream.DoubleStream;
 
 /**
  * A state object for collecting statistics such as count, min, max, sum, and
@@ -69,13 +70,66 @@
     private double max = Double.NEGATIVE_INFINITY;
 
     /**
-     * Construct an empty instance with zero count, zero sum,
+     * Constructs an empty instance with zero count, zero sum,
      * {@code Double.POSITIVE_INFINITY} min, {@code Double.NEGATIVE_INFINITY}
      * max and zero average.
      */
     public DoubleSummaryStatistics() { }
 
     /**
+     * Constructs a non-empty instance with the specified {@code count},
+     * {@code min}, {@code max}, and {@code sum}.
+     *
+     * <p>If {@code count} is zero then the remaining arguments are ignored and
+     * an empty instance is constructed.
+     *
+     * <p>If the arguments are inconsistent then an {@code IllegalArgumentException}
+     * is thrown.  The necessary consistent argument conditions are:
+     * <ul>
+     *   <li>{@code count >= 0}</li>
+     *   <li>{@code (min <= max && !isNaN(sum)) || (isNaN(min) && isNaN(max) && isNaN(sum))}</li>
+     * </ul>
+     * @apiNote
+     * The enforcement of argument correctness means that the retrieved set of
+     * recorded values obtained from a {@code DoubleSummaryStatistics} source
+     * instance may not be a legal set of arguments for this constructor due to
+     * arithmetic overflow of the source's recorded count of values.
+     * The consistent argument conditions are not sufficient to prevent the
+     * creation of an internally inconsistent instance.  An example of such a
+     * state would be an instance with: {@code count} = 2, {@code min} = 1,
+     * {@code max} = 2, and {@code sum} = 0.
+     *
+     * @param count the count of values
+     * @param min the minimum value
+     * @param max the maximum value
+     * @param sum the sum of all values
+     * @throws IllegalArgumentException if the arguments are inconsistent
+     * @since 10
+     */
+    public DoubleSummaryStatistics(long count, double min, double max, double sum)
+            throws IllegalArgumentException {
+        if (count < 0L) {
+            throw new IllegalArgumentException("Negative count value");
+        } else if (count > 0L) {
+            if (min > max)
+                throw new IllegalArgumentException("Minimum greater than maximum");
+
+            // All NaN or non NaN
+            var ncount = DoubleStream.of(min, max, sum).filter(Double::isNaN).count();
+            if (ncount > 0 && ncount < 3)
+                throw new IllegalArgumentException("Some, not all, of the minimum, maximum, or sum is NaN");
+
+            this.count = count;
+            this.sum = sum;
+            this.simpleSum = sum;
+            this.sumCompensation = 0.0d;
+            this.min = min;
+            this.max = max;
+        }
+        // Use default field values if count == 0
+    }
+
+    /**
      * Records another value into the summary information.
      *
      * @param value the input value
--- a/src/java.base/share/classes/java/util/EventObject.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/java/util/EventObject.java	Wed Nov 08 16:03:35 2017 -0500
@@ -43,13 +43,13 @@
     /**
      * The object on which the Event initially occurred.
      */
-    protected transient Object  source;
+    protected transient Object source;
 
     /**
      * Constructs a prototypical Event.
      *
-     * @param    source    The object on which the Event initially occurred.
-     * @exception  IllegalArgumentException  if source is null.
+     * @param source the object on which the Event initially occurred
+     * @throws IllegalArgumentException if source is null
      */
     public EventObject(Object source) {
         if (source == null)
@@ -61,7 +61,7 @@
     /**
      * The object on which the Event initially occurred.
      *
-     * @return   The object on which the Event initially occurred.
+     * @return the object on which the Event initially occurred
      */
     public Object getSource() {
         return source;
@@ -70,7 +70,7 @@
     /**
      * Returns a String representation of this EventObject.
      *
-     * @return  A a String representation of this EventObject.
+     * @return a String representation of this EventObject
      */
     public String toString() {
         return getClass().getName() + "[source=" + source + "]";
--- a/src/java.base/share/classes/java/util/FormattableFlags.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/java/util/FormattableFlags.java	Wed Nov 08 16:03:35 2017 -0500
@@ -26,7 +26,7 @@
 package java.util;
 
 /**
- * FomattableFlags are passed to the {@link Formattable#formatTo
+ * FormattableFlags are passed to the {@link Formattable#formatTo
  * Formattable.formatTo()} method and modify the output format for {@linkplain
  * Formattable Formattables}.  Implementations of {@link Formattable} are
  * responsible for interpreting and validating any flags.
--- a/src/java.base/share/classes/java/util/IntSummaryStatistics.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/java/util/IntSummaryStatistics.java	Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -69,13 +69,58 @@
     private int max = Integer.MIN_VALUE;
 
     /**
-     * Construct an empty instance with zero count, zero sum,
+     * Constructs an empty instance with zero count, zero sum,
      * {@code Integer.MAX_VALUE} min, {@code Integer.MIN_VALUE} max and zero
      * average.
      */
     public IntSummaryStatistics() { }
 
     /**
+     * Constructs a non-empty instance with the specified {@code count},
+     * {@code min}, {@code max}, and {@code sum}.
+     *
+     * <p>If {@code count} is zero then the remaining arguments are ignored and
+     * an empty instance is constructed.
+     *
+     * <p>If the arguments are inconsistent then an {@code IllegalArgumentException}
+     * is thrown.  The necessary consistent argument conditions are:
+     * <ul>
+     *   <li>{@code count >= 0}</li>
+     *   <li>{@code min <= max}</li>
+     * </ul>
+     * @apiNote
+     * The enforcement of argument correctness means that the retrieved set of
+     * recorded values obtained from a {@code IntSummaryStatistics} source
+     * instance may not be a legal set of arguments for this constructor due to
+     * arithmetic overflow of the source's recorded count of values.
+     * The consistent argument conditions are not sufficient to prevent the
+     * creation of an internally inconsistent instance.  An example of such a
+     * state would be an instance with: {@code count} = 2, {@code min} = 1,
+     * {@code max} = 2, and {@code sum} = 0.
+     *
+     * @param count the count of values
+     * @param min the minimum value
+     * @param max the maximum value
+     * @param sum the sum of all values
+     * @throws IllegalArgumentException if the arguments are inconsistent
+     * @since 10
+     */
+    public IntSummaryStatistics(long count, int min, int max, long sum)
+            throws IllegalArgumentException {
+        if (count < 0L) {
+            throw new IllegalArgumentException("Negative count value");
+        } else if (count > 0L) {
+            if (min > max) throw new IllegalArgumentException("Minimum greater than maximum");
+
+            this.count = count;
+            this.sum = sum;
+            this.min = min;
+            this.max = max;
+        }
+        // Use default field values if count == 0
+    }
+
+    /**
      * Records a new value into the summary information
      *
      * @param value the input value
--- a/src/java.base/share/classes/java/util/LongSummaryStatistics.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/java/util/LongSummaryStatistics.java	Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -70,13 +70,58 @@
     private long max = Long.MIN_VALUE;
 
     /**
-     * Construct an empty instance with zero count, zero sum,
+     * Constructs an empty instance with zero count, zero sum,
      * {@code Long.MAX_VALUE} min, {@code Long.MIN_VALUE} max and zero
      * average.
      */
     public LongSummaryStatistics() { }
 
     /**
+     * Constructs a non-empty instance with the specified {@code count},
+     * {@code min}, {@code max}, and {@code sum}.
+     *
+     * <p>If {@code count} is zero then the remaining arguments are ignored and
+     * an empty instance is constructed.
+     *
+     * <p>If the arguments are inconsistent then an {@code IllegalArgumentException}
+     * is thrown.  The necessary consistent argument conditions are:
+     * <ul>
+     *   <li>{@code count >= 0}</li>
+     *   <li>{@code min <= max}</li>
+     * </ul>
+     * @apiNote
+     * The enforcement of argument correctness means that the retrieved set of
+     * recorded values obtained from a {@code LongSummaryStatistics} source
+     * instance may not be a legal set of arguments for this constructor due to
+     * arithmetic overflow of the source's recorded count of values.
+     * The consistent argument conditions are not sufficient to prevent the
+     * creation of an internally inconsistent instance.  An example of such a
+     * state would be an instance with: {@code count} = 2, {@code min} = 1,
+     * {@code max} = 2, and {@code sum} = 0.
+     *
+     * @param count the count of values
+     * @param min the minimum value
+     * @param max the maximum value
+     * @param sum the sum of all values
+     * @throws IllegalArgumentException if the arguments are inconsistent
+     * @since 10
+     */
+    public LongSummaryStatistics(long count, long min, long max, long sum)
+            throws IllegalArgumentException {
+        if (count < 0L) {
+            throw new IllegalArgumentException("Negative count value");
+        } else if (count > 0L) {
+            if (min > max) throw new IllegalArgumentException("Minimum greater than maximum");
+
+            this.count = count;
+            this.sum = sum;
+            this.min = min;
+            this.max = max;
+        }
+        // Use default field values if count == 0
+    }
+
+    /**
      * Records a new {@code int} value into the summary information.
      *
      * @param value the input value
--- a/src/java.base/share/classes/java/util/Properties.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/java/util/Properties.java	Wed Nov 08 16:03:35 2017 -0500
@@ -122,6 +122,10 @@
  * <p>This class is thread-safe: multiple threads can share a single
  * {@code Properties} object without the need for external synchronization.
  *
+ * @apiNote
+ * The {@code Properties} class does not inherit the concept of a load factor
+ * from its superclass, {@code Hashtable}.
+ *
  * @author  Arthur van Hoff
  * @author  Michael McCloskey
  * @author  Xueming Shen
@@ -148,25 +152,49 @@
      * simple read operations.  Writes and bulk operations remain synchronized,
      * as in Hashtable.
      */
-    private transient ConcurrentHashMap<Object, Object> map =
-            new ConcurrentHashMap<>(8);
+    private transient ConcurrentHashMap<Object, Object> map;
 
     /**
      * Creates an empty property list with no default values.
+     *
+     * @implNote The initial capacity of a {@code Properties} object created
+     * with this constructor is unspecified.
      */
     public Properties() {
-        this(null);
+        this(null, 8);
+    }
+
+    /**
+     * Creates an empty property list with no default values, and with an
+     * initial size accommodating the specified number of elements without the
+     * need to dynamically resize.
+     *
+     * @param  initialCapacity the {@code Properties} will be sized to
+     *         accommodate this many elements
+     * @throws IllegalArgumentException if the initial capacity is less than
+     *         zero.
+     */
+    public Properties(int initialCapacity) {
+        this(null, initialCapacity);
     }
 
     /**
      * Creates an empty property list with the specified defaults.
      *
+     * @implNote The initial capacity of a {@code Properties} object created
+     * with this constructor is unspecified.
+     *
      * @param   defaults   the defaults.
      */
     public Properties(Properties defaults) {
+        this(defaults, 8);
+    }
+
+    private Properties(Properties defaults, int initialCapacity) {
         // use package-private constructor to
         // initialize unused fields with dummy values
         super((Void) null);
+        map = new ConcurrentHashMap<>(initialCapacity);
         this.defaults = defaults;
     }
 
--- a/src/java.base/share/classes/java/util/ResourceBundle.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/java/util/ResourceBundle.java	Wed Nov 08 16:03:35 2017 -0500
@@ -2743,7 +2743,7 @@
          * of multiple subtags separated by underscore, generate candidate
          * <code>Locale</code>s by omitting the variant subtags one by one, then
          * insert them after every occurrence of <code> Locale</code>s with the
-         * full variant value in the original list.  For example, if the
+         * full variant value in the original list.  For example, if
          * the variant consists of two subtags <em>V1</em> and <em>V2</em>:
          *
          * <ul>
--- a/src/java.base/share/classes/jdk/internal/logger/BootstrapLogger.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/logger/BootstrapLogger.java	Wed Nov 08 16:03:35 2017 -0500
@@ -238,7 +238,7 @@
     // This way we could simply do things like:
     //    push((logger) -> logger.log(level, msg));
     // Unfortunately, if we come to here it means we are in the bootsraping
-    // phase where using lambdas is not safe yet - so we have to use a
+    // phase where using lambdas is not safe yet - so we have to use
     // a data object instead...
     //
     static final class LogEvent {
--- a/src/java.base/share/classes/jdk/internal/module/ClassFileAttributes.java	Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,765 +0,0 @@
-/*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package jdk.internal.module;
-
-import java.lang.module.ModuleDescriptor;
-import java.lang.module.ModuleDescriptor.Builder;
-import java.lang.module.ModuleDescriptor.Requires;
-import java.lang.module.ModuleDescriptor.Exports;
-import java.lang.module.ModuleDescriptor.Opens;
-import java.lang.module.ModuleDescriptor.Provides;
-import java.lang.module.ModuleDescriptor.Version;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import jdk.internal.misc.JavaLangModuleAccess;
-import jdk.internal.misc.SharedSecrets;
-import jdk.internal.org.objectweb.asm.Attribute;
-import jdk.internal.org.objectweb.asm.ByteVector;
-import jdk.internal.org.objectweb.asm.ClassReader;
-import jdk.internal.org.objectweb.asm.ClassWriter;
-import jdk.internal.org.objectweb.asm.Label;
-import static jdk.internal.module.ClassFileConstants.*;
-
-
-/**
- * Provides ASM implementations of {@code Attribute} to read and write the
- * class file attributes in a module-info class file.
- */
-
-public final class ClassFileAttributes {
-
-    private ClassFileAttributes() { }
-
-    /**
-     * Module_attribute {
-     *   // See lang-vm.html for details.
-     * }
-     */
-    public static class ModuleAttribute extends Attribute {
-        private static final JavaLangModuleAccess JLMA
-            = SharedSecrets.getJavaLangModuleAccess();
-
-        private ModuleDescriptor descriptor;
-        private Version replacementVersion;
-
-        public ModuleAttribute(ModuleDescriptor descriptor) {
-            super(MODULE);
-            this.descriptor = descriptor;
-        }
-
-        public ModuleAttribute(Version v) {
-            super(MODULE);
-            this.replacementVersion = v;
-        }
-
-        public ModuleAttribute() {
-            super(MODULE);
-        }
-
-        @Override
-        protected Attribute read(ClassReader cr,
-                                 int off,
-                                 int len,
-                                 char[] buf,
-                                 int codeOff,
-                                 Label[] labels)
-        {
-            // module_name (CONSTANT_Module_info)
-            String mn = cr.readModule(off, buf);
-            off += 2;
-
-            // module_flags
-            int module_flags = cr.readUnsignedShort(off);
-            off += 2;
-
-            Set<ModuleDescriptor.Modifier> modifiers = new HashSet<>();
-            if ((module_flags & ACC_OPEN) != 0)
-                modifiers.add(ModuleDescriptor.Modifier.OPEN);
-            if ((module_flags & ACC_SYNTHETIC) != 0)
-                modifiers.add(ModuleDescriptor.Modifier.SYNTHETIC);
-            if ((module_flags & ACC_MANDATED) != 0)
-                modifiers.add(ModuleDescriptor.Modifier.MANDATED);
-
-            Builder builder = JLMA.newModuleBuilder(mn, false, modifiers);
-
-            // module_version
-            String module_version = cr.readUTF8(off, buf);
-            off += 2;
-            if (replacementVersion != null) {
-                builder.version(replacementVersion);
-            } else if (module_version != null) {
-                builder.version(module_version);
-            }
-
-            // requires_count and requires[requires_count]
-            int requires_count = cr.readUnsignedShort(off);
-            off += 2;
-            for (int i=0; i<requires_count; i++) {
-                // CONSTANT_Module_info
-                String dn = cr.readModule(off, buf);
-                off += 2;
-
-                // requires_flags
-                int requires_flags = cr.readUnsignedShort(off);
-                off += 2;
-                Set<Requires.Modifier> mods;
-                if (requires_flags == 0) {
-                    mods = Collections.emptySet();
-                } else {
-                    mods = new HashSet<>();
-                    if ((requires_flags & ACC_TRANSITIVE) != 0)
-                        mods.add(Requires.Modifier.TRANSITIVE);
-                    if ((requires_flags & ACC_STATIC_PHASE) != 0)
-                        mods.add(Requires.Modifier.STATIC);
-                    if ((requires_flags & ACC_SYNTHETIC) != 0)
-                        mods.add(Requires.Modifier.SYNTHETIC);
-                    if ((requires_flags & ACC_MANDATED) != 0)
-                        mods.add(Requires.Modifier.MANDATED);
-                }
-
-                // requires_version
-                String requires_version = cr.readUTF8(off, buf);
-                off += 2;
-                if (requires_version == null) {
-                    builder.requires(mods, dn);
-                } else {
-                    JLMA.requires(builder, mods, dn, requires_version);
-                }
-            }
-
-            // exports_count and exports[exports_count]
-            int exports_count = cr.readUnsignedShort(off);
-            off += 2;
-            if (exports_count > 0) {
-                for (int i=0; i<exports_count; i++) {
-                    // CONSTANT_Package_info
-                    String pkg = cr.readPackage(off, buf).replace('/', '.');
-                    off += 2;
-
-                    int exports_flags = cr.readUnsignedShort(off);
-                    off += 2;
-                    Set<Exports.Modifier> mods;
-                    if (exports_flags == 0) {
-                        mods = Collections.emptySet();
-                    } else {
-                        mods = new HashSet<>();
-                        if ((exports_flags & ACC_SYNTHETIC) != 0)
-                            mods.add(Exports.Modifier.SYNTHETIC);
-                        if ((exports_flags & ACC_MANDATED) != 0)
-                            mods.add(Exports.Modifier.MANDATED);
-                    }
-
-                    int exports_to_count = cr.readUnsignedShort(off);
-                    off += 2;
-                    if (exports_to_count > 0) {
-                        Set<String> targets = new HashSet<>();
-                        for (int j=0; j<exports_to_count; j++) {
-                            String t = cr.readModule(off, buf);
-                            off += 2;
-                            targets.add(t);
-                        }
-                        builder.exports(mods, pkg, targets);
-                    } else {
-                        builder.exports(mods, pkg);
-                    }
-                }
-            }
-
-            // opens_count and opens[opens_count]
-            int open_count = cr.readUnsignedShort(off);
-            off += 2;
-            if (open_count > 0) {
-                for (int i=0; i<open_count; i++) {
-                    // CONSTANT_Package_info
-                    String pkg = cr.readPackage(off, buf).replace('/', '.');
-                    off += 2;
-
-                    int opens_flags = cr.readUnsignedShort(off);
-                    off += 2;
-                    Set<Opens.Modifier> mods;
-                    if (opens_flags == 0) {
-                        mods = Collections.emptySet();
-                    } else {
-                        mods = new HashSet<>();
-                        if ((opens_flags & ACC_SYNTHETIC) != 0)
-                            mods.add(Opens.Modifier.SYNTHETIC);
-                        if ((opens_flags & ACC_MANDATED) != 0)
-                            mods.add(Opens.Modifier.MANDATED);
-                    }
-
-                    int opens_to_count = cr.readUnsignedShort(off);
-                    off += 2;
-                    if (opens_to_count > 0) {
-                        Set<String> targets = new HashSet<>();
-                        for (int j=0; j<opens_to_count; j++) {
-                            String t = cr.readModule(off, buf);
-                            off += 2;
-                            targets.add(t);
-                        }
-                        builder.opens(mods, pkg, targets);
-                    } else {
-                        builder.opens(mods, pkg);
-                    }
-                }
-            }
-
-            // uses_count and uses_index[uses_count]
-            int uses_count = cr.readUnsignedShort(off);
-            off += 2;
-            if (uses_count > 0) {
-                for (int i=0; i<uses_count; i++) {
-                    String sn = cr.readClass(off, buf).replace('/', '.');
-                    builder.uses(sn);
-                    off += 2;
-                }
-            }
-
-            // provides_count and provides[provides_count]
-            int provides_count = cr.readUnsignedShort(off);
-            off += 2;
-            if (provides_count > 0) {
-                for (int i=0; i<provides_count; i++) {
-                    String service = cr.readClass(off, buf).replace('/', '.');
-                    off += 2;
-                    int with_count = cr.readUnsignedShort(off);
-                    off += 2;
-                    List<String> providers = new ArrayList<>();
-                    for (int j=0; j<with_count; j++) {
-                        String cn = cr.readClass(off, buf).replace('/', '.');
-                        off += 2;
-                        providers.add(cn);
-                    }
-                    builder.provides(service, providers);
-                }
-            }
-
-            return new ModuleAttribute(builder.build());
-        }
-
-        @Override
-        protected ByteVector write(ClassWriter cw,
-                                   byte[] code,
-                                   int len,
-                                   int maxStack,
-                                   int maxLocals)
-        {
-            assert descriptor != null;
-            ByteVector attr = new ByteVector();
-
-            // module_name
-            String mn = descriptor.name();
-            int module_name_index = cw.newModule(mn);
-            attr.putShort(module_name_index);
-
-            // module_flags
-            Set<ModuleDescriptor.Modifier> modifiers = descriptor.modifiers();
-            int module_flags = 0;
-            if (modifiers.contains(ModuleDescriptor.Modifier.OPEN))
-                module_flags |= ACC_OPEN;
-            if (modifiers.contains(ModuleDescriptor.Modifier.SYNTHETIC))
-                module_flags |= ACC_SYNTHETIC;
-            if (modifiers.contains(ModuleDescriptor.Modifier.MANDATED))
-                module_flags |= ACC_MANDATED;
-            attr.putShort(module_flags);
-
-            // module_version
-            String vs = descriptor.rawVersion().orElse(null);
-            if (vs == null) {
-                attr.putShort(0);
-            } else {
-                int module_version_index = cw.newUTF8(vs);
-                attr.putShort(module_version_index);
-            }
-
-            // requires_count
-            attr.putShort(descriptor.requires().size());
-
-            // requires[requires_count]
-            for (Requires r : descriptor.requires()) {
-                int requires_index = cw.newModule(r.name());
-                attr.putShort(requires_index);
-
-                int requires_flags = 0;
-                if (r.modifiers().contains(Requires.Modifier.TRANSITIVE))
-                    requires_flags |= ACC_TRANSITIVE;
-                if (r.modifiers().contains(Requires.Modifier.STATIC))
-                    requires_flags |= ACC_STATIC_PHASE;
-                if (r.modifiers().contains(Requires.Modifier.SYNTHETIC))
-                    requires_flags |= ACC_SYNTHETIC;
-                if (r.modifiers().contains(Requires.Modifier.MANDATED))
-                    requires_flags |= ACC_MANDATED;
-                attr.putShort(requires_flags);
-
-                int requires_version_index;
-                vs = r.rawCompiledVersion().orElse(null);
-                if (vs == null) {
-                    requires_version_index = 0;
-                } else {
-                    requires_version_index = cw.newUTF8(vs);
-                }
-                attr.putShort(requires_version_index);
-            }
-
-            // exports_count and exports[exports_count];
-            attr.putShort(descriptor.exports().size());
-            for (Exports e : descriptor.exports()) {
-                String pkg = e.source().replace('.', '/');
-                attr.putShort(cw.newPackage(pkg));
-
-                int exports_flags = 0;
-                if (e.modifiers().contains(Exports.Modifier.SYNTHETIC))
-                    exports_flags |= ACC_SYNTHETIC;
-                if (e.modifiers().contains(Exports.Modifier.MANDATED))
-                    exports_flags |= ACC_MANDATED;
-                attr.putShort(exports_flags);
-
-                if (e.isQualified()) {
-                    Set<String> ts = e.targets();
-                    attr.putShort(ts.size());
-                    ts.forEach(target -> attr.putShort(cw.newModule(target)));
-                } else {
-                    attr.putShort(0);
-                }
-            }
-
-            // opens_counts and opens[opens_counts]
-            attr.putShort(descriptor.opens().size());
-            for (Opens obj : descriptor.opens()) {
-                String pkg = obj.source().replace('.', '/');
-                attr.putShort(cw.newPackage(pkg));
-
-                int opens_flags = 0;
-                if (obj.modifiers().contains(Opens.Modifier.SYNTHETIC))
-                    opens_flags |= ACC_SYNTHETIC;
-                if (obj.modifiers().contains(Opens.Modifier.MANDATED))
-                    opens_flags |= ACC_MANDATED;
-                attr.putShort(opens_flags);
-
-                if (obj.isQualified()) {
-                    Set<String> ts = obj.targets();
-                    attr.putShort(ts.size());
-                    ts.forEach(target -> attr.putShort(cw.newModule(target)));
-                } else {
-                    attr.putShort(0);
-                }
-            }
-
-            // uses_count and uses_index[uses_count]
-            if (descriptor.uses().isEmpty()) {
-                attr.putShort(0);
-            } else {
-                attr.putShort(descriptor.uses().size());
-                for (String s : descriptor.uses()) {
-                    String service = s.replace('.', '/');
-                    int index = cw.newClass(service);
-                    attr.putShort(index);
-                }
-            }
-
-            // provides_count and provides[provides_count]
-            if (descriptor.provides().isEmpty()) {
-                attr.putShort(0);
-            } else {
-                attr.putShort(descriptor.provides().size());
-                for (Provides p : descriptor.provides()) {
-                    String service = p.service().replace('.', '/');
-                    attr.putShort(cw.newClass(service));
-                    int with_count = p.providers().size();
-                    attr.putShort(with_count);
-                    for (String provider : p.providers()) {
-                        attr.putShort(cw.newClass(provider.replace('.', '/')));
-                    }
-                }
-            }
-
-            return attr;
-        }
-    }
-
-    /**
-     * ModulePackages attribute.
-     *
-     * <pre> {@code
-     *
-     * ModulePackages_attribute {
-     *   // index to CONSTANT_utf8_info structure in constant pool representing
-     *   // the string "ModulePackages"
-     *   u2 attribute_name_index;
-     *   u4 attribute_length;
-     *
-     *   // the number of entries in the packages table
-     *   u2 packages_count;
-     *   { // index to CONSTANT_Package_info structure with the package name
-     *     u2 package_index
-     *   } packages[package_count];
-     *
-     * }</pre>
-     */
-    public static class ModulePackagesAttribute extends Attribute {
-        private final Set<String> packages;
-
-        public ModulePackagesAttribute(Set<String> packages) {
-            super(MODULE_PACKAGES);
-            this.packages = packages;
-        }
-
-        public ModulePackagesAttribute() {
-            this(null);
-        }
-
-        @Override
-        protected Attribute read(ClassReader cr,
-                                 int off,
-                                 int len,
-                                 char[] buf,
-                                 int codeOff,
-                                 Label[] labels)
-        {
-            // package count
-            int package_count = cr.readUnsignedShort(off);
-            off += 2;
-
-            // packages
-            Set<String> packages = new HashSet<>();
-            for (int i=0; i<package_count; i++) {
-                String pkg = cr.readPackage(off, buf).replace('/', '.');
-                packages.add(pkg);
-                off += 2;
-            }
-
-            return new ModulePackagesAttribute(packages);
-        }
-
-        @Override
-        protected ByteVector write(ClassWriter cw,
-                                   byte[] code,
-                                   int len,
-                                   int maxStack,
-                                   int maxLocals)
-        {
-            assert packages != null;
-
-            ByteVector attr = new ByteVector();
-
-            // package_count
-            attr.putShort(packages.size());
-
-            // packages
-            packages.stream()
-                .map(p -> p.replace('.', '/'))
-                .forEach(p -> attr.putShort(cw.newPackage(p)));
-
-            return attr;
-        }
-
-    }
-
-    /**
-     * ModuleMainClass attribute.
-     *
-     * <pre> {@code
-     *
-     * MainClass_attribute {
-     *   // index to CONSTANT_utf8_info structure in constant pool representing
-     *   // the string "ModuleMainClass"
-     *   u2 attribute_name_index;
-     *   u4 attribute_length;
-     *
-     *   // index to CONSTANT_Class_info structure with the main class name
-     *   u2 main_class_index;
-     * }
-     *
-     * } </pre>
-     */
-    public static class ModuleMainClassAttribute extends Attribute {
-        private final String mainClass;
-
-        public ModuleMainClassAttribute(String mainClass) {
-            super(MODULE_MAIN_CLASS);
-            this.mainClass = mainClass;
-        }
-
-        public ModuleMainClassAttribute() {
-            this(null);
-        }
-
-        @Override
-        protected Attribute read(ClassReader cr,
-                                 int off,
-                                 int len,
-                                 char[] buf,
-                                 int codeOff,
-                                 Label[] labels)
-        {
-            String value = cr.readClass(off, buf).replace('/', '.');
-            return new ModuleMainClassAttribute(value);
-        }
-
-        @Override
-        protected ByteVector write(ClassWriter cw,
-                                   byte[] code,
-                                   int len,
-                                   int maxStack,
-                                   int maxLocals)
-        {
-            ByteVector attr = new ByteVector();
-            int index = cw.newClass(mainClass.replace('.', '/'));
-            attr.putShort(index);
-            return attr;
-        }
-    }
-
-    /**
-     * ModuleTarget attribute.
-     *
-     * <pre> {@code
-     *
-     * TargetPlatform_attribute {
-     *   // index to CONSTANT_utf8_info structure in constant pool representing
-     *   // the string "ModuleTarget"
-     *   u2 attribute_name_index;
-     *   u4 attribute_length;
-     *
-     *   // index to CONSTANT_utf8_info structure with the target platform
-     *   u2 target_platform_index;
-     * }
-     *
-     * } </pre>
-     */
-    public static class ModuleTargetAttribute extends Attribute {
-        private final String targetPlatform;
-
-        public ModuleTargetAttribute(String targetPlatform) {
-            super(MODULE_TARGET);
-            this.targetPlatform = targetPlatform;
-        }
-
-        public ModuleTargetAttribute() {
-            this(null);
-        }
-
-        public String targetPlatform() {
-            return targetPlatform;
-        }
-
-        @Override
-        protected Attribute read(ClassReader cr,
-                                 int off,
-                                 int len,
-                                 char[] buf,
-                                 int codeOff,
-                                 Label[] labels)
-        {
-
-            String targetPlatform = null;
-
-            int target_platform_index = cr.readUnsignedShort(off);
-            if (target_platform_index != 0)
-                targetPlatform = cr.readUTF8(off, buf);
-            off += 2;
-
-            return new ModuleTargetAttribute(targetPlatform);
-        }
-
-        @Override
-        protected ByteVector write(ClassWriter cw,
-                                   byte[] code,
-                                   int len,
-                                   int maxStack,
-                                   int maxLocals)
-        {
-            ByteVector attr = new ByteVector();
-
-            int target_platform_index = 0;
-            if (targetPlatform != null && targetPlatform.length() > 0)
-                target_platform_index = cw.newUTF8(targetPlatform);
-            attr.putShort(target_platform_index);
-
-            return attr;
-        }
-    }
-
-    /**
-     * ModuleHashes attribute.
-     *
-     * <pre> {@code
-     *
-     * ModuleHashes_attribute {
-     *   // index to CONSTANT_utf8_info structure in constant pool representing
-     *   // the string "ModuleHashes"
-     *   u2 attribute_name_index;
-     *   u4 attribute_length;
-     *
-     *   // index to CONSTANT_utf8_info structure with algorithm name
-     *   u2 algorithm_index;
-     *
-     *   // the number of entries in the hashes table
-     *   u2 hashes_count;
-     *   {   u2 module_name_index (index to CONSTANT_Module_info structure)
-     *       u2 hash_length;
-     *       u1 hash[hash_length];
-     *   } hashes[hashes_count];
-     *
-     * } </pre>
-     */
-    static class ModuleHashesAttribute extends Attribute {
-        private final ModuleHashes hashes;
-
-        ModuleHashesAttribute(ModuleHashes hashes) {
-            super(MODULE_HASHES);
-            this.hashes = hashes;
-        }
-
-        ModuleHashesAttribute() {
-            this(null);
-        }
-
-        @Override
-        protected Attribute read(ClassReader cr,
-                                 int off,
-                                 int len,
-                                 char[] buf,
-                                 int codeOff,
-                                 Label[] labels)
-        {
-            String algorithm = cr.readUTF8(off, buf);
-            off += 2;
-
-            int hashes_count = cr.readUnsignedShort(off);
-            off += 2;
-
-            Map<String, byte[]> map = new HashMap<>();
-            for (int i=0; i<hashes_count; i++) {
-                String mn = cr.readModule(off, buf);
-                off += 2;
-
-                int hash_length = cr.readUnsignedShort(off);
-                off += 2;
-                byte[] hash = new byte[hash_length];
-                for (int j=0; j<hash_length; j++) {
-                    hash[j] = (byte) (0xff & cr.readByte(off+j));
-                }
-                off += hash_length;
-
-                map.put(mn, hash);
-            }
-
-            ModuleHashes hashes = new ModuleHashes(algorithm, map);
-
-            return new ModuleHashesAttribute(hashes);
-        }
-
-        @Override
-        protected ByteVector write(ClassWriter cw,
-                                   byte[] code,
-                                   int len,
-                                   int maxStack,
-                                   int maxLocals)
-        {
-            ByteVector attr = new ByteVector();
-
-            int index = cw.newUTF8(hashes.algorithm());
-            attr.putShort(index);
-
-            Set<String> names = hashes.names();
-            attr.putShort(names.size());
-
-            for (String mn : names) {
-                byte[] hash = hashes.hashFor(mn);
-                assert hash != null;
-                attr.putShort(cw.newModule(mn));
-
-                attr.putShort(hash.length);
-                for (byte b: hash) {
-                    attr.putByte(b);
-                }
-            }
-
-            return attr;
-        }
-    }
-
-    /**
-     *  ModuleResolution_attribute {
-     *    u2 attribute_name_index;    // "ModuleResolution"
-     *    u4 attribute_length;        // 2
-     *    u2 resolution_flags;
-     *
-     *  The value of the resolution_flags item is a mask of flags used to denote
-     *  properties of module resolution. The flags are as follows:
-     *
-     *   // Optional
-     *   0x0001 (DO_NOT_RESOLVE_BY_DEFAULT)
-     *
-     *   // At most one of:
-     *   0x0002 (WARN_DEPRECATED)
-     *   0x0004 (WARN_DEPRECATED_FOR_REMOVAL)
-     *   0x0008 (WARN_INCUBATING)
-     */
-    static class ModuleResolutionAttribute extends Attribute {
-        private final int value;
-
-        ModuleResolutionAttribute() {
-            super(MODULE_RESOLUTION);
-            value = 0;
-        }
-
-        ModuleResolutionAttribute(int value) {
-            super(MODULE_RESOLUTION);
-            this.value = value;
-        }
-
-        @Override
-        protected Attribute read(ClassReader cr,
-                                 int off,
-                                 int len,
-                                 char[] buf,
-                                 int codeOff,
-                                 Label[] labels)
-        {
-            int flags = cr.readUnsignedShort(off);
-            return new ModuleResolutionAttribute(flags);
-        }
-
-        @Override
-        protected ByteVector write(ClassWriter cw,
-                                   byte[] code,
-                                   int len,
-                                   int maxStack,
-                                   int maxLocals)
-        {
-            ByteVector attr = new ByteVector();
-            attr.putShort(value);
-            return attr;
-        }
-    }
-}
--- a/src/java.base/share/classes/jdk/internal/module/ModuleInfoExtender.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/module/ModuleInfoExtender.java	Wed Nov 08 16:03:35 2017 -0500
@@ -31,18 +31,18 @@
 import java.lang.module.ModuleDescriptor.Version;
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
 import java.util.Set;
 
 import jdk.internal.org.objectweb.asm.Attribute;
 import jdk.internal.org.objectweb.asm.ClassReader;
 import jdk.internal.org.objectweb.asm.ClassVisitor;
 import jdk.internal.org.objectweb.asm.ClassWriter;
+import jdk.internal.org.objectweb.asm.ModuleVisitor;
 import jdk.internal.org.objectweb.asm.Opcodes;
-
-import static jdk.internal.module.ClassFileAttributes.*;
+import jdk.internal.org.objectweb.asm.commons.ModuleHashesAttribute;
+import jdk.internal.org.objectweb.asm.commons.ModuleResolutionAttribute;
+import jdk.internal.org.objectweb.asm.commons.ModuleTargetAttribute;
 
 /**
  * Utility class to extend a module-info.class with additional attributes.
@@ -133,43 +133,6 @@
     }
 
     /**
-     * A ClassVisitor that supports adding class file attributes. If an
-     * attribute already exists then the first occurrence of the attribute
-     * is replaced.
-     */
-    private static class AttributeAddingClassVisitor extends ClassVisitor {
-        private Map<String, Attribute> attrs = new HashMap<>();
-
-        AttributeAddingClassVisitor(int api, ClassVisitor cv) {
-            super(api, cv);
-        }
-
-        void addAttribute(Attribute attr) {
-            attrs.put(attr.type, attr);
-        }
-
-        @Override
-        public void visitAttribute(Attribute attr) {
-            String name = attr.type;
-            Attribute replacement = attrs.get(name);
-            if (replacement != null) {
-                attr = replacement;
-                attrs.remove(name);
-            }
-            super.visitAttribute(attr);
-        }
-
-        /**
-         * Adds any remaining attributes that weren't replaced to the
-         * class file.
-         */
-        void finish() {
-            attrs.values().forEach(a -> super.visitAttribute(a));
-            attrs.clear();
-        }
-    }
-
-    /**
      * Outputs the modified module-info.class to the given output stream.
      * Once this method has been called then the Extender object should
      * be discarded.
@@ -185,38 +148,86 @@
      * be discarded.
      */
     public byte[] toByteArray() throws IOException {
-        ClassWriter cw
-            = new ClassWriter(ClassWriter.COMPUTE_MAXS + ClassWriter.COMPUTE_FRAMES);
-
-        AttributeAddingClassVisitor cv
-            = new AttributeAddingClassVisitor(Opcodes.ASM5, cw);
+        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS
+                                         + ClassWriter.COMPUTE_FRAMES);
 
         ClassReader cr = new ClassReader(in);
 
-        if (packages != null)
-            cv.addAttribute(new ModulePackagesAttribute(packages));
-        if (mainClass != null)
-            cv.addAttribute(new ModuleMainClassAttribute(mainClass));
-        if (targetPlatform != null)
-            cv.addAttribute(new ModuleTargetAttribute(targetPlatform));
-        if (hashes != null)
-            cv.addAttribute(new ModuleHashesAttribute(hashes));
-        if (moduleResolution != null)
-            cv.addAttribute(new ModuleResolutionAttribute(moduleResolution.value()));
+        ClassVisitor cv = new ClassVisitor(Opcodes.ASM6, cw) {
+            @Override
+            public ModuleVisitor visitModule(String name, int flags, String version) {
+                Version v = ModuleInfoExtender.this.version;
+                String vs = (v != null) ? v.toString() : version;
+                ModuleVisitor mv = super.visitModule(name, flags, vs);
+
+                // ModuleMainClass attribute
+                if (mainClass != null) {
+                    mv.visitMainClass(mainClass.replace('.', '/'));
+                }
+
+                // ModulePackages attribute
+                if (packages != null) {
+                    packages.forEach(pn -> mv.visitPackage(pn.replace('.', '/')));
+                }
+
+                return new ModuleVisitor(Opcodes.ASM6, mv) {
+                    public void visitMainClass(String existingMainClass) {
+                        // skip main class if there is a new value
+                        if (mainClass == null) {
+                            super.visitMainClass(existingMainClass);
+                        }
+                    }
+                    public void visitPackage(String existingPackage) {
+                        // skip packages if there is a new set of packages
+                        if (packages == null) {
+                            super.visitPackage(existingPackage);
+                        }
+                    }
+                };
+            }
+            @Override
+            public void visitAttribute(Attribute attr) {
+                String name = attr.type;
+                // drop existing attributes if there are replacements
+                if (name.equals(ClassFileConstants.MODULE_TARGET)
+                    && targetPlatform != null)
+                    return;
+                if (name.equals(ClassFileConstants.MODULE_RESOLUTION)
+                    && moduleResolution != null)
+                    return;
+                if (name.equals(ClassFileConstants.MODULE_HASHES)
+                    && hashes != null)
+                    return;
+
+                super.visitAttribute(attr);
+
+            }
+        };
 
         List<Attribute> attrs = new ArrayList<>();
-
-        // prototypes of attributes that should be parsed
-        attrs.add(new ModuleAttribute(version));
-        attrs.add(new ModulePackagesAttribute());
-        attrs.add(new ModuleMainClassAttribute());
         attrs.add(new ModuleTargetAttribute());
+        attrs.add(new ModuleResolutionAttribute());
         attrs.add(new ModuleHashesAttribute());
-
         cr.accept(cv, attrs.toArray(new Attribute[0]), 0);
 
-        // add any attributes that didn't replace previous attributes
-        cv.finish();
+        // add ModuleTarget, ModuleResolution and ModuleHashes attributes
+        if (targetPlatform != null) {
+            cw.visitAttribute(new ModuleTargetAttribute(targetPlatform));
+        }
+        if (moduleResolution != null) {
+            int flags = moduleResolution.value();
+            cw.visitAttribute(new ModuleResolutionAttribute(flags));
+        }
+        if (hashes != null) {
+            String algorithm = hashes.algorithm();
+            List<String> names = new ArrayList<>();
+            List<byte[]> values = new ArrayList<>();
+            for (String name : hashes.names()) {
+                names.add(name);
+                values.add(hashes.hashFor(name));
+            }
+            cw.visitAttribute(new ModuleHashesAttribute(algorithm, names, values));
+        }
 
         return cw.toByteArray();
     }
--- a/src/java.base/share/classes/jdk/internal/module/ModuleInfoWriter.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/module/ModuleInfoWriter.java	Wed Nov 08 16:03:35 2017 -0500
@@ -28,13 +28,14 @@
 import java.io.OutputStream;
 import java.lang.module.ModuleDescriptor;
 import java.nio.ByteBuffer;
+import java.util.Map;
 import java.util.stream.Stream;
 
 import jdk.internal.org.objectweb.asm.ClassWriter;
+import jdk.internal.org.objectweb.asm.ModuleVisitor;
 import jdk.internal.org.objectweb.asm.Opcodes;
-
-import static jdk.internal.module.ClassFileAttributes.*;
-import static jdk.internal.module.ClassFileConstants.ACC_MODULE;
+import jdk.internal.org.objectweb.asm.commons.ModuleTargetAttribute;
+import static jdk.internal.org.objectweb.asm.Opcodes.*;
 
 /**
  * Utility class to write a ModuleDescriptor as a module-info.class.
@@ -42,6 +43,35 @@
 
 public final class ModuleInfoWriter {
 
+    private static final Map<ModuleDescriptor.Modifier, Integer>
+        MODULE_MODS_TO_FLAGS = Map.of(
+            ModuleDescriptor.Modifier.OPEN, ACC_OPEN,
+            ModuleDescriptor.Modifier.SYNTHETIC, ACC_SYNTHETIC,
+            ModuleDescriptor.Modifier.MANDATED, ACC_MANDATED
+        );
+
+    private static final Map<ModuleDescriptor.Requires.Modifier, Integer>
+        REQUIRES_MODS_TO_FLAGS = Map.of(
+            ModuleDescriptor.Requires.Modifier.TRANSITIVE, ACC_TRANSITIVE,
+            ModuleDescriptor.Requires.Modifier.STATIC, ACC_STATIC_PHASE,
+            ModuleDescriptor.Requires.Modifier.SYNTHETIC, ACC_SYNTHETIC,
+            ModuleDescriptor.Requires.Modifier.MANDATED, ACC_MANDATED
+        );
+
+    private static final Map<ModuleDescriptor.Exports.Modifier, Integer>
+        EXPORTS_MODS_TO_FLAGS = Map.of(
+            ModuleDescriptor.Exports.Modifier.SYNTHETIC, ACC_SYNTHETIC,
+            ModuleDescriptor.Exports.Modifier.MANDATED, ACC_MANDATED
+        );
+
+    private static final Map<ModuleDescriptor.Opens.Modifier, Integer>
+        OPENS_MODS_TO_FLAGS = Map.of(
+            ModuleDescriptor.Opens.Modifier.SYNTHETIC, ACC_SYNTHETIC,
+            ModuleDescriptor.Opens.Modifier.MANDATED, ACC_MANDATED
+        );
+
+    private static final String[] EMPTY_STRING_ARRAY = new String[0];
+
     private ModuleInfoWriter() { }
 
     /**
@@ -50,24 +80,75 @@
      */
     private static byte[] toModuleInfo(ModuleDescriptor md, ModuleTarget target) {
         ClassWriter cw = new ClassWriter(0);
-        cw.visit(Opcodes.V1_9, ACC_MODULE, "module-info", null, null, null);
-        cw.visitAttribute(new ModuleAttribute(md));
+        cw.visit(Opcodes.V9, ACC_MODULE, "module-info", null, null, null);
+
+        int moduleFlags = md.modifiers().stream()
+                .map(MODULE_MODS_TO_FLAGS::get)
+                .reduce(0, (x, y) -> (x | y));
+        String vs = md.rawVersion().orElse(null);
+        ModuleVisitor mv = cw.visitModule(md.name(), moduleFlags, vs);
+
+        // requires
+        for (ModuleDescriptor.Requires r : md.requires()) {
+            int flags = r.modifiers().stream()
+                    .map(REQUIRES_MODS_TO_FLAGS::get)
+                    .reduce(0, (x, y) -> (x | y));
+            vs = r.rawCompiledVersion().orElse(null);
+            mv.visitRequire(r.name(), flags, vs);
+        }
 
-        // for tests: write the ModulePackages attribute when there are packages
-        // that aren't exported or open
+        // exports
+        for (ModuleDescriptor.Exports e : md.exports()) {
+            int flags = e.modifiers().stream()
+                    .map(EXPORTS_MODS_TO_FLAGS::get)
+                    .reduce(0, (x, y) -> (x | y));
+            String[] targets = e.targets().toArray(EMPTY_STRING_ARRAY);
+            mv.visitExport(e.source().replace('.', '/'), flags, targets);
+        }
+
+        // opens
+        for (ModuleDescriptor.Opens opens : md.opens()) {
+            int flags = opens.modifiers().stream()
+                    .map(OPENS_MODS_TO_FLAGS::get)
+                    .reduce(0, (x, y) -> (x | y));
+            String[] targets = opens.targets().toArray(EMPTY_STRING_ARRAY);
+            mv.visitOpen(opens.source().replace('.', '/'), flags, targets);
+        }
+
+        // uses
+        md.uses().stream().map(sn -> sn.replace('.', '/')).forEach(mv::visitUse);
+
+        // provides
+        for (ModuleDescriptor.Provides p : md.provides()) {
+            mv.visitProvide(p.service().replace('.', '/'),
+                            p.providers()
+                                .stream()
+                                .map(pn -> pn.replace('.', '/'))
+                                .toArray(String[]::new));
+        }
+
+        // add the ModulePackages attribute when there are packages that aren't
+        // exported or open
         Stream<String> exported = md.exports().stream()
                 .map(ModuleDescriptor.Exports::source);
         Stream<String> open = md.opens().stream()
                 .map(ModuleDescriptor.Opens::source);
         long exportedOrOpen = Stream.concat(exported, open).distinct().count();
-        if (md.packages().size() > exportedOrOpen)
-            cw.visitAttribute(new ModulePackagesAttribute(md.packages()));
+        if (md.packages().size() > exportedOrOpen) {
+            md.packages().stream()
+                    .map(pn -> pn.replace('.', '/'))
+                    .forEach(mv::visitPackage);
+        }
 
-        // write ModuleMainClass if the module has a main class
-        md.mainClass().ifPresent(mc -> cw.visitAttribute(new ModuleMainClassAttribute(mc)));
+        // ModuleMainClass attribute
+        md.mainClass()
+            .map(mc -> mc.replace('.', '/'))
+            .ifPresent(mv::visitMainClass);
 
-        // write ModuleTarget if there is a target platform
-        if (target != null) {
+        mv.visitEnd();
+
+        // write ModuleTarget attribute if there is a target platform
+        if (target != null && target.targetPlatform().length() > 0) {
             cw.visitAttribute(new ModuleTargetAttribute(target.targetPlatform()));
         }
 
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/AnnotationVisitor.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/AnnotationVisitor.java	Wed Nov 08 16:03:35 2017 -0500
@@ -70,7 +70,7 @@
 
     /**
      * The ASM API version implemented by this visitor. The value of this field
-     * must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     * must be one of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      */
     protected final int api;
 
@@ -85,7 +85,7 @@
      *
      * @param api
      *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      */
     public AnnotationVisitor(final int api) {
         this(api, null);
@@ -96,13 +96,13 @@
      *
      * @param api
      *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      * @param av
      *            the annotation visitor to which this visitor must delegate
      *            method calls. May be null.
      */
     public AnnotationVisitor(final int api, final AnnotationVisitor av) {
-        if (api != Opcodes.ASM4 && api != Opcodes.ASM5) {
+        if (api < Opcodes.ASM4 || api > Opcodes.ASM6) {
             throw new IllegalArgumentException();
         }
         this.api = api;
@@ -118,7 +118,7 @@
      *            the actual value, whose type must be {@link Byte},
      *            {@link Boolean}, {@link Character}, {@link Short},
      *            {@link Integer} , {@link Long}, {@link Float}, {@link Double},
-     *            {@link String} or {@link Type} or OBJECT or ARRAY sort. This
+     *            {@link String} or {@link Type} of OBJECT or ARRAY sort. This
      *            value can also be an array of byte, boolean, short, char, int,
      *            long, float or double values (this is equivalent to using
      *            {@link #visitArray visitArray} and visiting each array element
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/AnnotationWriter.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/AnnotationWriter.java	Wed Nov 08 16:03:35 2017 -0500
@@ -133,7 +133,7 @@
      */
     AnnotationWriter(final ClassWriter cw, final boolean named,
             final ByteVector bv, final ByteVector parent, final int offset) {
-        super(Opcodes.ASM5);
+        super(Opcodes.ASM6);
         this.cw = cw;
         this.named = named;
         this.bv = bv;
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ClassReader.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ClassReader.java	Wed Nov 08 16:03:35 2017 -0500
@@ -73,31 +73,6 @@
 public class ClassReader {
 
     /**
-     * True to enable signatures support.
-     */
-    static final boolean SIGNATURES = true;
-
-    /**
-     * True to enable annotations support.
-     */
-    static final boolean ANNOTATIONS = true;
-
-    /**
-     * True to enable stack map frames support.
-     */
-    static final boolean FRAMES = true;
-
-    /**
-     * True to enable bytecode writing support.
-     */
-    static final boolean WRITER = true;
-
-    /**
-     * True to enable JSR_W and GOTO_W support.
-     */
-    static final boolean RESIZE = true;
-
-    /**
      * Flag to skip method code. If this class is set <code>CODE</code>
      * attribute won't be visited. This can be used, for example, to retrieve
      * annotations for methods and method parameters.
@@ -134,6 +109,21 @@
     public static final int EXPAND_FRAMES = 8;
 
     /**
+     * Flag to expand the ASM pseudo instructions into an equivalent sequence of
+     * standard bytecode instructions. When resolving a forward jump it may
+     * happen that the signed 2 bytes offset reserved for it is not sufficient
+     * to store the bytecode offset. In this case the jump instruction is
+     * replaced with a temporary ASM pseudo instruction using an unsigned 2
+     * bytes offset (see Label#resolve). This internal flag is used to re-read
+     * classes containing such instructions, in order to replace them with
+     * standard instructions. In addition, when this flag is used, GOTO_W and
+     * JSR_W are <i>not</i> converted into GOTO and JSR, to make sure that
+     * infinite loops where a GOTO_W is replaced with a GOTO in ClassReader and
+     * converted back to a GOTO_W in ClassWriter cannot occur.
+     */
+    static final int EXPAND_ASM_INSNS = 256;
+
+    /**
      * The class to be parsed. <i>The content of this array must not be
      * modified. This field is intended for {@link Attribute} sub classes, and
      * is normally not needed by class generators or adapters.</i>
@@ -195,7 +185,7 @@
     public ClassReader(final byte[] b, final int off, final int len) {
         this.b = b;
         // checks the class version
-        if (readShort(off + 6) > Opcodes.V1_9) {
+        if (readShort(off + 6) > Opcodes.V9) {
             throw new IllegalArgumentException();
         }
         // parses the constant pool
@@ -234,6 +224,8 @@
             // case ClassWriter.CLASS:
             // case ClassWriter.STR:
             // case ClassWriter.MTYPE
+            // case ClassWriter.PACKAGE:
+            // case ClassWriter.MODULE:
             default:
                 size = 3;
                 break;
@@ -377,7 +369,9 @@
                 break;
             // case ClassWriter.STR:
             // case ClassWriter.CLASS:
-            // case ClassWriter.MTYPE
+            // case ClassWriter.MTYPE:
+            // case ClassWriter.MODULE:
+            // case ClassWriter.PACKAGE:
             default:
                 item.set(tag, readUTF8(index, buf), null, null);
                 break;
@@ -584,11 +578,14 @@
         String enclosingOwner = null;
         String enclosingName = null;
         String enclosingDesc = null;
+        String moduleMainClass = null;
         int anns = 0;
         int ianns = 0;
         int tanns = 0;
         int itanns = 0;
         int innerClasses = 0;
+        int module = 0;
+        int packages = 0;
         Attribute attributes = null;
 
         u = getAttributes();
@@ -607,13 +604,11 @@
                     enclosingName = readUTF8(items[item], c);
                     enclosingDesc = readUTF8(items[item] + 2, c);
                 }
-            } else if (SIGNATURES && "Signature".equals(attrName)) {
+            } else if ("Signature".equals(attrName)) {
                 signature = readUTF8(u + 8, c);
-            } else if (ANNOTATIONS
-                    && "RuntimeVisibleAnnotations".equals(attrName)) {
+            } else if ("RuntimeVisibleAnnotations".equals(attrName)) {
                 anns = u + 8;
-            } else if (ANNOTATIONS
-                    && "RuntimeVisibleTypeAnnotations".equals(attrName)) {
+            } else if ("RuntimeVisibleTypeAnnotations".equals(attrName)) {
                 tanns = u + 8;
             } else if ("Deprecated".equals(attrName)) {
                 access |= Opcodes.ACC_DEPRECATED;
@@ -623,12 +618,16 @@
             } else if ("SourceDebugExtension".equals(attrName)) {
                 int len = readInt(u + 4);
                 sourceDebug = readUTF(u + 8, len, new char[len]);
-            } else if (ANNOTATIONS
-                    && "RuntimeInvisibleAnnotations".equals(attrName)) {
+            } else if ("RuntimeInvisibleAnnotations".equals(attrName)) {
                 ianns = u + 8;
-            } else if (ANNOTATIONS
-                    && "RuntimeInvisibleTypeAnnotations".equals(attrName)) {
+            } else if ("RuntimeInvisibleTypeAnnotations".equals(attrName)) {
                 itanns = u + 8;
+            } else if ("Module".equals(attrName)) {
+                module = u + 8;
+            } else if ("ModuleMainClass".equals(attrName)) {
+                moduleMainClass = readClass(u + 8, c);
+            } else if ("ModulePackages".equals(attrName)) {
+                packages = u + 10;
             } else if ("BootstrapMethods".equals(attrName)) {
                 int[] bootstrapMethods = new int[readUnsignedShort(u + 8)];
                 for (int j = 0, v = u + 10; j < bootstrapMethods.length; j++) {
@@ -657,6 +656,12 @@
             classVisitor.visitSource(sourceFile, sourceDebug);
         }
 
+        // visits the module info and associated attributes
+        if (module != 0) {
+            readModule(classVisitor, context, module,
+                    moduleMainClass, packages);
+        }
+
         // visits the outer class
         if (enclosingOwner != null) {
             classVisitor.visitOuterClass(enclosingOwner, enclosingName,
@@ -664,19 +669,19 @@
         }
 
         // visits the class annotations and type annotations
-        if (ANNOTATIONS && anns != 0) {
+        if (anns != 0) {
             for (int i = readUnsignedShort(anns), v = anns + 2; i > 0; --i) {
                 v = readAnnotationValues(v + 2, c, true,
                         classVisitor.visitAnnotation(readUTF8(v, c), true));
             }
         }
-        if (ANNOTATIONS && ianns != 0) {
+        if (ianns != 0) {
             for (int i = readUnsignedShort(ianns), v = ianns + 2; i > 0; --i) {
                 v = readAnnotationValues(v + 2, c, true,
                         classVisitor.visitAnnotation(readUTF8(v, c), false));
             }
         }
-        if (ANNOTATIONS && tanns != 0) {
+        if (tanns != 0) {
             for (int i = readUnsignedShort(tanns), v = tanns + 2; i > 0; --i) {
                 v = readAnnotationTarget(context, v);
                 v = readAnnotationValues(v + 2, c, true,
@@ -684,7 +689,7 @@
                                 context.typePath, readUTF8(v, c), true));
             }
         }
-        if (ANNOTATIONS && itanns != 0) {
+        if (itanns != 0) {
             for (int i = readUnsignedShort(itanns), v = itanns + 2; i > 0; --i) {
                 v = readAnnotationTarget(context, v);
                 v = readAnnotationValues(v + 2, c, true,
@@ -727,6 +732,120 @@
     }
 
     /**
+     * Reads the module attribute and visit it.
+     *
+     * @param classVisitor
+     *           the current class visitor
+     * @param context
+     *           information about the class being parsed.
+     * @param u
+     *           start offset of the module attribute in the class file.
+     * @param mainClass
+     *           name of the main class of a module or null.
+     * @param packages
+     *           start offset of the concealed package attribute.
+     */
+    private void readModule(final ClassVisitor classVisitor,
+            final Context context, int u,
+            final String mainClass, int packages) {
+
+        char[] buffer = context.buffer;
+
+        // reads module name, flags and version
+        String name = readModule(u, buffer);
+        int flags = readUnsignedShort(u + 2);
+        String version = readUTF8(u + 4, buffer);
+        u += 6;
+
+        ModuleVisitor mv = classVisitor.visitModule(name, flags, version);
+        if (mv == null) {
+            return;
+        }
+
+        // module attributes (main class, packages)
+        if (mainClass != null) {
+            mv.visitMainClass(mainClass);
+        }
+
+        if (packages != 0) {
+            for (int i = readUnsignedShort(packages - 2); i > 0; --i) {
+                String packaze = readPackage(packages, buffer);
+                mv.visitPackage(packaze);
+                packages += 2;
+            }
+        }
+
+        // reads requires
+        u += 2;
+        for (int i = readUnsignedShort(u - 2); i > 0; --i) {
+            String module = readModule(u, buffer);
+            int access = readUnsignedShort(u + 2);
+            String requireVersion = readUTF8(u + 4, buffer);
+            mv.visitRequire(module, access, requireVersion);
+            u += 6;
+        }
+
+        // reads exports
+        u += 2;
+        for (int i = readUnsignedShort(u - 2); i > 0; --i) {
+            String export = readPackage(u, buffer);
+            int access = readUnsignedShort(u + 2);
+            int exportToCount = readUnsignedShort(u + 4);
+            u += 6;
+            String[] tos = null;
+            if (exportToCount != 0) {
+                tos = new String[exportToCount];
+                for (int j = 0; j < tos.length; ++j) {
+                    tos[j] = readModule(u, buffer);
+                    u += 2;
+                }
+            }
+            mv.visitExport(export, access, tos);
+        }
+
+        // reads opens
+        u += 2;
+        for (int i = readUnsignedShort(u - 2); i > 0; --i) {
+            String open = readPackage(u, buffer);
+            int access = readUnsignedShort(u + 2);
+            int openToCount = readUnsignedShort(u + 4);
+            u += 6;
+            String[] tos = null;
+            if (openToCount != 0) {
+                tos = new String[openToCount];
+                for (int j = 0; j < tos.length; ++j) {
+                    tos[j] = readModule(u, buffer);
+                    u += 2;
+                }
+            }
+            mv.visitOpen(open, access, tos);
+        }
+
+        // read uses
+        u += 2;
+        for (int i = readUnsignedShort(u - 2); i > 0; --i) {
+            mv.visitUse(readClass(u, buffer));
+            u += 2;
+        }
+
+        // read provides
+        u += 2;
+        for (int i = readUnsignedShort(u - 2); i > 0; --i) {
+            String service = readClass(u, buffer);
+            int provideWithCount = readUnsignedShort(u + 2);
+            u += 4;
+            String[] withs = new String[provideWithCount];
+            for (int j = 0; j < withs.length; ++j) {
+                withs[j] = readClass(u, buffer);
+                u += 2;
+            }
+            mv.visitProvide(service, withs);
+        }
+
+        mv.visitEnd();
+    }
+
+    /**
      * Reads a field and makes the given visitor visit it.
      *
      * @param classVisitor
@@ -762,24 +881,20 @@
             if ("ConstantValue".equals(attrName)) {
                 int item = readUnsignedShort(u + 8);
                 value = item == 0 ? null : readConst(item, c);
-            } else if (SIGNATURES && "Signature".equals(attrName)) {
+            } else if ("Signature".equals(attrName)) {
                 signature = readUTF8(u + 8, c);
             } else if ("Deprecated".equals(attrName)) {
                 access |= Opcodes.ACC_DEPRECATED;
             } else if ("Synthetic".equals(attrName)) {
                 access |= Opcodes.ACC_SYNTHETIC
                         | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE;
-            } else if (ANNOTATIONS
-                    && "RuntimeVisibleAnnotations".equals(attrName)) {
+            } else if ("RuntimeVisibleAnnotations".equals(attrName)) {
                 anns = u + 8;
-            } else if (ANNOTATIONS
-                    && "RuntimeVisibleTypeAnnotations".equals(attrName)) {
+            } else if ("RuntimeVisibleTypeAnnotations".equals(attrName)) {
                 tanns = u + 8;
-            } else if (ANNOTATIONS
-                    && "RuntimeInvisibleAnnotations".equals(attrName)) {
+            } else if ("RuntimeInvisibleAnnotations".equals(attrName)) {
                 ianns = u + 8;
-            } else if (ANNOTATIONS
-                    && "RuntimeInvisibleTypeAnnotations".equals(attrName)) {
+            } else if ("RuntimeInvisibleTypeAnnotations".equals(attrName)) {
                 itanns = u + 8;
             } else {
                 Attribute attr = readAttribute(context.attrs, attrName, u + 8,
@@ -801,19 +916,19 @@
         }
 
         // visits the field annotations and type annotations
-        if (ANNOTATIONS && anns != 0) {
+        if (anns != 0) {
             for (int i = readUnsignedShort(anns), v = anns + 2; i > 0; --i) {
                 v = readAnnotationValues(v + 2, c, true,
                         fv.visitAnnotation(readUTF8(v, c), true));
             }
         }
-        if (ANNOTATIONS && ianns != 0) {
+        if (ianns != 0) {
             for (int i = readUnsignedShort(ianns), v = ianns + 2; i > 0; --i) {
                 v = readAnnotationValues(v + 2, c, true,
                         fv.visitAnnotation(readUTF8(v, c), false));
             }
         }
-        if (ANNOTATIONS && tanns != 0) {
+        if (tanns != 0) {
             for (int i = readUnsignedShort(tanns), v = tanns + 2; i > 0; --i) {
                 v = readAnnotationTarget(context, v);
                 v = readAnnotationValues(v + 2, c, true,
@@ -821,7 +936,7 @@
                                 context.typePath, readUTF8(v, c), true));
             }
         }
-        if (ANNOTATIONS && itanns != 0) {
+        if (itanns != 0) {
             for (int i = readUnsignedShort(itanns), v = itanns + 2; i > 0; --i) {
                 v = readAnnotationTarget(context, v);
                 v = readAnnotationValues(v + 2, c, true,
@@ -895,32 +1010,26 @@
                     exceptions[j] = readClass(exception, c);
                     exception += 2;
                 }
-            } else if (SIGNATURES && "Signature".equals(attrName)) {
+            } else if ("Signature".equals(attrName)) {
                 signature = readUTF8(u + 8, c);
             } else if ("Deprecated".equals(attrName)) {
                 context.access |= Opcodes.ACC_DEPRECATED;
-            } else if (ANNOTATIONS
-                    && "RuntimeVisibleAnnotations".equals(attrName)) {
+            } else if ("RuntimeVisibleAnnotations".equals(attrName)) {
                 anns = u + 8;
-            } else if (ANNOTATIONS
-                    && "RuntimeVisibleTypeAnnotations".equals(attrName)) {
+            } else if ("RuntimeVisibleTypeAnnotations".equals(attrName)) {
                 tanns = u + 8;
-            } else if (ANNOTATIONS && "AnnotationDefault".equals(attrName)) {
+            } else if ("AnnotationDefault".equals(attrName)) {
                 dann = u + 8;
             } else if ("Synthetic".equals(attrName)) {
                 context.access |= Opcodes.ACC_SYNTHETIC
                         | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE;
-            } else if (ANNOTATIONS
-                    && "RuntimeInvisibleAnnotations".equals(attrName)) {
+            } else if ("RuntimeInvisibleAnnotations".equals(attrName)) {
                 ianns = u + 8;
-            } else if (ANNOTATIONS
-                    && "RuntimeInvisibleTypeAnnotations".equals(attrName)) {
+            } else if ("RuntimeInvisibleTypeAnnotations".equals(attrName)) {
                 itanns = u + 8;
-            } else if (ANNOTATIONS
-                    && "RuntimeVisibleParameterAnnotations".equals(attrName)) {
+            } else if ("RuntimeVisibleParameterAnnotations".equals(attrName)) {
                 mpanns = u + 8;
-            } else if (ANNOTATIONS
-                    && "RuntimeInvisibleParameterAnnotations".equals(attrName)) {
+            } else if ("RuntimeInvisibleParameterAnnotations".equals(attrName)) {
                 impanns = u + 8;
             } else if ("MethodParameters".equals(attrName)) {
                 methodParameters = u + 8;
@@ -953,7 +1062,7 @@
          * access, name and descriptor can have been changed, this is not
          * important since they are not copied as is from the reader).
          */
-        if (WRITER && mv instanceof MethodWriter) {
+        if (mv instanceof MethodWriter) {
             MethodWriter mw = (MethodWriter) mv;
             if (mw.cw.cr == this && signature == mw.signature) {
                 boolean sameExceptions = false;
@@ -990,26 +1099,26 @@
         }
 
         // visits the method annotations
-        if (ANNOTATIONS && dann != 0) {
+        if (dann != 0) {
             AnnotationVisitor dv = mv.visitAnnotationDefault();
             readAnnotationValue(dann, c, null, dv);
             if (dv != null) {
                 dv.visitEnd();
             }
         }
-        if (ANNOTATIONS && anns != 0) {
+        if (anns != 0) {
             for (int i = readUnsignedShort(anns), v = anns + 2; i > 0; --i) {
                 v = readAnnotationValues(v + 2, c, true,
                         mv.visitAnnotation(readUTF8(v, c), true));
             }
         }
-        if (ANNOTATIONS && ianns != 0) {
+        if (ianns != 0) {
             for (int i = readUnsignedShort(ianns), v = ianns + 2; i > 0; --i) {
                 v = readAnnotationValues(v + 2, c, true,
                         mv.visitAnnotation(readUTF8(v, c), false));
             }
         }
-        if (ANNOTATIONS && tanns != 0) {
+        if (tanns != 0) {
             for (int i = readUnsignedShort(tanns), v = tanns + 2; i > 0; --i) {
                 v = readAnnotationTarget(context, v);
                 v = readAnnotationValues(v + 2, c, true,
@@ -1017,7 +1126,7 @@
                                 context.typePath, readUTF8(v, c), true));
             }
         }
-        if (ANNOTATIONS && itanns != 0) {
+        if (itanns != 0) {
             for (int i = readUnsignedShort(itanns), v = itanns + 2; i > 0; --i) {
                 v = readAnnotationTarget(context, v);
                 v = readAnnotationValues(v + 2, c, true,
@@ -1025,10 +1134,10 @@
                                 context.typePath, readUTF8(v, c), false));
             }
         }
-        if (ANNOTATIONS && mpanns != 0) {
+        if (mpanns != 0) {
             readParameterAnnotations(mv, context, mpanns, true);
         }
-        if (ANNOTATIONS && impanns != 0) {
+        if (impanns != 0) {
             readParameterAnnotations(mv, context, impanns, false);
         }
 
@@ -1075,7 +1184,7 @@
         int codeStart = u;
         int codeEnd = u + codeLength;
         Label[] labels = context.labels = new Label[codeLength + 2];
-        readLabel(codeLength + 1, labels);
+        createLabel(codeLength + 1, labels);
         while (u < codeEnd) {
             int offset = u - codeStart;
             int opcode = b[u] & 0xFF;
@@ -1085,11 +1194,16 @@
                 u += 1;
                 break;
             case ClassWriter.LABEL_INSN:
-                readLabel(offset + readShort(u + 1), labels);
+                createLabel(offset + readShort(u + 1), labels);
+                u += 3;
+                break;
+            case ClassWriter.ASM_LABEL_INSN:
+                createLabel(offset + readUnsignedShort(u + 1), labels);
                 u += 3;
                 break;
             case ClassWriter.LABELW_INSN:
-                readLabel(offset + readInt(u + 1), labels);
+            case ClassWriter.ASM_LABELW_INSN:
+                createLabel(offset + readInt(u + 1), labels);
                 u += 5;
                 break;
             case ClassWriter.WIDE_INSN:
@@ -1104,9 +1218,9 @@
                 // skips 0 to 3 padding bytes
                 u = u + 4 - (offset & 3);
                 // reads instruction
-                readLabel(offset + readInt(u), labels);
+                createLabel(offset + readInt(u), labels);
                 for (int i = readInt(u + 8) - readInt(u + 4) + 1; i > 0; --i) {
-                    readLabel(offset + readInt(u + 12), labels);
+                    createLabel(offset + readInt(u + 12), labels);
                     u += 4;
                 }
                 u += 12;
@@ -1115,9 +1229,9 @@
                 // skips 0 to 3 padding bytes
                 u = u + 4 - (offset & 3);
                 // reads instruction
-                readLabel(offset + readInt(u), labels);
+                createLabel(offset + readInt(u), labels);
                 for (int i = readInt(u + 4); i > 0; --i) {
-                    readLabel(offset + readInt(u + 12), labels);
+                    createLabel(offset + readInt(u + 12), labels);
                     u += 8;
                 }
                 u += 8;
@@ -1147,9 +1261,9 @@
 
         // reads the try catch entries to find the labels, and also visits them
         for (int i = readUnsignedShort(u); i > 0; --i) {
-            Label start = readLabel(readUnsignedShort(u + 2), labels);
-            Label end = readLabel(readUnsignedShort(u + 4), labels);
-            Label handler = readLabel(readUnsignedShort(u + 6), labels);
+            Label start = createLabel(readUnsignedShort(u + 2), labels);
+            Label end = createLabel(readUnsignedShort(u + 4), labels);
+            Label handler = createLabel(readUnsignedShort(u + 6), labels);
             String type = readUTF8(items[readUnsignedShort(u + 8)], c);
             mv.visitTryCatchBlock(start, end, handler, type);
             u += 8;
@@ -1180,13 +1294,9 @@
                     varTable = u + 8;
                     for (int j = readUnsignedShort(u + 8), v = u; j > 0; --j) {
                         int label = readUnsignedShort(v + 10);
-                        if (labels[label] == null) {
-                            readLabel(label, labels).status |= Label.DEBUG;
-                        }
+                        createDebugLabel(label, labels);
                         label += readUnsignedShort(v + 12);
-                        if (labels[label] == null) {
-                            readLabel(label, labels).status |= Label.DEBUG;
-                        }
+                        createDebugLabel(label, labels);
                         v += 10;
                     }
                 }
@@ -1196,9 +1306,7 @@
                 if ((context.flags & SKIP_DEBUG) == 0) {
                     for (int j = readUnsignedShort(u + 8), v = u; j > 0; --j) {
                         int label = readUnsignedShort(v + 10);
-                        if (labels[label] == null) {
-                            readLabel(label, labels).status |= Label.DEBUG;
-                        }
+                        createDebugLabel(label, labels);
                         Label l = labels[label];
                         while (l.line > 0) {
                             if (l.next == null) {
@@ -1210,17 +1318,15 @@
                         v += 4;
                     }
                 }
-            } else if (ANNOTATIONS
-                    && "RuntimeVisibleTypeAnnotations".equals(attrName)) {
+            } else if ("RuntimeVisibleTypeAnnotations".equals(attrName)) {
                 tanns = readTypeAnnotations(mv, context, u + 8, true);
                 ntoff = tanns.length == 0 || readByte(tanns[0]) < 0x43 ? -1
                         : readUnsignedShort(tanns[0] + 1);
-            } else if (ANNOTATIONS
-                    && "RuntimeInvisibleTypeAnnotations".equals(attrName)) {
+            } else if ("RuntimeInvisibleTypeAnnotations".equals(attrName)) {
                 itanns = readTypeAnnotations(mv, context, u + 8, false);
                 nitoff = itanns.length == 0 || readByte(itanns[0]) < 0x43 ? -1
                         : readUnsignedShort(itanns[0] + 1);
-            } else if (FRAMES && "StackMapTable".equals(attrName)) {
+            } else if ("StackMapTable".equals(attrName)) {
                 if ((context.flags & SKIP_FRAMES) == 0) {
                     stackMap = u + 10;
                     stackMapSize = readInt(u + 4);
@@ -1244,7 +1350,7 @@
                  * this by parsing the stack map table without a full decoding
                  * (see below).
                  */
-            } else if (FRAMES && "StackMap".equals(attrName)) {
+            } else if ("StackMap".equals(attrName)) {
                 if ((context.flags & SKIP_FRAMES) == 0) {
                     zip = false;
                     stackMap = u + 10;
@@ -1273,7 +1379,7 @@
         u += 2;
 
         // generates the first (implicit) stack map frame
-        if (FRAMES && stackMap != 0) {
+        if (stackMap != 0) {
             /*
              * for the first explicit frame the offset is not offset_delta + 1
              * but only offset_delta; setting the implicit frame offset to -1
@@ -1306,14 +1412,31 @@
                     int v = readUnsignedShort(i + 1);
                     if (v >= 0 && v < codeLength) {
                         if ((b[codeStart + v] & 0xFF) == Opcodes.NEW) {
-                            readLabel(v, labels);
+                            createLabel(v, labels);
                         }
                     }
                 }
             }
         }
+        if ((context.flags & EXPAND_ASM_INSNS) != 0
+            && (context.flags & EXPAND_FRAMES) != 0) {
+            // Expanding the ASM pseudo instructions can introduce F_INSERT
+            // frames, even if the method does not currently have any frame.
+            // Also these inserted frames must be computed by simulating the
+            // effect of the bytecode instructions one by one, starting from the
+            // first one and the last existing frame (or the implicit first
+            // one). Finally, due to the way MethodWriter computes this (with
+            // the compute = INSERTED_FRAMES option), MethodWriter needs to know
+            // maxLocals before the first instruction is visited. For all these
+            // reasons we always visit the implicit first frame in this case
+            // (passing only maxLocals - the rest can be and is computed in
+            // MethodWriter).
+            mv.visitFrame(Opcodes.F_NEW, maxLocals, null, 0, null);
+        }
 
         // visits the instructions
+        int opcodeDelta = (context.flags & EXPAND_ASM_INSNS) == 0 ? -33 : 0;
+        boolean insertFrame = false;
         u = codeStart;
         while (u < codeEnd) {
             int offset = u - codeStart;
@@ -1334,7 +1457,7 @@
             }
 
             // visits the frame for this offset, if any
-            while (FRAMES && frame != null
+            while (frame != null
                     && (frame.offset == offset || frame.offset == -1)) {
                 // if there is a frame for this offset, makes the visitor visit
                 // it, and reads the next frame if there is one.
@@ -1346,6 +1469,9 @@
                         mv.visitFrame(frame.mode, frame.localDiff, frame.local,
                                 frame.stackCount, frame.stack);
                     }
+                    // if there is already a frame for this offset, there is no
+                    // need to insert a new one.
+                    insertFrame = false;
                 }
                 if (frameCount > 0) {
                     stackMap = readFrame(stackMap, zip, unzip, frame);
@@ -1354,6 +1480,13 @@
                     frame = null;
                 }
             }
+            // inserts a frame for this offset, if requested by setting
+            // insertFrame to true during the previous iteration. The actual
+            // frame content will be computed in MethodWriter.
+            if (insertFrame) {
+                mv.visitFrame(ClassWriter.F_INSERT, 0, null, 0, null);
+                insertFrame = false;
+            }
 
             // visits the instruction at this offset
             int opcode = b[u] & 0xFF;
@@ -1378,9 +1511,47 @@
                 u += 3;
                 break;
             case ClassWriter.LABELW_INSN:
-                mv.visitJumpInsn(opcode - 33, labels[offset + readInt(u + 1)]);
+                mv.visitJumpInsn(opcode + opcodeDelta, labels[offset
+                        + readInt(u + 1)]);
                 u += 5;
                 break;
+            case ClassWriter.ASM_LABEL_INSN: {
+                // changes temporary opcodes 202 to 217 (inclusive), 218
+                // and 219 to IFEQ ... JSR (inclusive), IFNULL and
+                // IFNONNULL
+                opcode = opcode < 218 ? opcode - 49 : opcode - 20;
+                Label target = labels[offset + readUnsignedShort(u + 1)];
+                // replaces GOTO with GOTO_W, JSR with JSR_W and IFxxx
+                // <l> with IFNOTxxx <L> GOTO_W <l> L:..., where IFNOTxxx is
+                // the "opposite" opcode of IFxxx (i.e., IFNE for IFEQ)
+                // and where <L> designates the instruction just after
+                // the GOTO_W.
+                if (opcode == Opcodes.GOTO || opcode == Opcodes.JSR) {
+                    mv.visitJumpInsn(opcode + 33, target);
+                } else {
+                    opcode = opcode <= 166 ? ((opcode + 1) ^ 1) - 1
+                            : opcode ^ 1;
+                    Label endif = createLabel(offset + 3, labels);
+                    mv.visitJumpInsn(opcode, endif);
+                    mv.visitJumpInsn(200, target); // GOTO_W
+                    // endif designates the instruction just after GOTO_W,
+                    // and is visited as part of the next instruction. Since
+                    // it is a jump target, we need to insert a frame here.
+                    insertFrame = true;
+                }
+                u += 3;
+                break;
+            }
+            case ClassWriter.ASM_LABELW_INSN: {
+                // replaces the pseudo GOTO_W instruction with a real one.
+                mv.visitJumpInsn(200, labels[offset + readInt(u + 1)]);
+                // The instruction just after is a jump target (because pseudo
+                // GOTO_W are used in patterns IFNOTxxx <L> GOTO_W <l> L:...,
+                // see MethodWriter), so we need to insert a frame here.
+                insertFrame = true;
+                u += 5;
+                break;
+            }
             case ClassWriter.WIDE_INSN:
                 opcode = b[u + 1] & 0xFF;
                 if (opcode == Opcodes.IINC) {
@@ -1636,8 +1807,8 @@
                 for (int j = readUnsignedShort(u + 1); j > 0; --j) {
                     int start = readUnsignedShort(u + 3);
                     int length = readUnsignedShort(u + 5);
-                    readLabel(start, context.labels);
-                    readLabel(start + length, context.labels);
+                    createLabel(start, context.labels);
+                    createLabel(start + length, context.labels);
                     u += 6;
                 }
                 u += 3;
@@ -1716,8 +1887,8 @@
             for (int i = 0; i < n; ++i) {
                 int start = readUnsignedShort(u);
                 int length = readUnsignedShort(u + 2);
-                context.start[i] = readLabel(start, context.labels);
-                context.end[i] = readLabel(start + length, context.labels);
+                context.start[i] = createLabel(start, context.labels);
+                context.end[i] = createLabel(start + length, context.labels);
                 context.index[i] = readUnsignedShort(u + 4);
                 u += 6;
             }
@@ -2137,7 +2308,7 @@
             }
         }
         frame.offset += delta + 1;
-        readLabel(frame.offset, labels);
+        createLabel(frame.offset, labels);
         return stackMap;
     }
 
@@ -2190,7 +2361,7 @@
             v += 2;
             break;
         default: // Uninitialized
-            frame[index] = readLabel(readUnsignedShort(v), labels);
+            frame[index] = createLabel(readUnsignedShort(v), labels);
             v += 2;
         }
         return v;
@@ -2217,6 +2388,39 @@
     }
 
     /**
+     * Creates a label without the Label.DEBUG flag set, for the given offset.
+     * The label is created with a call to {@link #readLabel} and its
+     * Label.DEBUG flag is cleared.
+     *
+     * @param offset
+     *            a bytecode offset in a method.
+     * @param labels
+     *            the already created labels, indexed by their offset.
+     * @return a Label without the Label.DEBUG flag set.
+     */
+    private Label createLabel(int offset, Label[] labels) {
+      Label label = readLabel(offset, labels);
+      label.status &= ~Label.DEBUG;
+      return label;
+    }
+
+    /**
+     * Creates a label with the Label.DEBUG flag set, if there is no already
+     * existing label for the given offset (otherwise does nothing). The label
+     * is created with a call to {@link #readLabel}.
+     *
+     * @param offset
+     *            a bytecode offset in a method.
+     * @param labels
+     *            the already created labels, indexed by their offset.
+     */
+    private void createDebugLabel(int offset, Label[] labels) {
+        if (labels[offset] == null) {
+            readLabel(offset, labels).status |= Label.DEBUG;
+        }
+    }
+
+    /**
      * Returns the start index of the attribute_info structure of this class.
      *
      * @return the start index of the attribute_info structure of this class.
@@ -2471,6 +2675,20 @@
     }
 
     /**
+     * Read a stringish constant item (CONSTANT_Class, CONSTANT_String,
+     * CONSTANT_MethodType, CONSTANT_Module or CONSTANT_Package
+     * @param index
+     * @param buf
+     * @return
+     */
+    private String readStringish(final int index, final char[] buf) {
+        // computes the start index of the item in b
+        // and reads the CONSTANT_Utf8 item designated by
+        // the first two bytes of this item
+        return readUTF8(items[readUnsignedShort(index)], buf);
+    }
+
+    /**
      * Reads a class constant pool item in {@link #b b}. <i>This method is
      * intended for {@link Attribute} sub classes, and is normally not needed by
      * class generators or adapters.</i>
@@ -2484,44 +2702,41 @@
      * @return the String corresponding to the specified class item.
      */
     public String readClass(final int index, final char[] buf) {
-        // computes the start index of the CONSTANT_Class item in b
-        // and reads the CONSTANT_Utf8 item designated by
-        // the first two bytes of this CONSTANT_Class item
-        return readUTF8(items[readUnsignedShort(index)], buf);
+        return readStringish(index, buf);
     }
 
     /**
-     * Reads a CONSTANT_Module_info item in {@code b}. This method is intended
-     * for {@link Attribute} sub classes, and is normally not needed by class
-     * generators or adapters.</i>
+     * Reads a module constant pool item in {@link #b b}. <i>This method is
+     * intended for {@link Attribute} sub classes, and is normally not needed by
+     * class generators or adapters.</i>
      *
-     * @param  index
-     *         the start index of an unsigned short value in {@link #b b},
-     *         whose value is the index of a module constant pool item.
-     * @param  buf
-     *         buffer to be used to read the item. This buffer must be
-     *         sufficiently large. It is not automatically resized.
+     * @param index
+     *            the start index of an unsigned short value in {@link #b b},
+     *            whose value is the index of a module constant pool item.
+     * @param buf
+     *            buffer to be used to read the item. This buffer must be
+     *            sufficiently large. It is not automatically resized.
      * @return the String corresponding to the specified module item.
      */
-    public String readModule(int index, char[] buf) {
-        return readUTF8(items[readUnsignedShort(index)], buf);
+    public String readModule(final int index, final char[] buf) {
+        return readStringish(index, buf);
     }
 
     /**
-     * Reads a CONSTANT_Package_info item in {@code b}.  This method is
-     * intended for {@link Attribute} sub slasses, and is normally not needed
-     * by class generators or adapters.</i>
+     * Reads a module constant pool item in {@link #b b}. <i>This method is
+     * intended for {@link Attribute} sub classes, and is normally not needed by
+     * class generators or adapters.</i>
      *
-     * @param  index
-     *         the start index of an unsigned short value in {@link #b b},
-     *         whose value is the index of a package constant pool item.
-     * @param  buf
-     *         buffer to be used to read the item. This buffer must be
-     *         sufficiently large. It is not automatically resized.
-     * @return the String corresponding to the specified package item.
+     * @param index
+     *            the start index of an unsigned short value in {@link #b b},
+     *            whose value is the index of a module constant pool item.
+     * @param buf
+     *            buffer to be used to read the item. This buffer must be
+     *            sufficiently large. It is not automatically resized.
+     * @return the String corresponding to the specified module item.
      */
-    public String readPackage(int index, char[] buf) {
-        return readUTF8(items[readUnsignedShort(index)], buf);
+    public String readPackage(final int index, final char[] buf) {
+        return readStringish(index, buf);
     }
 
     /**
@@ -2550,8 +2765,6 @@
         case ClassWriter.DOUBLE:
             return Double.longBitsToDouble(readLong(index));
         case ClassWriter.CLASS:
-        case ClassWriter.MODULE:
-        case ClassWriter.PACKAGE:
             return Type.getObjectType(readUTF8(index, buf));
         case ClassWriter.STR:
             return readUTF8(index, buf);
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ClassVisitor.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ClassVisitor.java	Wed Nov 08 16:03:35 2017 -0500
@@ -61,7 +61,7 @@
 /**
  * A visitor to visit a Java class. The methods of this class must be called in
  * the following order: <tt>visit</tt> [ <tt>visitSource</tt> ] [
- * <tt>visitOuterClass</tt> ] ( <tt>visitAnnotation</tt> |
+ * <tt>visitModule</tt> ][ <tt>visitOuterClass</tt> ] ( <tt>visitAnnotation</tt> |
  * <tt>visitTypeAnnotation</tt> | <tt>visitAttribute</tt> )* (
  * <tt>visitInnerClass</tt> | <tt>visitField</tt> | <tt>visitMethod</tt> )*
  * <tt>visitEnd</tt>.
@@ -72,7 +72,7 @@
 
     /**
      * The ASM API version implemented by this visitor. The value of this field
-     * must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     * must be one of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      */
     protected final int api;
 
@@ -87,7 +87,7 @@
      *
      * @param api
      *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      */
     public ClassVisitor(final int api) {
         this(api, null);
@@ -98,13 +98,13 @@
      *
      * @param api
      *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      * @param cv
      *            the class visitor to which this visitor must delegate method
      *            calls. May be null.
      */
     public ClassVisitor(final int api, final ClassVisitor cv) {
-        if (api != Opcodes.ASM4 && api != Opcodes.ASM5) {
+        if (api < Opcodes.ASM4 || api > Opcodes.ASM6) {
             throw new IllegalArgumentException();
         }
         this.api = api;
@@ -161,6 +161,28 @@
     }
 
     /**
+     * Visit the module corresponding to the class.
+     * @param name
+     *            module name
+     * @param access
+     *            module flags, among {@code ACC_OPEN}, {@code ACC_SYNTHETIC}
+     *            and {@code ACC_MANDATED}.
+     * @param version
+     *            module version or null.
+     * @return a visitor to visit the module values, or <tt>null</tt> if
+     *         this visitor is not interested in visiting this module.
+     */
+    public ModuleVisitor visitModule(String name, int access, String version) {
+        if (api < Opcodes.ASM6) {
+            throw new RuntimeException();
+        }
+        if (cv != null) {
+            return cv.visitModule(name, access, version);
+        }
+        return null;
+    }
+
+    /**
      * Visits the enclosing class of the class. This method must be called only
      * if the class has an enclosing class.
      *
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ClassWriter.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ClassWriter.java	Wed Nov 08 16:03:35 2017 -0500
@@ -87,8 +87,8 @@
      * {@link MethodVisitor#visitFrame} method are ignored, and the stack map
      * frames are recomputed from the methods bytecode. The arguments of the
      * {@link MethodVisitor#visitMaxs visitMaxs} method are also ignored and
-     * recomputed from the bytecode. In other words, computeFrames implies
-     * computeMaxs.
+     * recomputed from the bytecode. In other words, COMPUTE_FRAMES implies
+     * COMPUTE_MAXS.
      *
      * @see #ClassWriter(int)
      */
@@ -197,6 +197,27 @@
     static final int WIDE_INSN = 17;
 
     /**
+     * The type of the ASM pseudo instructions with an unsigned 2 bytes offset
+     * label (see Label#resolve).
+     */
+    static final int ASM_LABEL_INSN = 18;
+
+    /**
+     * The type of the ASM pseudo instructions with a 4 bytes offset label.
+     */
+    static final int ASM_LABELW_INSN = 19;
+
+    /**
+     * Represents a frame inserted between already existing frames. This kind of
+     * frame can only be used if the frame content can be computed from the
+     * previous existing frame and from the instructions between this existing
+     * frame and the inserted one, without any knowledge of the type hierarchy.
+     * This kind of frame is only used when an unconditional jump is inserted in
+     * a method while expanding an ASM pseudo instruction (see ClassReader).
+     */
+    static final int F_INSERT = 256;
+
+    /**
      * The instruction types of all JVM opcodes.
      */
     static final byte[] TYPE;
@@ -284,7 +305,7 @@
     /**
      * The base value for all CONSTANT_MethodHandle constant pool items.
      * Internally, ASM store the 9 variations of CONSTANT_MethodHandle into 9
-     * different items.
+     * different items (from 21 to 29).
      */
     static final int HANDLE_BASE = 20;
 
@@ -434,6 +455,11 @@
     private ByteVector sourceDebug;
 
     /**
+     * The module attribute of this class.
+     */
+    private ModuleWriter moduleWriter;
+
+    /**
      * The constant pool item that contains the name of the enclosing class of
      * this class.
      */
@@ -523,25 +549,19 @@
     MethodWriter lastMethod;
 
     /**
-     * <tt>true</tt> if the maximum stack size and number of local variables
-     * must be automatically computed.
+     * Indicates what must be automatically computed.
+     *
+     * @see MethodWriter#compute
      */
-    private boolean computeMaxs;
+    private int compute;
 
     /**
-     * <tt>true</tt> if the stack map frames must be recomputed from scratch.
+     * <tt>true</tt> if some methods have wide forward jumps using ASM pseudo
+     * instructions, which need to be expanded into sequences of standard
+     * bytecode instructions. In this case the class is re-read and re-written
+     * with a ClassReader -> ClassWriter chain to perform this transformation.
      */
-    private boolean computeFrames;
-
-    /**
-     * <tt>true</tt> if the stack map tables of this class are invalid. The
-     * {@link MethodWriter#resizeInstructions} method cannot transform existing
-     * stack map tables, and so produces potentially invalid classes when it is
-     * executed. In this case the class is reread and rewritten with the
-     * {@link #COMPUTE_FRAMES} option (the resizeInstructions method can resize
-     * stack map tables when this option is used).
-     */
-    boolean invalidFrames;
+    boolean hasAsmInsns;
 
     // ------------------------------------------------------------------------
     // Static initializer
@@ -552,11 +572,11 @@
      */
     static {
         int i;
-        byte[] b = new byte[220];
+        byte[] b = new byte[221];
         String s = "AAAAAAAAAAAAAAAABCLMMDDDDDEEEEEEEEEEEEEEEEEEEEAAAAAAAADD"
                 + "DDDEEEEEEEEEEEEEEEEEEEEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
                 + "AAAAAAAAAAAAAAAAANAAAAAAAAAAAAAAAAAAAAJJJJJJJJJJJJJJJJDOPAA"
-                + "AAAAGGGGGGGHIFBFAAFFAARQJJKKJJJJJJJJJJJJJJJJJJ";
+                + "AAAAGGGGGGGHIFBFAAFFAARQJJKKSSSSSSSSSSSSSSSSSST";
         for (i = 0; i < b.length; ++i) {
             b[i] = (byte) (s.charAt(i) - 'A');
         }
@@ -610,8 +630,9 @@
         // // temporary opcodes used internally by ASM - see Label and
         // MethodWriter
         // for (i = 202; i < 220; ++i) {
-        // b[i] = LABEL_INSN;
+        // b[i] = ASM_LABEL_INSN;
         // }
+        // b[220] = ASM_LABELW_INSN;
         //
         // // LDC(_W) instructions
         // b[Constants.LDC] = LDC_INSN;
@@ -644,7 +665,7 @@
      *            {@link #COMPUTE_FRAMES}.
      */
     public ClassWriter(final int flags) {
-        super(Opcodes.ASM5);
+        super(Opcodes.ASM6);
         index = 1;
         pool = new ByteVector();
         items = new Item[256];
@@ -653,8 +674,9 @@
         key2 = new Item();
         key3 = new Item();
         key4 = new Item();
-        this.computeMaxs = (flags & COMPUTE_MAXS) != 0;
-        this.computeFrames = (flags & COMPUTE_FRAMES) != 0;
+        this.compute = (flags & COMPUTE_FRAMES) != 0 ? MethodWriter.FRAMES
+                : ((flags & COMPUTE_MAXS) != 0 ? MethodWriter.MAXS
+                        : MethodWriter.NOTHING);
     }
 
     /**
@@ -684,9 +706,9 @@
      * @param flags
      *            option flags that can be used to modify the default behavior
      *            of this class. <i>These option flags do not affect methods
-     *            that are copied as is in the new class. This means that the
-     *            maximum stack size nor the stack frames will be computed for
-     *            these methods</i>. See {@link #COMPUTE_MAXS},
+     *            that are copied as is in the new class. This means that
+     *            neither the maximum stack size nor the stack frames will be
+     *            computed for these methods</i>. See {@link #COMPUTE_MAXS},
      *            {@link #COMPUTE_FRAMES}.
      */
     public ClassWriter(final ClassReader classReader, final int flags) {
@@ -705,9 +727,9 @@
             final String[] interfaces) {
         this.version = version;
         this.access = access;
-        this.name = (name == null) ? 0 : newClass(name);
+        this.name = newClass(name);
         thisName = name;
-        if (ClassReader.SIGNATURES && signature != null) {
+        if (signature != null) {
             this.signature = newUTF8(signature);
         }
         this.superName = superName == null ? 0 : newClass(superName);
@@ -732,6 +754,14 @@
     }
 
     @Override
+    public final ModuleVisitor visitModule(final String name,
+            final int access, final String version) {
+        return moduleWriter = new ModuleWriter(this,
+                newModule(name), access,
+                version == null ? 0 : newUTF8(version));
+    }
+
+    @Override
     public final void visitOuterClass(final String owner, final String name,
             final String desc) {
         enclosingMethodOwner = newClass(owner);
@@ -743,9 +773,6 @@
     @Override
     public final AnnotationVisitor visitAnnotation(final String desc,
             final boolean visible) {
-        if (!ClassReader.ANNOTATIONS) {
-            return null;
-        }
         ByteVector bv = new ByteVector();
         // write type, and reserve space for values count
         bv.putShort(newUTF8(desc)).putShort(0);
@@ -763,9 +790,6 @@
     @Override
     public final AnnotationVisitor visitTypeAnnotation(int typeRef,
             TypePath typePath, final String desc, final boolean visible) {
-        if (!ClassReader.ANNOTATIONS) {
-            return null;
-        }
         ByteVector bv = new ByteVector();
         // write target_type and target_info
         AnnotationWriter.putTarget(typeRef, typePath, bv);
@@ -805,7 +829,7 @@
         // and equality tests). If so we store the index of this inner class
         // entry (plus one) in intVal. This hack allows duplicate detection in
         // O(1) time.
-        Item nameItem = newClassItem(name);
+        Item nameItem = newStringishItem(CLASS, name);
         if (nameItem.intVal == 0) {
             ++innerClassesCount;
             innerClasses.putShort(nameItem.index);
@@ -830,7 +854,7 @@
     public final MethodVisitor visitMethod(final int access, final String name,
             final String desc, final String signature, final String[] exceptions) {
         return new MethodWriter(this, access, name, desc, signature,
-                exceptions, computeMaxs, computeFrames);
+                exceptions, compute);
     }
 
     @Override
@@ -874,7 +898,7 @@
             size += 8 + bootstrapMethods.length;
             newUTF8("BootstrapMethods");
         }
-        if (ClassReader.SIGNATURES && signature != 0) {
+        if (signature != 0) {
             ++attributeCount;
             size += 8;
             newUTF8("Signature");
@@ -912,26 +936,31 @@
             size += 8 + innerClasses.length;
             newUTF8("InnerClasses");
         }
-        if (ClassReader.ANNOTATIONS && anns != null) {
+        if (anns != null) {
             ++attributeCount;
             size += 8 + anns.getSize();
             newUTF8("RuntimeVisibleAnnotations");
         }
-        if (ClassReader.ANNOTATIONS && ianns != null) {
+        if (ianns != null) {
             ++attributeCount;
             size += 8 + ianns.getSize();
             newUTF8("RuntimeInvisibleAnnotations");
         }
-        if (ClassReader.ANNOTATIONS && tanns != null) {
+        if (tanns != null) {
             ++attributeCount;
             size += 8 + tanns.getSize();
             newUTF8("RuntimeVisibleTypeAnnotations");
         }
-        if (ClassReader.ANNOTATIONS && itanns != null) {
+        if (itanns != null) {
             ++attributeCount;
             size += 8 + itanns.getSize();
             newUTF8("RuntimeInvisibleTypeAnnotations");
         }
+        if (moduleWriter != null) {
+            attributeCount += 1 + moduleWriter.attributeCount;
+            size += 6 + moduleWriter.size + moduleWriter.attributesSize;
+            newUTF8("Module");
+        }
         if (attrs != null) {
             attributeCount += attrs.getCount();
             size += attrs.getSize(this, null, 0, -1, -1);
@@ -968,7 +997,7 @@
                     bootstrapMethodsCount);
             out.putByteArray(bootstrapMethods.data, 0, bootstrapMethods.length);
         }
-        if (ClassReader.SIGNATURES && signature != 0) {
+        if (signature != 0) {
             out.putShort(newUTF8("Signature")).putInt(2).putShort(signature);
         }
         if (sourceFile != 0) {
@@ -979,6 +1008,11 @@
             out.putShort(newUTF8("SourceDebugExtension")).putInt(len);
             out.putByteArray(sourceDebug.data, 0, len);
         }
+        if (moduleWriter != null) {
+            out.putShort(newUTF8("Module"));
+            moduleWriter.put(out);
+            moduleWriter.putAttributes(out);
+        }
         if (enclosingMethodOwner != 0) {
             out.putShort(newUTF8("EnclosingMethod")).putInt(4);
             out.putShort(enclosingMethodOwner).putShort(enclosingMethod);
@@ -997,41 +1031,46 @@
             out.putInt(innerClasses.length + 2).putShort(innerClassesCount);
             out.putByteArray(innerClasses.data, 0, innerClasses.length);
         }
-        if (ClassReader.ANNOTATIONS && anns != null) {
+        if (anns != null) {
             out.putShort(newUTF8("RuntimeVisibleAnnotations"));
             anns.put(out);
         }
-        if (ClassReader.ANNOTATIONS && ianns != null) {
+        if (ianns != null) {
             out.putShort(newUTF8("RuntimeInvisibleAnnotations"));
             ianns.put(out);
         }
-        if (ClassReader.ANNOTATIONS && tanns != null) {
+        if (tanns != null) {
             out.putShort(newUTF8("RuntimeVisibleTypeAnnotations"));
             tanns.put(out);
         }
-        if (ClassReader.ANNOTATIONS && itanns != null) {
+        if (itanns != null) {
             out.putShort(newUTF8("RuntimeInvisibleTypeAnnotations"));
             itanns.put(out);
         }
         if (attrs != null) {
             attrs.put(this, null, 0, -1, -1, out);
         }
-        if (invalidFrames) {
+        if (hasAsmInsns) {
+            boolean hasFrames = false;
+            mb = firstMethod;
+            while (mb != null) {
+                hasFrames |= mb.frameCount > 0;
+                mb = (MethodWriter) mb.mv;
+            }
             anns = null;
             ianns = null;
             attrs = null;
-            innerClassesCount = 0;
-            innerClasses = null;
-            bootstrapMethodsCount = 0;
-            bootstrapMethods = null;
+            moduleWriter = null;
             firstField = null;
             lastField = null;
             firstMethod = null;
             lastMethod = null;
-            computeMaxs = false;
-            computeFrames = true;
-            invalidFrames = false;
-            new ClassReader(out.data).accept(this, ClassReader.SKIP_FRAMES);
+            compute =
+                hasFrames ? MethodWriter.INSERTED_FRAMES : MethodWriter.NOTHING;
+            hasAsmInsns = false;
+            new ClassReader(out.data).accept(this,
+                    (hasFrames ? ClassReader.EXPAND_FRAMES : 0)
+                    | ClassReader.EXPAND_ASM_INSNS);
             return toByteArray();
         }
         return out.data;
@@ -1078,16 +1117,16 @@
             double val = ((Double) cst).doubleValue();
             return newDouble(val);
         } else if (cst instanceof String) {
-            return newString((String) cst);
+            return newStringishItem(STR, (String) cst);
         } else if (cst instanceof Type) {
             Type t = (Type) cst;
             int s = t.getSort();
             if (s == Type.OBJECT) {
-                return newClassItem(t.getInternalName());
+                return newStringishItem(CLASS, t.getInternalName());
             } else if (s == Type.METHOD) {
-                return newMethodTypeItem(t.getDescriptor());
+                return newStringishItem(MTYPE, t.getDescriptor());
             } else { // s == primitive type or array
-                return newClassItem(t.getDescriptor());
+                return newStringishItem(CLASS, t.getDescriptor());
             }
         } else if (cst instanceof Handle) {
             Handle h = (Handle) cst;
@@ -1136,20 +1175,21 @@
     }
 
     /**
-     * Adds a class reference to the constant pool of the class being build.
+     * Adds a string reference, a class reference, a method type, a module
+     * or a package to the constant pool of the class being build.
      * Does nothing if the constant pool already contains a similar item.
-     * <i>This method is intended for {@link Attribute} sub classes, and is
-     * normally not needed by class generators or adapters.</i>
      *
+     * @param type
+     *            a type among STR, CLASS, MTYPE, MODULE or PACKAGE
      * @param value
-     *            the internal name of the class.
-     * @return a new or already existing class reference item.
+     *            string value of the reference.
+     * @return a new or already existing reference item.
      */
-    Item newClassItem(final String value) {
-        key2.set(CLASS, value, null, null);
+    Item newStringishItem(final int type, final String value) {
+        key2.set(type, value, null, null);
         Item result = get(key2);
         if (result == null) {
-            pool.put12(CLASS, newUTF8(value));
+            pool.put12(type, newUTF8(value));
             result = new Item(index++, key2);
             put(result);
         }
@@ -1167,72 +1207,7 @@
      * @return the index of a new or already existing class reference item.
      */
     public int newClass(final String value) {
-        return newClassItem(value).index;
-    }
-
-    /**
-     * Adds a module name to the constant pool.
-     *
-     * Does nothing if the constant pool already contains a similar item.
-     * <i>This method is intended for {@link Attribute} sub classes, and is
-     * normally not needed by class generators or adapters.</i>
-     *
-     * @param  value
-     *         the module name
-     * @return the index of a new or already existing module reference item.
-     */
-    public int newModule(String value) {
-        key2.set(MODULE, value, null, null);
-        Item result = get(key2);
-        if (result == null) {
-            pool.put12(MODULE, newUTF8(value));
-            result = new Item(index++, key2);
-            put(result);
-        }
-        return result.index;
-    }
-
-    /**
-     * Adds a package name to the constant pool.
-     *
-     * Does nothing if the constant pool already contains a similar item.
-     * <i>This method is intended for {@link Attribute} sub classes, and is
-     * normally not needed by class generators or adapters.</i>
-     *
-     * @param  value
-     *         the internal name of the package.
-     * @return the index of a new or already existing package reference item.
-     */
-    public int newPackage(String value) {
-        key2.set(PACKAGE, value, null, null);
-        Item result = get(key2);
-        if (result == null) {
-            pool.put12(PACKAGE, newUTF8(value));
-            result = new Item(index++, key2);
-            put(result);
-        }
-        return result.index;
-    }
-
-    /**
-     * Adds a method type reference to the constant pool of the class being
-     * build. Does nothing if the constant pool already contains a similar item.
-     * <i>This method is intended for {@link Attribute} sub classes, and is
-     * normally not needed by class generators or adapters.</i>
-     *
-     * @param methodDesc
-     *            method descriptor of the method type.
-     * @return a new or already existing method type reference item.
-     */
-    Item newMethodTypeItem(final String methodDesc) {
-        key2.set(MTYPE, methodDesc, null, null);
-        Item result = get(key2);
-        if (result == null) {
-            pool.put12(MTYPE, newUTF8(methodDesc));
-            result = new Item(index++, key2);
-            put(result);
-        }
-        return result;
+        return newStringishItem(CLASS, value).index;
     }
 
     /**
@@ -1247,7 +1222,37 @@
      *         item.
      */
     public int newMethodType(final String methodDesc) {
-        return newMethodTypeItem(methodDesc).index;
+        return newStringishItem(MTYPE, methodDesc).index;
+    }
+
+    /**
+     * Adds a module reference to the constant pool of the class being
+     * build. Does nothing if the constant pool already contains a similar item.
+     * <i>This method is intended for {@link Attribute} sub classes, and is
+     * normally not needed by class generators or adapters.</i>
+     *
+     * @param moduleName
+     *            name of the module.
+     * @return the index of a new or already existing module reference
+     *         item.
+     */
+    public int newModule(final String moduleName) {
+        return newStringishItem(MODULE, moduleName).index;
+    }
+
+    /**
+     * Adds a package reference to the constant pool of the class being
+     * build. Does nothing if the constant pool already contains a similar item.
+     * <i>This method is intended for {@link Attribute} sub classes, and is
+     * normally not needed by class generators or adapters.</i>
+     *
+     * @param packageName
+     *            name of the package in its internal form.
+     * @return the index of a new or already existing module reference
+     *         item.
+     */
+    public int newPackage(final String packageName) {
+        return newStringishItem(PACKAGE, packageName).index;
     }
 
     /**
@@ -1629,25 +1634,6 @@
     }
 
     /**
-     * Adds a string to the constant pool of the class being build. Does nothing
-     * if the constant pool already contains a similar item.
-     *
-     * @param value
-     *            the String value.
-     * @return a new or already existing string item.
-     */
-    private Item newString(final String value) {
-        key2.set(STR, value, null, null);
-        Item result = get(key2);
-        if (result == null) {
-            pool.put12(STR, newUTF8(value));
-            result = new Item(index++, key2);
-            put(result);
-        }
-        return result;
-    }
-
-    /**
      * Adds a name and type to the constant pool of the class being build. Does
      * nothing if the constant pool already contains a similar item. <i>This
      * method is intended for {@link Attribute} sub classes, and is normally not
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/CurrentFrame.java	Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,85 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jdk.internal.org.objectweb.asm;
+
+/**
+ * Information about the input stack map frame at the "current" instruction of a
+ * method. This is implemented as a Frame subclass for a "basic block"
+ * containing only one instruction.
+ *
+ * @author Eric Bruneton
+ */
+class CurrentFrame extends Frame {
+
+    /**
+     * Sets this CurrentFrame to the input stack map frame of the next "current"
+     * instruction, i.e. the instruction just after the given one. It is assumed
+     * that the value of this object when this method is called is the stack map
+     * frame status just before the given instruction is executed.
+     */
+    @Override
+    void execute(int opcode, int arg, ClassWriter cw, Item item) {
+        super.execute(opcode, arg, cw, item);
+        Frame successor = new Frame();
+        merge(cw, successor, 0);
+        set(successor);
+        owner.inputStackTop = 0;
+    }
+}
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/FieldVisitor.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/FieldVisitor.java	Wed Nov 08 16:03:35 2017 -0500
@@ -69,7 +69,7 @@
 
     /**
      * The ASM API version implemented by this visitor. The value of this field
-     * must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     * must be one of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      */
     protected final int api;
 
@@ -84,7 +84,7 @@
      *
      * @param api
      *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      */
     public FieldVisitor(final int api) {
         this(api, null);
@@ -95,13 +95,13 @@
      *
      * @param api
      *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      * @param fv
      *            the field visitor to which this visitor must delegate method
      *            calls. May be null.
      */
     public FieldVisitor(final int api, final FieldVisitor fv) {
-        if (api != Opcodes.ASM4 && api != Opcodes.ASM5) {
+        if (api < Opcodes.ASM4 || api > Opcodes.ASM6) {
             throw new IllegalArgumentException();
         }
         this.api = api;
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/FieldWriter.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/FieldWriter.java	Wed Nov 08 16:03:35 2017 -0500
@@ -147,7 +147,7 @@
      */
     FieldWriter(final ClassWriter cw, final int access, final String name,
             final String desc, final String signature, final Object value) {
-        super(Opcodes.ASM5);
+        super(Opcodes.ASM6);
         if (cw.firstField == null) {
             cw.firstField = this;
         } else {
@@ -158,7 +158,7 @@
         this.access = access;
         this.name = cw.newUTF8(name);
         this.desc = cw.newUTF8(desc);
-        if (ClassReader.SIGNATURES && signature != null) {
+        if (signature != null) {
             this.signature = cw.newUTF8(signature);
         }
         if (value != null) {
@@ -173,9 +173,6 @@
     @Override
     public AnnotationVisitor visitAnnotation(final String desc,
             final boolean visible) {
-        if (!ClassReader.ANNOTATIONS) {
-            return null;
-        }
         ByteVector bv = new ByteVector();
         // write type, and reserve space for values count
         bv.putShort(cw.newUTF8(desc)).putShort(0);
@@ -193,9 +190,6 @@
     @Override
     public AnnotationVisitor visitTypeAnnotation(final int typeRef,
             final TypePath typePath, final String desc, final boolean visible) {
-        if (!ClassReader.ANNOTATIONS) {
-            return null;
-        }
         ByteVector bv = new ByteVector();
         // write target_type and target_info
         AnnotationWriter.putTarget(typeRef, typePath, bv);
@@ -249,23 +243,23 @@
             cw.newUTF8("Deprecated");
             size += 6;
         }
-        if (ClassReader.SIGNATURES && signature != 0) {
+        if (signature != 0) {
             cw.newUTF8("Signature");
             size += 8;
         }
-        if (ClassReader.ANNOTATIONS && anns != null) {
+        if (anns != null) {
             cw.newUTF8("RuntimeVisibleAnnotations");
             size += 8 + anns.getSize();
         }
-        if (ClassReader.ANNOTATIONS && ianns != null) {
+        if (ianns != null) {
             cw.newUTF8("RuntimeInvisibleAnnotations");
             size += 8 + ianns.getSize();
         }
-        if (ClassReader.ANNOTATIONS && tanns != null) {
+        if (tanns != null) {
             cw.newUTF8("RuntimeVisibleTypeAnnotations");
             size += 8 + tanns.getSize();
         }
-        if (ClassReader.ANNOTATIONS && itanns != null) {
+        if (itanns != null) {
             cw.newUTF8("RuntimeInvisibleTypeAnnotations");
             size += 8 + itanns.getSize();
         }
@@ -299,19 +293,19 @@
         if ((access & Opcodes.ACC_DEPRECATED) != 0) {
             ++attributeCount;
         }
-        if (ClassReader.SIGNATURES && signature != 0) {
+        if (signature != 0) {
             ++attributeCount;
         }
-        if (ClassReader.ANNOTATIONS && anns != null) {
+        if (anns != null) {
             ++attributeCount;
         }
-        if (ClassReader.ANNOTATIONS && ianns != null) {
+        if (ianns != null) {
             ++attributeCount;
         }
-        if (ClassReader.ANNOTATIONS && tanns != null) {
+        if (tanns != null) {
             ++attributeCount;
         }
-        if (ClassReader.ANNOTATIONS && itanns != null) {
+        if (itanns != null) {
             ++attributeCount;
         }
         if (attrs != null) {
@@ -331,23 +325,23 @@
         if ((access & Opcodes.ACC_DEPRECATED) != 0) {
             out.putShort(cw.newUTF8("Deprecated")).putInt(0);
         }
-        if (ClassReader.SIGNATURES && signature != 0) {
+        if (signature != 0) {
             out.putShort(cw.newUTF8("Signature"));
             out.putInt(2).putShort(signature);
         }
-        if (ClassReader.ANNOTATIONS && anns != null) {
+        if (anns != null) {
             out.putShort(cw.newUTF8("RuntimeVisibleAnnotations"));
             anns.put(out);
         }
-        if (ClassReader.ANNOTATIONS && ianns != null) {
+        if (ianns != null) {
             out.putShort(cw.newUTF8("RuntimeInvisibleAnnotations"));
             ianns.put(out);
         }
-        if (ClassReader.ANNOTATIONS && tanns != null) {
+        if (tanns != null) {
             out.putShort(cw.newUTF8("RuntimeVisibleTypeAnnotations"));
             tanns.put(out);
         }
-        if (ClassReader.ANNOTATIONS && itanns != null) {
+        if (itanns != null) {
             out.putShort(cw.newUTF8("RuntimeInvisibleTypeAnnotations"));
             itanns.put(out);
         }
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Frame.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Frame.java	Wed Nov 08 16:03:35 2017 -0500
@@ -63,7 +63,7 @@
  *
  * @author Eric Bruneton
  */
-final class Frame {
+class Frame {
 
     /*
      * Frames are computed in a two steps process: during the visit of each
@@ -525,7 +525,7 @@
      * When the stack map frames are completely computed, this field is the
      * actual number of types in {@link #outputStack}.
      */
-    private int outputStackTop;
+    int outputStackTop;
 
     /**
      * Number of types that are initialized in the basic block.
@@ -550,6 +550,110 @@
     private int[] initializations;
 
     /**
+     * Sets this frame to the given value.
+     *
+     * @param cw
+     *            the ClassWriter to which this label belongs.
+     * @param nLocal
+     *            the number of local variables.
+     * @param local
+     *            the local variable types. Primitive types are represented by
+     *            {@link Opcodes#TOP}, {@link Opcodes#INTEGER},
+     *            {@link Opcodes#FLOAT}, {@link Opcodes#LONG},
+     *            {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or
+     *            {@link Opcodes#UNINITIALIZED_THIS} (long and double are
+     *            represented by a single element). Reference types are
+     *            represented by String objects (representing internal names),
+     *            and uninitialized types by Label objects (this label
+     *            designates the NEW instruction that created this uninitialized
+     *            value).
+     * @param nStack
+     *            the number of operand stack elements.
+     * @param stack
+     *            the operand stack types (same format as the "local" array).
+     */
+    final void set(ClassWriter cw, final int nLocal, final Object[] local,
+            final int nStack, final Object[] stack) {
+        int i = convert(cw, nLocal, local, inputLocals);
+        while (i < local.length) {
+            inputLocals[i++] = TOP;
+        }
+        int nStackTop = 0;
+        for (int j = 0; j < nStack; ++j) {
+            if (stack[j] == Opcodes.LONG || stack[j] == Opcodes.DOUBLE) {
+                ++nStackTop;
+            }
+        }
+        inputStack = new int[nStack + nStackTop];
+        convert(cw, nStack, stack, inputStack);
+        outputStackTop = 0;
+        initializationCount = 0;
+    }
+
+    /**
+     * Converts types from the MethodWriter.visitFrame() format to the Frame
+     * format.
+     *
+     * @param cw
+     *            the ClassWriter to which this label belongs.
+     * @param nInput
+     *            the number of types to convert.
+     * @param input
+     *            the types to convert. Primitive types are represented by
+     *            {@link Opcodes#TOP}, {@link Opcodes#INTEGER},
+     *            {@link Opcodes#FLOAT}, {@link Opcodes#LONG},
+     *            {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or
+     *            {@link Opcodes#UNINITIALIZED_THIS} (long and double are
+     *            represented by a single element). Reference types are
+     *            represented by String objects (representing internal names),
+     *            and uninitialized types by Label objects (this label
+     *            designates the NEW instruction that created this uninitialized
+     *            value).
+     * @param output
+     *            where to store the converted types.
+     * @return the number of output elements.
+     */
+    private static int convert(ClassWriter cw, int nInput, Object[] input,
+            int[] output) {
+        int i = 0;
+        for (int j = 0; j < nInput; ++j) {
+            if (input[j] instanceof Integer) {
+                output[i++] = BASE | ((Integer) input[j]).intValue();
+                if (input[j] == Opcodes.LONG || input[j] == Opcodes.DOUBLE) {
+                    output[i++] = TOP;
+                }
+            } else if (input[j] instanceof String) {
+                output[i++] = type(cw, Type.getObjectType((String) input[j])
+                        .getDescriptor());
+            } else {
+                output[i++] = UNINITIALIZED
+                        | cw.addUninitializedType("",
+                                ((Label) input[j]).position);
+            }
+        }
+        return i;
+    }
+
+    /**
+     * Sets this frame to the value of the given frame. WARNING: after this
+     * method is called the two frames share the same data structures. It is
+     * recommended to discard the given frame f to avoid unexpected side
+     * effects.
+     *
+     * @param f
+     *            The new frame value.
+     */
+    final void set(final Frame f) {
+        inputLocals = f.inputLocals;
+        inputStack = f.inputStack;
+        outputLocals = f.outputLocals;
+        outputStack = f.outputStack;
+        outputStackTop = f.outputStackTop;
+        initializationCount = f.initializationCount;
+        initializations = f.initializations;
+    }
+
+    /**
      * Returns the output frame local variable type at the given index.
      *
      * @param local
@@ -614,7 +718,7 @@
         }
         // pushes the type on the output stack
         outputStack[outputStackTop++] = type;
-        // updates the maximun height reached by the output stack, if needed
+        // updates the maximum height reached by the output stack, if needed
         int top = owner.inputStackTop + outputStackTop;
         if (top > owner.outputStackMax) {
             owner.outputStackMax = top;
@@ -650,7 +754,7 @@
      *            a type descriptor.
      * @return the int encoding of the given type.
      */
-    private static int type(final ClassWriter cw, final String desc) {
+    static int type(final ClassWriter cw, final String desc) {
         String t;
         int index = desc.charAt(0) == '(' ? desc.indexOf(')') + 1 : 0;
         switch (desc.charAt(index)) {
@@ -838,7 +942,7 @@
      * @param maxLocals
      *            the maximum number of local variables of this method.
      */
-    void initInputFrame(final ClassWriter cw, final int access,
+    final void initInputFrame(final ClassWriter cw, final int access,
             final Type[] args, final int maxLocals) {
         inputLocals = new int[maxLocals];
         inputStack = new int[0];
@@ -981,7 +1085,7 @@
         case Opcodes.AALOAD:
             pop(1);
             t1 = pop();
-            push(ELEMENT_OF + t1);
+            push(t1 == NULL ? t1 : ELEMENT_OF + t1);
             break;
         case Opcodes.ISTORE:
         case Opcodes.FSTORE:
@@ -1312,7 +1416,7 @@
      * @return <tt>true</tt> if the input frame of the given label has been
      *         changed by this operation.
      */
-    boolean merge(final ClassWriter cw, final Frame frame, final int edge) {
+    final boolean merge(final ClassWriter cw, final Frame frame, final int edge) {
         boolean changed = false;
         int i, s, dim, kind, t;
 
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Item.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Item.java	Wed Nov 08 16:03:35 2017 -0500
@@ -80,6 +80,7 @@
      * {@link ClassWriter#STR}, {@link ClassWriter#CLASS},
      * {@link ClassWriter#NAME_TYPE}, {@link ClassWriter#FIELD},
      * {@link ClassWriter#METH}, {@link ClassWriter#IMETH},
+     * {@link ClassWriter#MODULE}, {@link ClassWriter#PACKAGE},
      * {@link ClassWriter#MTYPE}, {@link ClassWriter#INDY}.
      *
      * MethodHandle constant 9 variations are stored using a range of 9 values
@@ -239,12 +240,12 @@
         this.strVal3 = strVal3;
         switch (type) {
         case ClassWriter.CLASS:
-        case ClassWriter.MODULE:
-        case ClassWriter.PACKAGE:
             this.intVal = 0;     // intVal of a class must be zero, see visitInnerClass
         case ClassWriter.UTF8:
         case ClassWriter.STR:
         case ClassWriter.MTYPE:
+        case ClassWriter.MODULE:
+        case ClassWriter.PACKAGE:
         case ClassWriter.TYPE_NORMAL:
             hashCode = 0x7FFFFFFF & (type + strVal1.hashCode());
             return;
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Label.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Label.java	Wed Nov 08 16:03:35 2017 -0500
@@ -389,13 +389,12 @@
      *            the position of this label in the bytecode.
      * @param data
      *            the bytecode of the method.
-     * @return <tt>true</tt> if a blank that was left for this label was to
+     * @return <tt>true</tt> if a blank that was left for this label was too
      *         small to store the offset. In such a case the corresponding jump
      *         instruction is replaced with a pseudo instruction (using unused
      *         opcodes) using an unsigned two bytes offset. These pseudo
-     *         instructions will need to be replaced with true instructions with
-     *         wider offsets (4 bytes instead of 2). This is done in
-     *         {@link MethodWriter#resizeInstructions}.
+     *         instructions will be replaced with standard bytecode instructions
+     *         with wider offsets (4 bytes instead of 2), in ClassReader.
      * @throws IllegalArgumentException
      *             if this label has already been resolved, or if it has not
      *             been created by the given code writer.
@@ -454,7 +453,7 @@
      * @return the first label of the series to which this label belongs.
      */
     Label getFirst() {
-        return !ClassReader.FRAMES || frame == null ? this : frame.owner;
+        return frame == null ? this : frame.owner;
     }
 
     // ------------------------------------------------------------------------
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/MethodVisitor.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/MethodVisitor.java	Wed Nov 08 16:03:35 2017 -0500
@@ -86,7 +86,7 @@
 
     /**
      * The ASM API version implemented by this visitor. The value of this field
-     * must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     * must be one of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      */
     protected final int api;
 
@@ -101,7 +101,7 @@
      *
      * @param api
      *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      */
     public MethodVisitor(final int api) {
         this(api, null);
@@ -112,13 +112,13 @@
      *
      * @param api
      *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      * @param mv
      *            the method visitor to which this visitor must delegate method
      *            calls. May be null.
      */
     public MethodVisitor(final int api, final MethodVisitor mv) {
-        if (api != Opcodes.ASM4 && api != Opcodes.ASM5) {
+        if (api < Opcodes.ASM4 || api > Opcodes.ASM6) {
             throw new IllegalArgumentException();
         }
         this.api = api;
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/MethodWriter.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/MethodWriter.java	Wed Nov 08 16:03:35 2017 -0500
@@ -128,7 +128,19 @@
      *
      * @see #compute
      */
-    private static final int FRAMES = 0;
+    static final int FRAMES = 0;
+
+    /**
+     * Indicates that the stack map frames of type F_INSERT must be computed.
+     * The other frames are not (re)computed. They should all be of type F_NEW
+     * and should be sufficient to compute the content of the F_INSERT frames,
+     * together with the bytecode instructions between a F_NEW and a F_INSERT
+     * frame - and without any knowledge of the type hierarchy (by definition of
+     * F_INSERT).
+     *
+     * @see #compute
+     */
+    static final int INSERTED_FRAMES = 1;
 
     /**
      * Indicates that the maximum stack size and number of local variables must
@@ -136,14 +148,14 @@
      *
      * @see #compute
      */
-    private static final int MAXS = 1;
+    static final int MAXS = 2;
 
     /**
      * Indicates that nothing must be automatically computed.
      *
      * @see #compute
      */
-    private static final int NOTHING = 2;
+    static final int NOTHING = 3;
 
     /**
      * The class writer to which this method must be added.
@@ -277,7 +289,7 @@
     /**
      * Number of stack map frames in the StackMapTable attribute.
      */
-    private int frameCount;
+    int frameCount;
 
     /**
      * The StackMapTable attribute.
@@ -384,11 +396,6 @@
     private Attribute cattrs;
 
     /**
-     * Indicates if some jump instructions are too small and need to be resized.
-     */
-    private boolean resize;
-
-    /**
      * The number of subroutines in this method.
      */
     private int subroutines;
@@ -409,6 +416,7 @@
      * Indicates what must be automatically computed.
      *
      * @see #FRAMES
+     * @see #INSERTED_FRAMES
      * @see #MAXS
      * @see #NOTHING
      */
@@ -471,18 +479,13 @@
      * @param exceptions
      *            the internal names of the method's exceptions. May be
      *            <tt>null</tt>.
-     * @param computeMaxs
-     *            <tt>true</tt> if the maximum stack size and number of local
-     *            variables must be automatically computed.
-     * @param computeFrames
-     *            <tt>true</tt> if the stack map tables must be recomputed from
-     *            scratch.
+     * @param compute
+     *            Indicates what must be automatically computed (see #compute).
      */
     MethodWriter(final ClassWriter cw, final int access, final String name,
             final String desc, final String signature,
-            final String[] exceptions, final boolean computeMaxs,
-            final boolean computeFrames) {
-        super(Opcodes.ASM5);
+            final String[] exceptions, final int compute) {
+        super(Opcodes.ASM6);
         if (cw.firstMethod == null) {
             cw.firstMethod = this;
         } else {
@@ -497,9 +500,7 @@
         this.name = cw.newUTF8(name);
         this.desc = cw.newUTF8(desc);
         this.descriptor = desc;
-        if (ClassReader.SIGNATURES) {
-            this.signature = signature;
-        }
+        this.signature = signature;
         if (exceptions != null && exceptions.length > 0) {
             exceptionCount = exceptions.length;
             this.exceptions = new int[exceptionCount];
@@ -507,8 +508,8 @@
                 this.exceptions[i] = cw.newClass(exceptions[i]);
             }
         }
-        this.compute = computeFrames ? FRAMES : (computeMaxs ? MAXS : NOTHING);
-        if (computeMaxs || computeFrames) {
+        this.compute = compute;
+        if (compute != NOTHING) {
             // updates maxLocals
             int size = Type.getArgumentsAndReturnSizes(descriptor) >> 2;
             if ((access & Opcodes.ACC_STATIC) != 0) {
@@ -539,9 +540,6 @@
 
     @Override
     public AnnotationVisitor visitAnnotationDefault() {
-        if (!ClassReader.ANNOTATIONS) {
-            return null;
-        }
         annd = new ByteVector();
         return new AnnotationWriter(cw, false, annd, null, 0);
     }
@@ -549,9 +547,6 @@
     @Override
     public AnnotationVisitor visitAnnotation(final String desc,
             final boolean visible) {
-        if (!ClassReader.ANNOTATIONS) {
-            return null;
-        }
         ByteVector bv = new ByteVector();
         // write type, and reserve space for values count
         bv.putShort(cw.newUTF8(desc)).putShort(0);
@@ -569,9 +564,6 @@
     @Override
     public AnnotationVisitor visitTypeAnnotation(final int typeRef,
             final TypePath typePath, final String desc, final boolean visible) {
-        if (!ClassReader.ANNOTATIONS) {
-            return null;
-        }
         ByteVector bv = new ByteVector();
         // write target_type and target_info
         AnnotationWriter.putTarget(typeRef, typePath, bv);
@@ -592,9 +584,6 @@
     @Override
     public AnnotationVisitor visitParameterAnnotation(final int parameter,
             final String desc, final boolean visible) {
-        if (!ClassReader.ANNOTATIONS) {
-            return null;
-        }
         ByteVector bv = new ByteVector();
         if ("Ljava/lang/Synthetic;".equals(desc)) {
             // workaround for a bug in javac with synthetic parameters
@@ -639,11 +628,33 @@
     @Override
     public void visitFrame(final int type, final int nLocal,
             final Object[] local, final int nStack, final Object[] stack) {
-        if (!ClassReader.FRAMES || compute == FRAMES) {
+        if (compute == FRAMES) {
             return;
         }
 
-        if (type == Opcodes.F_NEW) {
+        if (compute == INSERTED_FRAMES) {
+            if (currentBlock.frame == null) {
+                // This should happen only once, for the implicit first frame
+                // (which is explicitly visited in ClassReader if the
+                // EXPAND_ASM_INSNS option is used).
+                currentBlock.frame = new CurrentFrame();
+                currentBlock.frame.owner = currentBlock;
+                currentBlock.frame.initInputFrame(cw, access,
+                        Type.getArgumentTypes(descriptor), nLocal);
+                visitImplicitFirstFrame();
+            } else {
+                if (type == Opcodes.F_NEW) {
+                    currentBlock.frame.set(cw, nLocal, local, nStack, stack);
+                } else {
+                    // In this case type is equal to F_INSERT by hypothesis, and
+                    // currentBlock.frame contains the stack map frame at the
+                    // current instruction, computed from the last F_NEW frame
+                    // and the bytecode instructions in between (via calls to
+                    // CurrentFrame#execute).
+                }
+                visitFrame(currentBlock.frame);
+            }
+        } else if (type == Opcodes.F_NEW) {
             if (previousFrame == null) {
                 visitImplicitFirstFrame();
             }
@@ -651,10 +662,10 @@
             int frameIndex = startFrame(code.length, nLocal, nStack);
             for (int i = 0; i < nLocal; ++i) {
                 if (local[i] instanceof String) {
-                    frame[frameIndex++] = Frame.OBJECT
-                            | cw.addType((String) local[i]);
+                    String desc = Type.getObjectType((String) local[i]).getDescriptor();
+                    frame[frameIndex++] = Frame.type(cw, desc);
                 } else if (local[i] instanceof Integer) {
-                    frame[frameIndex++] = ((Integer) local[i]).intValue();
+                    frame[frameIndex++] = Frame.BASE | ((Integer) local[i]).intValue();
                 } else {
                     frame[frameIndex++] = Frame.UNINITIALIZED
                             | cw.addUninitializedType("",
@@ -663,10 +674,10 @@
             }
             for (int i = 0; i < nStack; ++i) {
                 if (stack[i] instanceof String) {
-                    frame[frameIndex++] = Frame.OBJECT
-                            | cw.addType((String) stack[i]);
+                    String desc = Type.getObjectType((String) stack[i]).getDescriptor();
+                    frame[frameIndex++] = Frame.type(cw, desc);
                 } else if (stack[i] instanceof Integer) {
-                    frame[frameIndex++] = ((Integer) stack[i]).intValue();
+                    frame[frameIndex++] = Frame.BASE | ((Integer) stack[i]).intValue();
                 } else {
                     frame[frameIndex++] = Frame.UNINITIALIZED
                             | cw.addUninitializedType("",
@@ -747,7 +758,7 @@
         // update currentBlock
         // Label currentBlock = this.currentBlock;
         if (currentBlock != null) {
-            if (compute == FRAMES) {
+            if (compute == FRAMES || compute == INSERTED_FRAMES) {
                 currentBlock.frame.execute(opcode, 0, null, null);
             } else {
                 // updates current and max stack sizes
@@ -770,7 +781,7 @@
         lastCodeOffset = code.length;
         // Label currentBlock = this.currentBlock;
         if (currentBlock != null) {
-            if (compute == FRAMES) {
+            if (compute == FRAMES || compute == INSERTED_FRAMES) {
                 currentBlock.frame.execute(opcode, operand, null, null);
             } else if (opcode != Opcodes.NEWARRAY) {
                 // updates current and max stack sizes only for NEWARRAY
@@ -795,7 +806,7 @@
         lastCodeOffset = code.length;
         // Label currentBlock = this.currentBlock;
         if (currentBlock != null) {
-            if (compute == FRAMES) {
+            if (compute == FRAMES || compute == INSERTED_FRAMES) {
                 currentBlock.frame.execute(opcode, var, null, null);
             } else {
                 // updates current and max stack sizes
@@ -852,10 +863,10 @@
     @Override
     public void visitTypeInsn(final int opcode, final String type) {
         lastCodeOffset = code.length;
-        Item i = cw.newClassItem(type);
+        Item i = cw.newStringishItem(ClassWriter.CLASS, type);
         // Label currentBlock = this.currentBlock;
         if (currentBlock != null) {
-            if (compute == FRAMES) {
+            if (compute == FRAMES || compute == INSERTED_FRAMES) {
                 currentBlock.frame.execute(opcode, code.length, cw, i);
             } else if (opcode == Opcodes.NEW) {
                 // updates current and max stack sizes only if opcode == NEW
@@ -878,7 +889,7 @@
         Item i = cw.newFieldItem(owner, name, desc);
         // Label currentBlock = this.currentBlock;
         if (currentBlock != null) {
-            if (compute == FRAMES) {
+            if (compute == FRAMES || compute == INSERTED_FRAMES) {
                 currentBlock.frame.execute(opcode, 0, cw, i);
             } else {
                 int size;
@@ -918,7 +929,7 @@
         int argSize = i.intVal;
         // Label currentBlock = this.currentBlock;
         if (currentBlock != null) {
-            if (compute == FRAMES) {
+            if (compute == FRAMES || compute == INSERTED_FRAMES) {
                 currentBlock.frame.execute(opcode, 0, cw, i);
             } else {
                 /*
@@ -970,7 +981,7 @@
         int argSize = i.intVal;
         // Label currentBlock = this.currentBlock;
         if (currentBlock != null) {
-            if (compute == FRAMES) {
+            if (compute == FRAMES || compute == INSERTED_FRAMES) {
                 currentBlock.frame.execute(Opcodes.INVOKEDYNAMIC, 0, cw, i);
             } else {
                 /*
@@ -1004,7 +1015,9 @@
     }
 
     @Override
-    public void visitJumpInsn(final int opcode, final Label label) {
+    public void visitJumpInsn(int opcode, final Label label) {
+        boolean isWide = opcode >= 200; // GOTO_W
+        opcode = isWide ? opcode - 33 : opcode;
         lastCodeOffset = code.length;
         Label nextInsn = null;
         // Label currentBlock = this.currentBlock;
@@ -1019,6 +1032,8 @@
                     // creates a Label for the next basic block
                     nextInsn = new Label();
                 }
+            } else if (compute == INSERTED_FRAMES) {
+                currentBlock.frame.execute(opcode, 0, null, null);
             } else {
                 if (opcode == Opcodes.JSR) {
                     if ((label.status & Label.SUBROUTINE) == 0) {
@@ -1050,8 +1065,8 @@
             /*
              * case of a backward jump with an offset < -32768. In this case we
              * automatically replace GOTO with GOTO_W, JSR with JSR_W and IFxxx
-             * <l> with IFNOTxxx <l'> GOTO_W <l>, where IFNOTxxx is the
-             * "opposite" opcode of IFxxx (i.e., IFNE for IFEQ) and where <l'>
+             * <l> with IFNOTxxx <L> GOTO_W <l> L:..., where IFNOTxxx is the
+             * "opposite" opcode of IFxxx (i.e., IFNE for IFEQ) and where <L>
              * designates the instruction just after the GOTO_W.
              */
             if (opcode == Opcodes.GOTO) {
@@ -1067,9 +1082,21 @@
                 code.putByte(opcode <= 166 ? ((opcode + 1) ^ 1) - 1
                         : opcode ^ 1);
                 code.putShort(8); // jump offset
-                code.putByte(200); // GOTO_W
+                // ASM pseudo GOTO_W insn, see ClassReader. We don't use a real
+                // GOTO_W because we might need to insert a frame just after (as
+                // the target of the IFNOTxxx jump instruction).
+                code.putByte(220);
+                cw.hasAsmInsns = true;
             }
             label.put(this, code, code.length - 1, true);
+        } else if (isWide) {
+            /*
+             * case of a GOTO_W or JSR_W specified by the user (normally
+             * ClassReader when used to resize instructions). In this case we
+             * keep the original instruction.
+             */
+            code.putByte(opcode + 33);
+            label.put(this, code, code.length - 1, true);
         } else {
             /*
              * case of a backward jump with an offset >= -32768, or of a forward
@@ -1097,7 +1124,7 @@
     @Override
     public void visitLabel(final Label label) {
         // resolves previous forward references to label, if any
-        resize |= label.resolve(this, code.length, code.data);
+        cw.hasAsmInsns |= label.resolve(this, code.length, code.data);
         // updates currentBlock
         if ((label.status & Label.DEBUG) != 0) {
             return;
@@ -1130,6 +1157,18 @@
                 previousBlock.successor = label;
             }
             previousBlock = label;
+        } else if (compute == INSERTED_FRAMES) {
+            if (currentBlock == null) {
+                // This case should happen only once, for the visitLabel call in
+                // the constructor. Indeed, if compute is equal to
+                // INSERTED_FRAMES currentBlock can not be set back to null (see
+                // #noSuccessor).
+                currentBlock = label;
+            } else {
+                // Updates the frame owner so that a correct frame offset is
+                // computed in visitFrame(Frame).
+                currentBlock.frame.owner = label;
+            }
         } else if (compute == MAXS) {
             if (currentBlock != null) {
                 // ends current block (with one new successor)
@@ -1155,7 +1194,7 @@
         Item i = cw.newConstItem(cst);
         // Label currentBlock = this.currentBlock;
         if (currentBlock != null) {
-            if (compute == FRAMES) {
+            if (compute == FRAMES || compute == INSERTED_FRAMES) {
                 currentBlock.frame.execute(Opcodes.LDC, 0, cw, i);
             } else {
                 int size;
@@ -1187,7 +1226,7 @@
     public void visitIincInsn(final int var, final int increment) {
         lastCodeOffset = code.length;
         if (currentBlock != null) {
-            if (compute == FRAMES) {
+            if (compute == FRAMES || compute == INSERTED_FRAMES) {
                 currentBlock.frame.execute(Opcodes.IINC, var, null, null);
             }
         }
@@ -1271,10 +1310,10 @@
     @Override
     public void visitMultiANewArrayInsn(final String desc, final int dims) {
         lastCodeOffset = code.length;
-        Item i = cw.newClassItem(desc);
+        Item i = cw.newStringishItem(ClassWriter.CLASS, desc);
         // Label currentBlock = this.currentBlock;
         if (currentBlock != null) {
-            if (compute == FRAMES) {
+            if (compute == FRAMES || compute == INSERTED_FRAMES) {
                 currentBlock.frame.execute(Opcodes.MULTIANEWARRAY, dims, cw, i);
             } else {
                 // updates current stack size (max stack size unchanged because
@@ -1289,9 +1328,6 @@
     @Override
     public AnnotationVisitor visitInsnAnnotation(int typeRef,
             TypePath typePath, String desc, boolean visible) {
-        if (!ClassReader.ANNOTATIONS) {
-            return null;
-        }
         ByteVector bv = new ByteVector();
         // write target_type and target_info
         typeRef = (typeRef & 0xFF0000FF) | (lastCodeOffset << 8);
@@ -1331,9 +1367,6 @@
     @Override
     public AnnotationVisitor visitTryCatchAnnotation(int typeRef,
             TypePath typePath, String desc, boolean visible) {
-        if (!ClassReader.ANNOTATIONS) {
-            return null;
-        }
         ByteVector bv = new ByteVector();
         // write target_type and target_info
         AnnotationWriter.putTarget(typeRef, typePath, bv);
@@ -1387,9 +1420,6 @@
     public AnnotationVisitor visitLocalVariableAnnotation(int typeRef,
             TypePath typePath, Label[] start, Label[] end, int[] index,
             String desc, boolean visible) {
-        if (!ClassReader.ANNOTATIONS) {
-            return null;
-        }
         ByteVector bv = new ByteVector();
         // write target_type and target_info
         bv.putByte(typeRef >>> 24).putShort(start.length);
@@ -1430,15 +1460,7 @@
 
     @Override
     public void visitMaxs(final int maxStack, final int maxLocals) {
-        if (resize) {
-            // replaces the temporary jump opcodes introduced by Label.resolve.
-            if (ClassReader.RESIZE) {
-                resizeInstructions();
-            } else {
-                throw new RuntimeException("Method code too large!");
-            }
-        }
-        if (ClassReader.FRAMES && compute == FRAMES) {
+        if (compute == FRAMES) {
             // completes the control flow graph with exception handler blocks
             Handler handler = firstHandler;
             while (handler != null) {
@@ -1468,8 +1490,8 @@
 
             // creates and visits the first (implicit) frame
             Frame f = labels.frame;
-            Type[] args = Type.getArgumentTypes(descriptor);
-            f.initInputFrame(cw, access, args, this.maxLocals);
+            f.initInputFrame(cw, access, Type.getArgumentTypes(descriptor),
+                    this.maxLocals);
             visitFrame(f);
 
             /*
@@ -1717,7 +1739,9 @@
         } else {
             currentBlock.outputStackMax = maxStackSize;
         }
-        currentBlock = null;
+        if (compute != INSERTED_FRAMES) {
+            currentBlock = null;
+        }
     }
 
     // ------------------------------------------------------------------------
@@ -1789,7 +1813,7 @@
             if ((access & ACC_CONSTRUCTOR) == 0) {
                 frame[frameIndex++] = Frame.OBJECT | cw.addType(cw.thisName);
             } else {
-                frame[frameIndex++] = 6; // Opcodes.UNINITIALIZED_THIS;
+                frame[frameIndex++] = Frame.UNINITIALIZED_THIS;
             }
         }
         int i = 1;
@@ -1801,16 +1825,16 @@
             case 'B':
             case 'S':
             case 'I':
-                frame[frameIndex++] = 1; // Opcodes.INTEGER;
+                frame[frameIndex++] = Frame.INTEGER;
                 break;
             case 'F':
-                frame[frameIndex++] = 2; // Opcodes.FLOAT;
+                frame[frameIndex++] = Frame.FLOAT;
                 break;
             case 'J':
-                frame[frameIndex++] = 4; // Opcodes.LONG;
+                frame[frameIndex++] = Frame.LONG;
                 break;
             case 'D':
-                frame[frameIndex++] = 3; // Opcodes.DOUBLE;
+                frame[frameIndex++] = Frame.DOUBLE;
                 break;
             case '[':
                 while (descriptor.charAt(i) == '[') {
@@ -1822,8 +1846,7 @@
                         ++i;
                     }
                 }
-                frame[frameIndex++] = Frame.OBJECT
-                        | cw.addType(descriptor.substring(j, ++i));
+                frame[frameIndex++] = Frame.type(cw, descriptor.substring(j, ++i));
                 break;
             case 'L':
                 while (descriptor.charAt(i) != ';') {
@@ -2083,11 +2106,11 @@
                 cw.newUTF8(zip ? "StackMapTable" : "StackMap");
                 size += 8 + stackMap.length;
             }
-            if (ClassReader.ANNOTATIONS && ctanns != null) {
+            if (ctanns != null) {
                 cw.newUTF8("RuntimeVisibleTypeAnnotations");
                 size += 8 + ctanns.getSize();
             }
-            if (ClassReader.ANNOTATIONS && ictanns != null) {
+            if (ictanns != null) {
                 cw.newUTF8("RuntimeInvisibleTypeAnnotations");
                 size += 8 + ictanns.getSize();
             }
@@ -2111,7 +2134,7 @@
             cw.newUTF8("Deprecated");
             size += 6;
         }
-        if (ClassReader.SIGNATURES && signature != null) {
+        if (signature != null) {
             cw.newUTF8("Signature");
             cw.newUTF8(signature);
             size += 8;
@@ -2120,34 +2143,34 @@
             cw.newUTF8("MethodParameters");
             size += 7 + methodParameters.length;
         }
-        if (ClassReader.ANNOTATIONS && annd != null) {
+        if (annd != null) {
             cw.newUTF8("AnnotationDefault");
             size += 6 + annd.length;
         }
-        if (ClassReader.ANNOTATIONS && anns != null) {
+        if (anns != null) {
             cw.newUTF8("RuntimeVisibleAnnotations");
             size += 8 + anns.getSize();
         }
-        if (ClassReader.ANNOTATIONS && ianns != null) {
+        if (ianns != null) {
             cw.newUTF8("RuntimeInvisibleAnnotations");
             size += 8 + ianns.getSize();
         }
-        if (ClassReader.ANNOTATIONS && tanns != null) {
+        if (tanns != null) {
             cw.newUTF8("RuntimeVisibleTypeAnnotations");
             size += 8 + tanns.getSize();
         }
-        if (ClassReader.ANNOTATIONS && itanns != null) {
+        if (itanns != null) {
             cw.newUTF8("RuntimeInvisibleTypeAnnotations");
             size += 8 + itanns.getSize();
         }
-        if (ClassReader.ANNOTATIONS && panns != null) {
+        if (panns != null) {
             cw.newUTF8("RuntimeVisibleParameterAnnotations");
             size += 7 + 2 * (panns.length - synthetics);
             for (int i = panns.length - 1; i >= synthetics; --i) {
                 size += panns[i] == null ? 0 : panns[i].getSize();
             }
         }
-        if (ClassReader.ANNOTATIONS && ipanns != null) {
+        if (ipanns != null) {
             cw.newUTF8("RuntimeInvisibleParameterAnnotations");
             size += 7 + 2 * (ipanns.length - synthetics);
             for (int i = ipanns.length - 1; i >= synthetics; --i) {
@@ -2193,31 +2216,31 @@
         if ((access & Opcodes.ACC_DEPRECATED) != 0) {
             ++attributeCount;
         }
-        if (ClassReader.SIGNATURES && signature != null) {
+        if (signature != null) {
             ++attributeCount;
         }
         if (methodParameters != null) {
             ++attributeCount;
         }
-        if (ClassReader.ANNOTATIONS && annd != null) {
+        if (annd != null) {
             ++attributeCount;
         }
-        if (ClassReader.ANNOTATIONS && anns != null) {
+        if (anns != null) {
             ++attributeCount;
         }
-        if (ClassReader.ANNOTATIONS && ianns != null) {
+        if (ianns != null) {
             ++attributeCount;
         }
-        if (ClassReader.ANNOTATIONS && tanns != null) {
+        if (tanns != null) {
             ++attributeCount;
         }
-        if (ClassReader.ANNOTATIONS && itanns != null) {
+        if (itanns != null) {
             ++attributeCount;
         }
-        if (ClassReader.ANNOTATIONS && panns != null) {
+        if (panns != null) {
             ++attributeCount;
         }
-        if (ClassReader.ANNOTATIONS && ipanns != null) {
+        if (ipanns != null) {
             ++attributeCount;
         }
         if (attrs != null) {
@@ -2238,10 +2261,10 @@
             if (stackMap != null) {
                 size += 8 + stackMap.length;
             }
-            if (ClassReader.ANNOTATIONS && ctanns != null) {
+            if (ctanns != null) {
                 size += 8 + ctanns.getSize();
             }
-            if (ClassReader.ANNOTATIONS && ictanns != null) {
+            if (ictanns != null) {
                 size += 8 + ictanns.getSize();
             }
             if (cattrs != null) {
@@ -2273,10 +2296,10 @@
             if (stackMap != null) {
                 ++attributeCount;
             }
-            if (ClassReader.ANNOTATIONS && ctanns != null) {
+            if (ctanns != null) {
                 ++attributeCount;
             }
-            if (ClassReader.ANNOTATIONS && ictanns != null) {
+            if (ictanns != null) {
                 ++attributeCount;
             }
             if (cattrs != null) {
@@ -2304,11 +2327,11 @@
                 out.putInt(stackMap.length + 2).putShort(frameCount);
                 out.putByteArray(stackMap.data, 0, stackMap.length);
             }
-            if (ClassReader.ANNOTATIONS && ctanns != null) {
+            if (ctanns != null) {
                 out.putShort(cw.newUTF8("RuntimeVisibleTypeAnnotations"));
                 ctanns.put(out);
             }
-            if (ClassReader.ANNOTATIONS && ictanns != null) {
+            if (ictanns != null) {
                 out.putShort(cw.newUTF8("RuntimeInvisibleTypeAnnotations"));
                 ictanns.put(out);
             }
@@ -2333,7 +2356,7 @@
         if ((access & Opcodes.ACC_DEPRECATED) != 0) {
             out.putShort(cw.newUTF8("Deprecated")).putInt(0);
         }
-        if (ClassReader.SIGNATURES && signature != null) {
+        if (signature != null) {
             out.putShort(cw.newUTF8("Signature")).putInt(2)
                     .putShort(cw.newUTF8(signature));
         }
@@ -2343,32 +2366,32 @@
                     methodParametersCount);
             out.putByteArray(methodParameters.data, 0, methodParameters.length);
         }
-        if (ClassReader.ANNOTATIONS && annd != null) {
+        if (annd != null) {
             out.putShort(cw.newUTF8("AnnotationDefault"));
             out.putInt(annd.length);
             out.putByteArray(annd.data, 0, annd.length);
         }
-        if (ClassReader.ANNOTATIONS && anns != null) {
+        if (anns != null) {
             out.putShort(cw.newUTF8("RuntimeVisibleAnnotations"));
             anns.put(out);
         }
-        if (ClassReader.ANNOTATIONS && ianns != null) {
+        if (ianns != null) {
             out.putShort(cw.newUTF8("RuntimeInvisibleAnnotations"));
             ianns.put(out);
         }
-        if (ClassReader.ANNOTATIONS && tanns != null) {
+        if (tanns != null) {
             out.putShort(cw.newUTF8("RuntimeVisibleTypeAnnotations"));
             tanns.put(out);
         }
-        if (ClassReader.ANNOTATIONS && itanns != null) {
+        if (itanns != null) {
             out.putShort(cw.newUTF8("RuntimeInvisibleTypeAnnotations"));
             itanns.put(out);
         }
-        if (ClassReader.ANNOTATIONS && panns != null) {
+        if (panns != null) {
             out.putShort(cw.newUTF8("RuntimeVisibleParameterAnnotations"));
             AnnotationWriter.put(panns, synthetics, out);
         }
-        if (ClassReader.ANNOTATIONS && ipanns != null) {
+        if (ipanns != null) {
             out.putShort(cw.newUTF8("RuntimeInvisibleParameterAnnotations"));
             AnnotationWriter.put(ipanns, synthetics, out);
         }
@@ -2376,569 +2399,4 @@
             attrs.put(cw, null, 0, -1, -1, out);
         }
     }
-
-    // ------------------------------------------------------------------------
-    // Utility methods: instruction resizing (used to handle GOTO_W and JSR_W)
-    // ------------------------------------------------------------------------
-
-    /**
-     * Resizes and replaces the temporary instructions inserted by
-     * {@link Label#resolve} for wide forward jumps, while keeping jump offsets
-     * and instruction addresses consistent. This may require to resize other
-     * existing instructions, or even to introduce new instructions: for
-     * example, increasing the size of an instruction by 2 at the middle of a
-     * method can increases the offset of an IFEQ instruction from 32766 to
-     * 32768, in which case IFEQ 32766 must be replaced with IFNEQ 8 GOTO_W
-     * 32765. This, in turn, may require to increase the size of another jump
-     * instruction, and so on... All these operations are handled automatically
-     * by this method.
-     * <p>
-     * <i>This method must be called after all the method that is being built
-     * has been visited</i>. In particular, the {@link Label Label} objects used
-     * to construct the method are no longer valid after this method has been
-     * called.
-     */
-    private void resizeInstructions() {
-        byte[] b = code.data; // bytecode of the method
-        int u, v, label; // indexes in b
-        int i, j; // loop indexes
-        /*
-         * 1st step: As explained above, resizing an instruction may require to
-         * resize another one, which may require to resize yet another one, and
-         * so on. The first step of the algorithm consists in finding all the
-         * instructions that need to be resized, without modifying the code.
-         * This is done by the following "fix point" algorithm:
-         *
-         * Parse the code to find the jump instructions whose offset will need
-         * more than 2 bytes to be stored (the future offset is computed from
-         * the current offset and from the number of bytes that will be inserted
-         * or removed between the source and target instructions). For each such
-         * instruction, adds an entry in (a copy of) the indexes and sizes
-         * arrays (if this has not already been done in a previous iteration!).
-         *
-         * If at least one entry has been added during the previous step, go
-         * back to the beginning, otherwise stop.
-         *
-         * In fact the real algorithm is complicated by the fact that the size
-         * of TABLESWITCH and LOOKUPSWITCH instructions depends on their
-         * position in the bytecode (because of padding). In order to ensure the
-         * convergence of the algorithm, the number of bytes to be added or
-         * removed from these instructions is over estimated during the previous
-         * loop, and computed exactly only after the loop is finished (this
-         * requires another pass to parse the bytecode of the method).
-         */
-        int[] allIndexes = new int[0]; // copy of indexes
-        int[] allSizes = new int[0]; // copy of sizes
-        boolean[] resize; // instructions to be resized
-        int newOffset; // future offset of a jump instruction
-
-        resize = new boolean[code.length];
-
-        // 3 = loop again, 2 = loop ended, 1 = last pass, 0 = done
-        int state = 3;
-        do {
-            if (state == 3) {
-                state = 2;
-            }
-            u = 0;
-            while (u < b.length) {
-                int opcode = b[u] & 0xFF; // opcode of current instruction
-                int insert = 0; // bytes to be added after this instruction
-
-                switch (ClassWriter.TYPE[opcode]) {
-                case ClassWriter.NOARG_INSN:
-                case ClassWriter.IMPLVAR_INSN:
-                    u += 1;
-                    break;
-                case ClassWriter.LABEL_INSN:
-                    if (opcode > 201) {
-                        // converts temporary opcodes 202 to 217, 218 and
-                        // 219 to IFEQ ... JSR (inclusive), IFNULL and
-                        // IFNONNULL
-                        opcode = opcode < 218 ? opcode - 49 : opcode - 20;
-                        label = u + readUnsignedShort(b, u + 1);
-                    } else {
-                        label = u + readShort(b, u + 1);
-                    }
-                    newOffset = getNewOffset(allIndexes, allSizes, u, label);
-                    if (newOffset < Short.MIN_VALUE
-                            || newOffset > Short.MAX_VALUE) {
-                        if (!resize[u]) {
-                            if (opcode == Opcodes.GOTO || opcode == Opcodes.JSR) {
-                                // two additional bytes will be required to
-                                // replace this GOTO or JSR instruction with
-                                // a GOTO_W or a JSR_W
-                                insert = 2;
-                            } else {
-                                // five additional bytes will be required to
-                                // replace this IFxxx <l> instruction with
-                                // IFNOTxxx <l'> GOTO_W <l>, where IFNOTxxx
-                                // is the "opposite" opcode of IFxxx (i.e.,
-                                // IFNE for IFEQ) and where <l'> designates
-                                // the instruction just after the GOTO_W.
-                                insert = 5;
-                            }
-                            resize[u] = true;
-                        }
-                    }
-                    u += 3;
-                    break;
-                case ClassWriter.LABELW_INSN:
-                    u += 5;
-                    break;
-                case ClassWriter.TABL_INSN:
-                    if (state == 1) {
-                        // true number of bytes to be added (or removed)
-                        // from this instruction = (future number of padding
-                        // bytes - current number of padding byte) -
-                        // previously over estimated variation =
-                        // = ((3 - newOffset%4) - (3 - u%4)) - u%4
-                        // = (-newOffset%4 + u%4) - u%4
-                        // = -(newOffset & 3)
-                        newOffset = getNewOffset(allIndexes, allSizes, 0, u);
-                        insert = -(newOffset & 3);
-                    } else if (!resize[u]) {
-                        // over estimation of the number of bytes to be
-                        // added to this instruction = 3 - current number
-                        // of padding bytes = 3 - (3 - u%4) = u%4 = u & 3
-                        insert = u & 3;
-                        resize[u] = true;
-                    }
-                    // skips instruction
-                    u = u + 4 - (u & 3);
-                    u += 4 * (readInt(b, u + 8) - readInt(b, u + 4) + 1) + 12;
-                    break;
-                case ClassWriter.LOOK_INSN:
-                    if (state == 1) {
-                        // like TABL_INSN
-                        newOffset = getNewOffset(allIndexes, allSizes, 0, u);
-                        insert = -(newOffset & 3);
-                    } else if (!resize[u]) {
-                        // like TABL_INSN
-                        insert = u & 3;
-                        resize[u] = true;
-                    }
-                    // skips instruction
-                    u = u + 4 - (u & 3);
-                    u += 8 * readInt(b, u + 4) + 8;
-                    break;
-                case ClassWriter.WIDE_INSN:
-                    opcode = b[u + 1] & 0xFF;
-                    if (opcode == Opcodes.IINC) {
-                        u += 6;
-                    } else {
-                        u += 4;
-                    }
-                    break;
-                case ClassWriter.VAR_INSN:
-                case ClassWriter.SBYTE_INSN:
-                case ClassWriter.LDC_INSN:
-                    u += 2;
-                    break;
-                case ClassWriter.SHORT_INSN:
-                case ClassWriter.LDCW_INSN:
-                case ClassWriter.FIELDORMETH_INSN:
-                case ClassWriter.TYPE_INSN:
-                case ClassWriter.IINC_INSN:
-                    u += 3;
-                    break;
-                case ClassWriter.ITFMETH_INSN:
-                case ClassWriter.INDYMETH_INSN:
-                    u += 5;
-                    break;
-                // case ClassWriter.MANA_INSN:
-                default:
-                    u += 4;
-                    break;
-                }
-                if (insert != 0) {
-                    // adds a new (u, insert) entry in the allIndexes and
-                    // allSizes arrays
-                    int[] newIndexes = new int[allIndexes.length + 1];
-                    int[] newSizes = new int[allSizes.length + 1];
-                    System.arraycopy(allIndexes, 0, newIndexes, 0,
-                            allIndexes.length);
-                    System.arraycopy(allSizes, 0, newSizes, 0, allSizes.length);
-                    newIndexes[allIndexes.length] = u;
-                    newSizes[allSizes.length] = insert;
-                    allIndexes = newIndexes;
-                    allSizes = newSizes;
-                    if (insert > 0) {
-                        state = 3;
-                    }
-                }
-            }
-            if (state < 3) {
-                --state;
-            }
-        } while (state != 0);
-
-        // 2nd step:
-        // copies the bytecode of the method into a new bytevector, updates the
-        // offsets, and inserts (or removes) bytes as requested.
-
-        ByteVector newCode = new ByteVector(code.length);
-
-        u = 0;
-        while (u < code.length) {
-            int opcode = b[u] & 0xFF;
-            switch (ClassWriter.TYPE[opcode]) {
-            case ClassWriter.NOARG_INSN:
-            case ClassWriter.IMPLVAR_INSN:
-                newCode.putByte(opcode);
-                u += 1;
-                break;
-            case ClassWriter.LABEL_INSN:
-                if (opcode > 201) {
-                    // changes temporary opcodes 202 to 217 (inclusive), 218
-                    // and 219 to IFEQ ... JSR (inclusive), IFNULL and
-                    // IFNONNULL
-                    opcode = opcode < 218 ? opcode - 49 : opcode - 20;
-                    label = u + readUnsignedShort(b, u + 1);
-                } else {
-                    label = u + readShort(b, u + 1);
-                }
-                newOffset = getNewOffset(allIndexes, allSizes, u, label);
-                if (resize[u]) {
-                    // replaces GOTO with GOTO_W, JSR with JSR_W and IFxxx
-                    // <l> with IFNOTxxx <l'> GOTO_W <l>, where IFNOTxxx is
-                    // the "opposite" opcode of IFxxx (i.e., IFNE for IFEQ)
-                    // and where <l'> designates the instruction just after
-                    // the GOTO_W.
-                    if (opcode == Opcodes.GOTO) {
-                        newCode.putByte(200); // GOTO_W
-                    } else if (opcode == Opcodes.JSR) {
-                        newCode.putByte(201); // JSR_W
-                    } else {
-                        newCode.putByte(opcode <= 166 ? ((opcode + 1) ^ 1) - 1
-                                : opcode ^ 1);
-                        newCode.putShort(8); // jump offset
-                        newCode.putByte(200); // GOTO_W
-                        // newOffset now computed from start of GOTO_W
-                        newOffset -= 3;
-                    }
-                    newCode.putInt(newOffset);
-                } else {
-                    newCode.putByte(opcode);
-                    newCode.putShort(newOffset);
-                }
-                u += 3;
-                break;
-            case ClassWriter.LABELW_INSN:
-                label = u + readInt(b, u + 1);
-                newOffset = getNewOffset(allIndexes, allSizes, u, label);
-                newCode.putByte(opcode);
-                newCode.putInt(newOffset);
-                u += 5;
-                break;
-            case ClassWriter.TABL_INSN:
-                // skips 0 to 3 padding bytes
-                v = u;
-                u = u + 4 - (v & 3);
-                // reads and copies instruction
-                newCode.putByte(Opcodes.TABLESWITCH);
-                newCode.putByteArray(null, 0, (4 - newCode.length % 4) % 4);
-                label = v + readInt(b, u);
-                u += 4;
-                newOffset = getNewOffset(allIndexes, allSizes, v, label);
-                newCode.putInt(newOffset);
-                j = readInt(b, u);
-                u += 4;
-                newCode.putInt(j);
-                j = readInt(b, u) - j + 1;
-                u += 4;
-                newCode.putInt(readInt(b, u - 4));
-                for (; j > 0; --j) {
-                    label = v + readInt(b, u);
-                    u += 4;
-                    newOffset = getNewOffset(allIndexes, allSizes, v, label);
-                    newCode.putInt(newOffset);
-                }
-                break;
-            case ClassWriter.LOOK_INSN:
-                // skips 0 to 3 padding bytes
-                v = u;
-                u = u + 4 - (v & 3);
-                // reads and copies instruction
-                newCode.putByte(Opcodes.LOOKUPSWITCH);
-                newCode.putByteArray(null, 0, (4 - newCode.length % 4) % 4);
-                label = v + readInt(b, u);
-                u += 4;
-                newOffset = getNewOffset(allIndexes, allSizes, v, label);
-                newCode.putInt(newOffset);
-                j = readInt(b, u);
-                u += 4;
-                newCode.putInt(j);
-                for (; j > 0; --j) {
-                    newCode.putInt(readInt(b, u));
-                    u += 4;
-                    label = v + readInt(b, u);
-                    u += 4;
-                    newOffset = getNewOffset(allIndexes, allSizes, v, label);
-                    newCode.putInt(newOffset);
-                }
-                break;
-            case ClassWriter.WIDE_INSN:
-                opcode = b[u + 1] & 0xFF;
-                if (opcode == Opcodes.IINC) {
-                    newCode.putByteArray(b, u, 6);
-                    u += 6;
-                } else {
-                    newCode.putByteArray(b, u, 4);
-                    u += 4;
-                }
-                break;
-            case ClassWriter.VAR_INSN:
-            case ClassWriter.SBYTE_INSN:
-            case ClassWriter.LDC_INSN:
-                newCode.putByteArray(b, u, 2);
-                u += 2;
-                break;
-            case ClassWriter.SHORT_INSN:
-            case ClassWriter.LDCW_INSN:
-            case ClassWriter.FIELDORMETH_INSN:
-            case ClassWriter.TYPE_INSN:
-            case ClassWriter.IINC_INSN:
-                newCode.putByteArray(b, u, 3);
-                u += 3;
-                break;
-            case ClassWriter.ITFMETH_INSN:
-            case ClassWriter.INDYMETH_INSN:
-                newCode.putByteArray(b, u, 5);
-                u += 5;
-                break;
-            // case MANA_INSN:
-            default:
-                newCode.putByteArray(b, u, 4);
-                u += 4;
-                break;
-            }
-        }
-
-        // updates the stack map frame labels
-        if (compute == FRAMES) {
-            Label l = labels;
-            while (l != null) {
-                /*
-                 * Detects the labels that are just after an IF instruction that
-                 * has been resized with the IFNOT GOTO_W pattern. These labels
-                 * are now the target of a jump instruction (the IFNOT
-                 * instruction). Note that we need the original label position
-                 * here. getNewOffset must therefore never have been called for
-                 * this label.
-                 */
-                u = l.position - 3;
-                if (u >= 0 && resize[u]) {
-                    l.status |= Label.TARGET;
-                }
-                getNewOffset(allIndexes, allSizes, l);
-                l = l.successor;
-            }
-            // Update the offsets in the uninitialized types
-            if (cw.typeTable != null) {
-                for (i = 0; i < cw.typeTable.length; ++i) {
-                    Item item = cw.typeTable[i];
-                    if (item != null && item.type == ClassWriter.TYPE_UNINIT) {
-                        item.intVal = getNewOffset(allIndexes, allSizes, 0,
-                                item.intVal);
-                    }
-                }
-            }
-            // The stack map frames are not serialized yet, so we don't need
-            // to update them. They will be serialized in visitMaxs.
-        } else if (frameCount > 0) {
-            /*
-             * Resizing an existing stack map frame table is really hard. Not
-             * only the table must be parsed to update the offets, but new
-             * frames may be needed for jump instructions that were inserted by
-             * this method. And updating the offsets or inserting frames can
-             * change the format of the following frames, in case of packed
-             * frames. In practice the whole table must be recomputed. For this
-             * the frames are marked as potentially invalid. This will cause the
-             * whole class to be reread and rewritten with the COMPUTE_FRAMES
-             * option (see the ClassWriter.toByteArray method). This is not very
-             * efficient but is much easier and requires much less code than any
-             * other method I can think of.
-             */
-            cw.invalidFrames = true;
-        }
-        // updates the exception handler block labels
-        Handler h = firstHandler;
-        while (h != null) {
-            getNewOffset(allIndexes, allSizes, h.start);
-            getNewOffset(allIndexes, allSizes, h.end);
-            getNewOffset(allIndexes, allSizes, h.handler);
-            h = h.next;
-        }
-        // updates the instructions addresses in the
-        // local var and line number tables
-        for (i = 0; i < 2; ++i) {
-            ByteVector bv = i == 0 ? localVar : localVarType;
-            if (bv != null) {
-                b = bv.data;
-                u = 0;
-                while (u < bv.length) {
-                    label = readUnsignedShort(b, u);
-                    newOffset = getNewOffset(allIndexes, allSizes, 0, label);
-                    writeShort(b, u, newOffset);
-                    label += readUnsignedShort(b, u + 2);
-                    newOffset = getNewOffset(allIndexes, allSizes, 0, label)
-                            - newOffset;
-                    writeShort(b, u + 2, newOffset);
-                    u += 10;
-                }
-            }
-        }
-        if (lineNumber != null) {
-            b = lineNumber.data;
-            u = 0;
-            while (u < lineNumber.length) {
-                writeShort(
-                        b,
-                        u,
-                        getNewOffset(allIndexes, allSizes, 0,
-                                readUnsignedShort(b, u)));
-                u += 4;
-            }
-        }
-        // updates the labels of the other attributes
-        Attribute attr = cattrs;
-        while (attr != null) {
-            Label[] labels = attr.getLabels();
-            if (labels != null) {
-                for (i = labels.length - 1; i >= 0; --i) {
-                    getNewOffset(allIndexes, allSizes, labels[i]);
-                }
-            }
-            attr = attr.next;
-        }
-
-        // replaces old bytecodes with new ones
-        code = newCode;
-    }
-
-    /**
-     * Reads an unsigned short value in the given byte array.
-     *
-     * @param b
-     *            a byte array.
-     * @param index
-     *            the start index of the value to be read.
-     * @return the read value.
-     */
-    static int readUnsignedShort(final byte[] b, final int index) {
-        return ((b[index] & 0xFF) << 8) | (b[index + 1] & 0xFF);
-    }
-
-    /**
-     * Reads a signed short value in the given byte array.
-     *
-     * @param b
-     *            a byte array.
-     * @param index
-     *            the start index of the value to be read.
-     * @return the read value.
-     */
-    static short readShort(final byte[] b, final int index) {
-        return (short) (((b[index] & 0xFF) << 8) | (b[index + 1] & 0xFF));
-    }
-
-    /**
-     * Reads a signed int value in the given byte array.
-     *
-     * @param b
-     *            a byte array.
-     * @param index
-     *            the start index of the value to be read.
-     * @return the read value.
-     */
-    static int readInt(final byte[] b, final int index) {
-        return ((b[index] & 0xFF) << 24) | ((b[index + 1] & 0xFF) << 16)
-                | ((b[index + 2] & 0xFF) << 8) | (b[index + 3] & 0xFF);
-    }
-
-    /**
-     * Writes a short value in the given byte array.
-     *
-     * @param b
-     *            a byte array.
-     * @param index
-     *            where the first byte of the short value must be written.
-     * @param s
-     *            the value to be written in the given byte array.
-     */
-    static void writeShort(final byte[] b, final int index, final int s) {
-        b[index] = (byte) (s >>> 8);
-        b[index + 1] = (byte) s;
-    }
-
-    /**
-     * Computes the future value of a bytecode offset.
-     * <p>
-     * Note: it is possible to have several entries for the same instruction in
-     * the <tt>indexes</tt> and <tt>sizes</tt>: two entries (index=a,size=b) and
-     * (index=a,size=b') are equivalent to a single entry (index=a,size=b+b').
-     *
-     * @param indexes
-     *            current positions of the instructions to be resized. Each
-     *            instruction must be designated by the index of its <i>last</i>
-     *            byte, plus one (or, in other words, by the index of the
-     *            <i>first</i> byte of the <i>next</i> instruction).
-     * @param sizes
-     *            the number of bytes to be <i>added</i> to the above
-     *            instructions. More precisely, for each i < <tt>len</tt>,
-     *            <tt>sizes</tt>[i] bytes will be added at the end of the
-     *            instruction designated by <tt>indexes</tt>[i] or, if
-     *            <tt>sizes</tt>[i] is negative, the <i>last</i> |
-     *            <tt>sizes[i]</tt>| bytes of the instruction will be removed
-     *            (the instruction size <i>must not</i> become negative or
-     *            null).
-     * @param begin
-     *            index of the first byte of the source instruction.
-     * @param end
-     *            index of the first byte of the target instruction.
-     * @return the future value of the given bytecode offset.
-     */
-    static int getNewOffset(final int[] indexes, final int[] sizes,
-            final int begin, final int end) {
-        int offset = end - begin;
-        for (int i = 0; i < indexes.length; ++i) {
-            if (begin < indexes[i] && indexes[i] <= end) {
-                // forward jump
-                offset += sizes[i];
-            } else if (end < indexes[i] && indexes[i] <= begin) {
-                // backward jump
-                offset -= sizes[i];
-            }
-        }
-        return offset;
-    }
-
-    /**
-     * Updates the offset of the given label.
-     *
-     * @param indexes
-     *            current positions of the instructions to be resized. Each
-     *            instruction must be designated by the index of its <i>last</i>
-     *            byte, plus one (or, in other words, by the index of the
-     *            <i>first</i> byte of the <i>next</i> instruction).
-     * @param sizes
-     *            the number of bytes to be <i>added</i> to the above
-     *            instructions. More precisely, for each i < <tt>len</tt>,
-     *            <tt>sizes</tt>[i] bytes will be added at the end of the
-     *            instruction designated by <tt>indexes</tt>[i] or, if
-     *            <tt>sizes</tt>[i] is negative, the <i>last</i> |
-     *            <tt>sizes[i]</tt>| bytes of the instruction will be removed
-     *            (the instruction size <i>must not</i> become negative or
-     *            null).
-     * @param label
-     *            the label whose offset must be updated.
-     */
-    static void getNewOffset(final int[] indexes, final int[] sizes,
-            final Label label) {
-        if ((label.status & Label.RESIZED) == 0) {
-            label.position = getNewOffset(indexes, sizes, 0, label.position);
-            label.status |= Label.RESIZED;
-        }
-    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ModuleVisitor.java	Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,219 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package jdk.internal.org.objectweb.asm;
+
+/**
+ * A visitor to visit a Java module. The methods of this class must be called in
+ * the following order: <tt>visitMainClass</tt> | ( <tt>visitPackage</tt> |
+ * <tt>visitRequire</tt> | <tt>visitExport</tt> | <tt>visitOpen</tt> |
+ * <tt>visitUse</tt> | <tt>visitProvide</tt> )* <tt>visitEnd</tt>.
+ *
+ * The methods {@link #visitRequire(String, int, String)}, {@link #visitExport(String, int, String...)},
+ * {@link #visitOpen(String, int, String...)} and {@link #visitPackage(String)}
+ * take as parameter a package name or a module name. Unlike the other names which are internal names
+ * (names separated by slash), module and package names are qualified names (names separated by dot).
+ *
+ * @author Remi Forax
+ */
+public abstract class ModuleVisitor {
+    /**
+     * The ASM API version implemented by this visitor. The value of this field
+     * must be {@link Opcodes#ASM6}.
+     */
+    protected final int api;
+
+    /**
+     * The module visitor to which this visitor must delegate method calls. May
+     * be null.
+     */
+    protected ModuleVisitor mv;
+
+    /**
+     * Constructs a new {@link ModuleVisitor}.
+     *
+     * @param api
+     *            the ASM API version implemented by this visitor. Must be {@link Opcodes#ASM6}.
+     */
+    public ModuleVisitor(final int api) {
+        this(api, null);
+    }
+
+    /**
+     * Constructs a new {@link ModuleVisitor}.
+     *
+     * @param api
+     *            the ASM API version implemented by this visitor. Must be {@link Opcodes#ASM6}.
+     * @param mv
+     *            the module visitor to which this visitor must delegate method
+     *            calls. May be null.
+     */
+    public ModuleVisitor(final int api, final ModuleVisitor mv) {
+        if (api != Opcodes.ASM6) {
+            throw new IllegalArgumentException();
+        }
+        this.api = api;
+        this.mv = mv;
+    }
+
+    /**
+     * Visit the main class of the current module.
+     *
+     * @param mainClass the internal name of the main class of the current module.
+     */
+    public void visitMainClass(String mainClass) {
+        if (mv != null) {
+            mv.visitMainClass(mainClass);
+        }
+    }
+
+    /**
+     * Visit a package of the current module.
+     *
+     * @param packaze the qualified name of a package.
+     */
+    public void visitPackage(String packaze) {
+        if (mv != null) {
+            mv.visitPackage(packaze);
+        }
+    }
+
+    /**
+     * Visits a dependence of the current module.
+     *
+     * @param module the qualified name of the dependence.
+     * @param access the access flag of the dependence among
+     *        ACC_TRANSITIVE, ACC_STATIC_PHASE, ACC_SYNTHETIC
+     *        and ACC_MANDATED.
+     * @param version the module version at compile time or null.
+     */
+    public void visitRequire(String module, int access, String version) {
+        if (mv != null) {
+            mv.visitRequire(module, access, version);
+        }
+    }
+
+    /**
+     * Visit an exported package of the current module.
+     *
+     * @param packaze the qualified name of the exported package.
+     * @param access the access flag of the exported package,
+     *        valid values are among {@code ACC_SYNTHETIC} and
+     *        {@code ACC_MANDATED}.
+     * @param modules the qualified names of the modules that can access to
+     *        the public classes of the exported package or
+     *        <tt>null</tt>.
+     */
+    public void visitExport(String packaze, int access, String... modules) {
+        if (mv != null) {
+            mv.visitExport(packaze, access, modules);
+        }
+    }
+
+    /**
+     * Visit an open package of the current module.
+     *
+     * @param packaze the qualified name of the opened package.
+     * @param access the access flag of the opened package,
+     *        valid values are among {@code ACC_SYNTHETIC} and
+     *        {@code ACC_MANDATED}.
+     * @param modules the qualified names of the modules that can use deep
+     *        reflection to the classes of the open package or
+     *        <tt>null</tt>.
+     */
+    public void visitOpen(String packaze, int access, String... modules) {
+        if (mv != null) {
+            mv.visitOpen(packaze, access, modules);
+        }
+    }
+
+    /**
+     * Visit a service used by the current module.
+     * The name must be the internal name of an interface or a class.
+     *
+     * @param service the internal name of the service.
+     */
+    public void visitUse(String service) {
+        if (mv != null) {
+            mv.visitUse(service);
+        }
+    }
+
+    /**
+     * Visit an implementation of a service.
+     *
+     * @param service the internal name of the service
+     * @param providers the internal names of the implementations
+     *        of the service (there is at least one provider).
+     */
+    public void visitProvide(String service, String... providers) {
+        if (mv != null) {
+            mv.visitProvide(service, providers);
+        }
+    }
+
+    /**
+     * Visits the end of the module. This method, which is the last one to be
+     * called, is used to inform the visitor that everything have been visited.
+     */
+    public void visitEnd() {
+        if (mv != null) {
+            mv.visitEnd();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ModuleWriter.java	Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,322 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jdk.internal.org.objectweb.asm;
+
+/**
+ * @author Remi Forax
+ */
+final class ModuleWriter extends ModuleVisitor {
+    /**
+     * The class writer to which this Module attribute must be added.
+     */
+    private final ClassWriter cw;
+
+    /**
+     * size in byte of the Module attribute.
+     */
+    int size;
+
+    /**
+     * Number of attributes associated with the current module
+     * (Version, ConcealPackages, etc)
+     */
+    int attributeCount;
+
+    /**
+     * Size in bytes of the attributes associated with the current module
+     */
+    int attributesSize;
+
+    /**
+     * module name index in the constant pool
+     */
+    private final int name;
+
+    /**
+     * module access flags
+     */
+    private final int access;
+
+    /**
+     * module version index in the constant pool or 0
+     */
+    private final int version;
+
+    /**
+     * module main class index in the constant pool or 0
+     */
+    private int mainClass;
+
+    /**
+     * number of packages
+     */
+    private int packageCount;
+
+    /**
+     * The packages in bytecode form. This byte vector only contains
+     * the items themselves, the number of items is store in packageCount
+     */
+    private ByteVector packages;
+
+    /**
+     * number of requires items
+     */
+    private int requireCount;
+
+    /**
+     * The requires items in bytecode form. This byte vector only contains
+     * the items themselves, the number of items is store in requireCount
+     */
+    private ByteVector requires;
+
+    /**
+     * number of exports items
+     */
+    private int exportCount;
+
+    /**
+     * The exports items in bytecode form. This byte vector only contains
+     * the items themselves, the number of items is store in exportCount
+     */
+    private ByteVector exports;
+
+    /**
+     * number of opens items
+     */
+    private int openCount;
+
+    /**
+     * The opens items in bytecode form. This byte vector only contains
+     * the items themselves, the number of items is store in openCount
+     */
+    private ByteVector opens;
+
+    /**
+     * number of uses items
+     */
+    private int useCount;
+
+    /**
+     * The uses items in bytecode form. This byte vector only contains
+     * the items themselves, the number of items is store in useCount
+     */
+    private ByteVector uses;
+
+    /**
+     * number of provides items
+     */
+    private int provideCount;
+
+    /**
+     * The uses provides in bytecode form. This byte vector only contains
+     * the items themselves, the number of items is store in provideCount
+     */
+    private ByteVector provides;
+
+    ModuleWriter(final ClassWriter cw, final int name,
+            final int access, final int version) {
+        super(Opcodes.ASM6);
+        this.cw = cw;
+        this.size = 16;  // name + access + version + 5 counts
+        this.name = name;
+        this.access = access;
+        this.version = version;
+    }
+
+    @Override
+    public void visitMainClass(String mainClass) {
+        if (this.mainClass == 0) { // protect against several calls to visitMainClass
+            cw.newUTF8("ModuleMainClass");
+            attributeCount++;
+            attributesSize += 8;
+        }
+        this.mainClass = cw.newClass(mainClass);
+    }
+
+    @Override
+    public void visitPackage(String packaze) {
+        if (packages == null) {
+            // protect against several calls to visitPackage
+            cw.newUTF8("ModulePackages");
+            packages = new ByteVector();
+            attributeCount++;
+            attributesSize += 8;
+        }
+        packages.putShort(cw.newPackage(packaze));
+        packageCount++;
+        attributesSize += 2;
+    }
+
+    @Override
+    public void visitRequire(String module, int access, String version) {
+        if (requires == null) {
+            requires = new ByteVector();
+        }
+        requires.putShort(cw.newModule(module))
+                .putShort(access)
+                .putShort(version == null? 0: cw.newUTF8(version));
+        requireCount++;
+        size += 6;
+    }
+
+    @Override
+    public void visitExport(String packaze, int access, String... modules) {
+        if (exports == null) {
+            exports = new ByteVector();
+        }
+        exports.putShort(cw.newPackage(packaze)).putShort(access);
+        if (modules == null) {
+            exports.putShort(0);
+            size += 6;
+        } else {
+            exports.putShort(modules.length);
+            for(String module: modules) {
+                exports.putShort(cw.newModule(module));
+            }
+            size += 6 + 2 * modules.length;
+        }
+        exportCount++;
+    }
+
+    @Override
+    public void visitOpen(String packaze, int access, String... modules) {
+        if (opens == null) {
+            opens = new ByteVector();
+        }
+        opens.putShort(cw.newPackage(packaze)).putShort(access);
+        if (modules == null) {
+            opens.putShort(0);
+            size += 6;
+        } else {
+            opens.putShort(modules.length);
+            for(String module: modules) {
+                opens.putShort(cw.newModule(module));
+            }
+            size += 6 + 2 * modules.length;
+        }
+        openCount++;
+    }
+
+    @Override
+    public void visitUse(String service) {
+        if (uses == null) {
+            uses = new ByteVector();
+        }
+        uses.putShort(cw.newClass(service));
+        useCount++;
+        size += 2;
+    }
+
+    @Override
+    public void visitProvide(String service, String... providers) {
+        if (provides == null) {
+            provides = new ByteVector();
+        }
+        provides.putShort(cw.newClass(service));
+        provides.putShort(providers.length);
+        for(String provider: providers) {
+            provides.putShort(cw.newClass(provider));
+        }
+        provideCount++;
+        size += 4 + 2 * providers.length;
+    }
+
+    @Override
+    public void visitEnd() {
+        // empty
+    }
+
+    void putAttributes(ByteVector out) {
+        if (mainClass != 0) {
+            out.putShort(cw.newUTF8("ModuleMainClass")).putInt(2).putShort(mainClass);
+        }
+        if (packages != null) {
+            out.putShort(cw.newUTF8("ModulePackages"))
+               .putInt(2 + 2 * packageCount)
+               .putShort(packageCount)
+               .putByteArray(packages.data, 0, packages.length);
+        }
+    }
+
+    void put(ByteVector out) {
+        out.putInt(size);
+        out.putShort(name).putShort(access).putShort(version);
+        out.putShort(requireCount);
+        if (requires != null) {
+            out.putByteArray(requires.data, 0, requires.length);
+        }
+        out.putShort(exportCount);
+        if (exports != null) {
+            out.putByteArray(exports.data, 0, exports.length);
+        }
+        out.putShort(openCount);
+        if (opens != null) {
+            out.putByteArray(opens.data, 0, opens.length);
+        }
+        out.putShort(useCount);
+        if (uses != null) {
+            out.putByteArray(uses.data, 0, uses.length);
+        }
+        out.putShort(provideCount);
+        if (provides != null) {
+            out.putByteArray(provides.data, 0, provides.length);
+        }
+    }
+}
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Opcodes.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Opcodes.java	Wed Nov 08 16:03:35 2017 -0500
@@ -70,13 +70,13 @@
  * @author Eric Bruneton
  * @author Eugene Kuleshov
  */
-@SuppressWarnings("deprecation") // for Integer(int) constructor
 public interface Opcodes {
 
     // ASM API versions
 
     int ASM4 = 4 << 16 | 0 << 8 | 0;
     int ASM5 = 5 << 16 | 0 << 8 | 0;
+    int ASM6 = 6 << 16 | 0 << 8 | 0;
 
     // versions
 
@@ -88,7 +88,7 @@
     int V1_6 = 0 << 16 | 50;
     int V1_7 = 0 << 16 | 51;
     int V1_8 = 0 << 16 | 52;
-    int V1_9 = 0 << 16 | 53;
+    int V9 = 0 << 16 | 53;
 
     // access flags
 
@@ -99,18 +99,23 @@
     int ACC_FINAL = 0x0010; // class, field, method, parameter
     int ACC_SUPER = 0x0020; // class
     int ACC_SYNCHRONIZED = 0x0020; // method
+    int ACC_OPEN = 0x0020; // module
+    int ACC_TRANSITIVE = 0x0020; // module requires
     int ACC_VOLATILE = 0x0040; // field
     int ACC_BRIDGE = 0x0040; // method
+    int ACC_STATIC_PHASE = 0x0040; // module requires
     int ACC_VARARGS = 0x0080; // method
     int ACC_TRANSIENT = 0x0080; // field
     int ACC_NATIVE = 0x0100; // method
     int ACC_INTERFACE = 0x0200; // class
     int ACC_ABSTRACT = 0x0400; // class, method
     int ACC_STRICT = 0x0800; // method
-    int ACC_SYNTHETIC = 0x1000; // class, field, method, parameter
+    int ACC_SYNTHETIC = 0x1000; // class, field, method, parameter, module *
     int ACC_ANNOTATION = 0x2000; // class
     int ACC_ENUM = 0x4000; // class(?) field inner
-    int ACC_MANDATED = 0x8000; // parameter
+    int ACC_MANDATED = 0x8000; // parameter, module, module *
+    int ACC_MODULE = 0x8000; // class
+
 
     // ASM specific pseudo access flags
 
@@ -177,15 +182,17 @@
      */
     int F_SAME1 = 4;
 
-    // For reference comparison purposes, construct new instances
-    // instead of using valueOf() or autoboxing.
-    Integer TOP = new Integer(0);
-    Integer INTEGER = new Integer(1);
-    Integer FLOAT = new Integer(2);
-    Integer DOUBLE = new Integer(3);
-    Integer LONG = new Integer(4);
-    Integer NULL = new Integer(5);
-    Integer UNINITIALIZED_THIS = new Integer(6);
+    // Do not try to change the following code to use auto-boxing,
+    // these values are compared by reference and not by value
+    // The constructor of Integer was deprecated in 9
+    // but we are stuck with it by backward compatibility
+    @SuppressWarnings("deprecation") Integer TOP = new Integer(0);
+    @SuppressWarnings("deprecation") Integer INTEGER = new Integer(1);
+    @SuppressWarnings("deprecation") Integer FLOAT = new Integer(2);
+    @SuppressWarnings("deprecation") Integer DOUBLE = new Integer(3);
+    @SuppressWarnings("deprecation") Integer LONG = new Integer(4);
+    @SuppressWarnings("deprecation") Integer NULL = new Integer(5);
+    @SuppressWarnings("deprecation") Integer UNINITIALIZED_THIS = new Integer(6);
 
     // opcodes // visit method (- = idem)
 
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Type.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Type.java	Wed Nov 08 16:03:35 2017 -0500
@@ -406,7 +406,16 @@
      */
     public static Type getReturnType(final String methodDescriptor) {
         char[] buf = methodDescriptor.toCharArray();
-        return getType(buf, methodDescriptor.indexOf(')') + 1);
+        int off = 1;
+        while (true) {
+            char car = buf[off++];
+            if (car == ')') {
+                return getType(buf, off);
+            } else if (car == 'L') {
+                while (buf[off++] != ';') {
+                }
+            }
+        }
     }
 
     /**
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/AdviceAdapter.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/AdviceAdapter.java	Wed Nov 08 16:03:35 2017 -0500
@@ -112,7 +112,7 @@
      *
      * @param api
      *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      * @param mv
      *            the method visitor to which this adapter delegates calls.
      * @param access
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/AnalyzerAdapter.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/AnalyzerAdapter.java	Wed Nov 08 16:03:35 2017 -0500
@@ -170,7 +170,7 @@
      */
     public AnalyzerAdapter(final String owner, final int access,
             final String name, final String desc, final MethodVisitor mv) {
-        this(Opcodes.ASM5, owner, access, name, desc, mv);
+        this(Opcodes.ASM6, owner, access, name, desc, mv);
         if (getClass() != AnalyzerAdapter.class) {
             throw new IllegalStateException();
         }
@@ -181,7 +181,7 @@
      *
      * @param api
      *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      * @param owner
      *            the owner's class name.
      * @param access
@@ -690,6 +690,8 @@
             t1 = pop();
             if (t1 instanceof String) {
                 pushDesc(((String) t1).substring(1));
+            } else if (t1 == Opcodes.NULL) {
+                push(t1);
             } else {
                 push("java/lang/Object");
             }
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/AnnotationRemapper.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/AnnotationRemapper.java	Wed Nov 08 16:03:35 2017 -0500
@@ -73,7 +73,7 @@
 
     public AnnotationRemapper(final AnnotationVisitor av,
             final Remapper remapper) {
-        this(Opcodes.ASM5, av, remapper);
+        this(Opcodes.ASM6, av, remapper);
     }
 
     protected AnnotationRemapper(final int api, final AnnotationVisitor av,
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/ClassRemapper.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/ClassRemapper.java	Wed Nov 08 16:03:35 2017 -0500
@@ -59,10 +59,14 @@
 
 package jdk.internal.org.objectweb.asm.commons;
 
+import java.util.List;
+
 import jdk.internal.org.objectweb.asm.AnnotationVisitor;
+import jdk.internal.org.objectweb.asm.Attribute;
 import jdk.internal.org.objectweb.asm.ClassVisitor;
 import jdk.internal.org.objectweb.asm.FieldVisitor;
 import jdk.internal.org.objectweb.asm.MethodVisitor;
+import jdk.internal.org.objectweb.asm.ModuleVisitor;
 import jdk.internal.org.objectweb.asm.Opcodes;
 import jdk.internal.org.objectweb.asm.TypePath;
 
@@ -78,7 +82,7 @@
     protected String className;
 
     public ClassRemapper(final ClassVisitor cv, final Remapper remapper) {
-        this(Opcodes.ASM5, cv, remapper);
+        this(Opcodes.ASM6, cv, remapper);
     }
 
     protected ClassRemapper(final int api, final ClassVisitor cv,
@@ -97,6 +101,12 @@
     }
 
     @Override
+    public ModuleVisitor visitModule(String name, int flags, String version) {
+        ModuleVisitor mv = super.visitModule(remapper.mapModuleName(name), flags, version);
+        return mv == null ? null : createModuleRemapper(mv);
+    }
+
+    @Override
     public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
         AnnotationVisitor av = super.visitAnnotation(remapper.mapDesc(desc),
                 visible);
@@ -112,6 +122,18 @@
     }
 
     @Override
+    public void visitAttribute(Attribute attr) {
+        if (attr instanceof ModuleHashesAttribute) {
+            ModuleHashesAttribute hashesAttr = new ModuleHashesAttribute();
+            List<String> modules = hashesAttr.modules;
+            for(int i = 0; i < modules.size(); i++) {
+                modules.set(i, remapper.mapModuleName(modules.get(i)));
+            }
+        }
+        super.visitAttribute(attr);
+    }
+
+    @Override
     public FieldVisitor visitField(int access, String name, String desc,
             String signature, Object value) {
         FieldVisitor fv = super.visitField(access,
@@ -158,4 +180,8 @@
     protected AnnotationVisitor createAnnotationRemapper(AnnotationVisitor av) {
         return new AnnotationRemapper(av, remapper);
     }
+
+    protected ModuleVisitor createModuleRemapper(ModuleVisitor mv) {
+        return new ModuleRemapper(mv, remapper);
+    }
 }
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/CodeSizeEvaluator.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/CodeSizeEvaluator.java	Wed Nov 08 16:03:35 2017 -0500
@@ -75,7 +75,7 @@
     private int maxSize;
 
     public CodeSizeEvaluator(final MethodVisitor mv) {
-        this(Opcodes.ASM5, mv);
+        this(Opcodes.ASM6, mv);
     }
 
     protected CodeSizeEvaluator(final int api, final MethodVisitor mv) {
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/FieldRemapper.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/FieldRemapper.java	Wed Nov 08 16:03:35 2017 -0500
@@ -74,7 +74,7 @@
     private final Remapper remapper;
 
     public FieldRemapper(final FieldVisitor fv, final Remapper remapper) {
-        this(Opcodes.ASM5, fv, remapper);
+        this(Opcodes.ASM6, fv, remapper);
     }
 
     protected FieldRemapper(final int api, final FieldVisitor fv,
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/GeneratorAdapter.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/GeneratorAdapter.java	Wed Nov 08 16:03:35 2017 -0500
@@ -289,7 +289,7 @@
      */
     public GeneratorAdapter(final MethodVisitor mv, final int access,
             final String name, final String desc) {
-        this(Opcodes.ASM5, mv, access, name, desc);
+        this(Opcodes.ASM6, mv, access, name, desc);
         if (getClass() != GeneratorAdapter.class) {
             throw new IllegalStateException();
         }
@@ -300,7 +300,7 @@
      *
      * @param api
      *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      * @param mv
      *            the method visitor to which this adapter delegates calls.
      * @param access
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/InstructionAdapter.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/InstructionAdapter.java	Wed Nov 08 16:03:35 2017 -0500
@@ -86,7 +86,7 @@
      *             If a subclass calls this constructor.
      */
     public InstructionAdapter(final MethodVisitor mv) {
-        this(Opcodes.ASM5, mv);
+        this(Opcodes.ASM6, mv);
         if (getClass() != InstructionAdapter.class) {
             throw new IllegalStateException();
         }
@@ -97,7 +97,7 @@
      *
      * @param api
      *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      * @param mv
      *            the method visitor to which this adapter delegates calls.
      */
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/JSRInlinerAdapter.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/JSRInlinerAdapter.java	Wed Nov 08 16:03:35 2017 -0500
@@ -142,7 +142,7 @@
     public JSRInlinerAdapter(final MethodVisitor mv, final int access,
             final String name, final String desc, final String signature,
             final String[] exceptions) {
-        this(Opcodes.ASM5, mv, access, name, desc, signature, exceptions);
+        this(Opcodes.ASM6, mv, access, name, desc, signature, exceptions);
         if (getClass() != JSRInlinerAdapter.class) {
             throw new IllegalStateException();
         }
@@ -153,7 +153,7 @@
      *
      * @param api
      *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      * @param mv
      *            the <code>MethodVisitor</code> to send the resulting inlined
      *            method code to (use <code>null</code> for none).
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/LocalVariablesSorter.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/LocalVariablesSorter.java	Wed Nov 08 16:03:35 2017 -0500
@@ -120,7 +120,7 @@
      */
     public LocalVariablesSorter(final int access, final String desc,
             final MethodVisitor mv) {
-        this(Opcodes.ASM5, access, desc, mv);
+        this(Opcodes.ASM6, access, desc, mv);
         if (getClass() != LocalVariablesSorter.class) {
             throw new IllegalStateException();
         }
@@ -131,7 +131,7 @@
      *
      * @param api
      *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      * @param access
      *            access flags of the adapted method.
      * @param desc
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/MethodRemapper.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/MethodRemapper.java	Wed Nov 08 16:03:35 2017 -0500
@@ -76,7 +76,7 @@
     protected final Remapper remapper;
 
     public MethodRemapper(final MethodVisitor mv, final Remapper remapper) {
-        this(Opcodes.ASM5, mv, remapper);
+        this(Opcodes.ASM6, mv, remapper);
     }
 
     protected MethodRemapper(final int api, final MethodVisitor mv,
@@ -122,18 +122,20 @@
     }
 
     private Object[] remapEntries(int n, Object[] entries) {
-        for (int i = 0; i < n; i++) {
-            if (entries[i] instanceof String) {
-                Object[] newEntries = new Object[n];
-                if (i > 0) {
-                    System.arraycopy(entries, 0, newEntries, 0, i);
+        if (entries != null) {
+            for (int i = 0; i < n; i++) {
+                if (entries[i] instanceof String) {
+                    Object[] newEntries = new Object[n];
+                    if (i > 0) {
+                        System.arraycopy(entries, 0, newEntries, 0, i);
+                    }
+                    do {
+                        Object t = entries[i];
+                        newEntries[i++] = t instanceof String ? remapper
+                                .mapType((String) t) : t;
+                    } while (i < n);
+                    return newEntries;
                 }
-                do {
-                    Object t = entries[i];
-                    newEntries[i++] = t instanceof String ? remapper
-                            .mapType((String) t) : t;
-                } while (i < n);
-                return newEntries;
             }
         }
         return entries;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/ModuleHashesAttribute.java	Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,155 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jdk.internal.org.objectweb.asm.commons;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import jdk.internal.org.objectweb.asm.Attribute;
+import jdk.internal.org.objectweb.asm.ByteVector;
+import jdk.internal.org.objectweb.asm.ClassReader;
+import jdk.internal.org.objectweb.asm.ClassWriter;
+import jdk.internal.org.objectweb.asm.Label;
+
+/**
+ * ModuleHashes attribute.
+ * This attribute is specific to the OpenJDK and may change in the future.
+ *
+ * @author Remi Forax
+ */
+public final class ModuleHashesAttribute extends Attribute {
+    public String algorithm;
+    public List<String> modules;
+    public List<byte[]> hashes;
+
+    /**
+     * Creates an attribute with a hashing algorithm, a list of module names,
+     * and a list of the same length of hashes.
+     * @param algorithm the hashing algorithm name.
+     * @param modules a list of module name
+     * @param hashes a list of hash, one for each module name.
+     */
+    public ModuleHashesAttribute(final String algorithm,
+            final List<String> modules, final List<byte[]> hashes) {
+        super("ModuleHashes");
+        this.algorithm = algorithm;
+        this.modules = modules;
+        this.hashes = hashes;
+    }
+
+    /**
+     * Creates an empty attribute that can be used as prototype
+     * to be passed as argument of the method
+     * {@link ClassReader#accept(org.objectweb.asm.ClassVisitor, Attribute[], int)}.
+     */
+    public ModuleHashesAttribute() {
+        this(null, null, null);
+    }
+
+    @Override
+    protected Attribute read(ClassReader cr, int off, int len, char[] buf,
+            int codeOff, Label[] labels) {
+        String hashAlgorithm = cr.readUTF8(off, buf);
+
+        int count = cr.readUnsignedShort(off + 2);
+        ArrayList<String> modules = new ArrayList<String>(count);
+        ArrayList<byte[]> hashes = new ArrayList<byte[]>(count);
+        off += 4;
+
+        for (int i = 0; i < count; i++) {
+            String module = cr.readModule(off, buf);
+            int hashLength = cr.readUnsignedShort(off + 2);
+            off += 4;
+
+            byte[] hash = new byte[hashLength];
+            for (int j = 0; j < hashLength; j++) {
+                hash[j] = (byte) (cr.readByte(off + j) & 0xff);
+            }
+            off += hashLength;
+
+            modules.add(module);
+            hashes.add(hash);
+        }
+        return new ModuleHashesAttribute(hashAlgorithm, modules, hashes);
+    }
+
+    @Override
+    protected ByteVector write(ClassWriter cw, byte[] code, int len,
+            int maxStack, int maxLocals) {
+        ByteVector v = new ByteVector();
+        int index = cw.newUTF8(algorithm);
+        v.putShort(index);
+
+        int count = (modules == null)? 0: modules.size();
+        v.putShort(count);
+
+        for(int i = 0; i < count; i++) {
+            String module = modules.get(i);
+            v.putShort(cw.newModule(module));
+
+            byte[] hash = hashes.get(i);
+            v.putShort(hash.length);
+            for(byte b: hash) {
+                v.putByte(b);
+            }
+        }
+        return v;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/ModuleRemapper.java	Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,135 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jdk.internal.org.objectweb.asm.commons;
+
+import jdk.internal.org.objectweb.asm.ModuleVisitor;
+import jdk.internal.org.objectweb.asm.Opcodes;
+
+/**
+ * A {@link ModuleVisitor} adapter for type remapping.
+ *
+ * @author Remi Forax
+ */
+public class ModuleRemapper extends ModuleVisitor {
+    private final Remapper remapper;
+
+    public ModuleRemapper(final ModuleVisitor mv, final Remapper remapper) {
+        this(Opcodes.ASM6, mv, remapper);
+    }
+
+    protected ModuleRemapper(final int api, final ModuleVisitor mv,
+            final Remapper remapper) {
+        super(api, mv);
+        this.remapper = remapper;
+    }
+
+    @Override
+    public void visitMainClass(String mainClass) {
+        super.visitMainClass(remapper.mapType(mainClass));
+    }
+
+    @Override
+    public void visitPackage(String packaze) {
+        super.visitPackage(remapper.mapPackageName(packaze));
+    }
+
+    @Override
+    public void visitRequire(String module, int access, String version) {
+        super.visitRequire(remapper.mapModuleName(module), access, version);
+    }
+
+    @Override
+    public void visitExport(String packaze, int access, String... modules) {
+        String[] newModules = null;
+        if (modules != null) {
+            newModules = new String[modules.length];
+            for (int i = 0 ; i < modules.length; i++) {
+                newModules[i] = remapper.mapModuleName(modules[i]);
+            }
+        }
+        super.visitExport(remapper.mapPackageName(packaze), access, newModules);
+    }
+
+    @Override
+    public void visitOpen(String packaze, int access, String... modules) {
+        String[] newModules = null;
+        if (modules != null) {
+            newModules = new String[modules.length];
+            for (int i = 0 ; i < modules.length; i++) {
+                newModules[i] = remapper.mapModuleName(modules[i]);
+            }
+        }
+        super.visitOpen(remapper.mapPackageName(packaze), access, newModules);
+    }
+
+    @Override
+    public void visitUse(String service) {
+        super.visitUse(remapper.mapType(service));
+    }
+
+    @Override
+    public void visitProvide(String service, String... providers) {
+        String[] newProviders = new String[providers.length];
+        for (int i = 0 ; i < providers.length; i++) {
+            newProviders[i] = remapper.mapType(providers[i]);
+        }
+        super.visitProvide(remapper.mapType(service), newProviders);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/ModuleResolutionAttribute.java	Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,135 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jdk.internal.org.objectweb.asm.commons;
+
+import jdk.internal.org.objectweb.asm.Attribute;
+import jdk.internal.org.objectweb.asm.ByteVector;
+import jdk.internal.org.objectweb.asm.ClassReader;
+import jdk.internal.org.objectweb.asm.ClassWriter;
+import jdk.internal.org.objectweb.asm.Label;
+
+/**
+ * ModuleResolution_attribute.
+ * This attribute is specific to the OpenJDK and may change in the future.
+ *
+ * @author Remi Forax
+ */
+public final class ModuleResolutionAttribute extends Attribute {
+    /**
+     * Resolution state of a module meaning that the module is not available
+     * from the class-path by default.
+     */
+    public static final int RESOLUTION_DO_NOT_RESOLVE_BY_DEFAULT = 1;
+
+    /**
+     * Resolution state of a module meaning the module is marked as deprecated.
+     */
+    public static final int RESOLUTION_WARN_DEPRECATED = 2;
+
+    /**
+     * Resolution state of a module meaning the module is marked as deprecated
+     * and will be removed in a future release.
+     */
+    public static final int RESOLUTION_WARN_DEPRECATED_FOR_REMOVAL = 4;
+
+    /**
+     * Resolution state of a module meaning the module is not yet standardized,
+     * so in incubating mode.
+     */
+    public static final int RESOLUTION_WARN_INCUBATING = 8;
+
+    public int resolution;
+
+    /**
+     * Creates an attribute with a resolution state value.
+     * @param resolution the resolution state among
+     *        {@link #RESOLUTION_WARN_DEPRECATED},
+     *        {@link #RESOLUTION_WARN_DEPRECATED_FOR_REMOVAL}, and
+     *        {@link #RESOLUTION_WARN_INCUBATING}.
+     */
+    public ModuleResolutionAttribute(final int resolution) {
+        super("ModuleResolution");
+        this.resolution = resolution;
+    }
+
+    /**
+     * Creates an empty attribute that can be used as prototype
+     * to be passed as argument of the method
+     * {@link ClassReader#accept(org.objectweb.asm.ClassVisitor, Attribute[], int)}.
+     */
+    public ModuleResolutionAttribute() {
+        this(0);
+    }
+
+    @Override
+    protected Attribute read(ClassReader cr, int off, int len, char[] buf,
+            int codeOff, Label[] labels) {
+        int resolution = cr.readUnsignedShort(off);
+        return new ModuleResolutionAttribute(resolution);
+    }
+
+    @Override
+    protected ByteVector write(ClassWriter cw, byte[] code, int len,
+            int maxStack, int maxLocals) {
+        ByteVector v = new ByteVector();
+        v.putShort(resolution);
+        return v;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/ModuleTargetAttribute.java	Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,110 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jdk.internal.org.objectweb.asm.commons;
+
+import jdk.internal.org.objectweb.asm.Attribute;
+import jdk.internal.org.objectweb.asm.ByteVector;
+import jdk.internal.org.objectweb.asm.ClassReader;
+import jdk.internal.org.objectweb.asm.ClassWriter;
+import jdk.internal.org.objectweb.asm.Label;
+
+/**
+ * ModuleTarget attribute.
+ * This attribute is specific to the OpenJDK and may change in the future.
+ *
+ * @author Remi Forax
+ */
+public final class ModuleTargetAttribute extends Attribute {
+    public String platform;
+
+    /**
+     * Creates an attribute with a platform name.
+     * @param platform the platform name on which the module can run.
+     */
+    public ModuleTargetAttribute(final String platform) {
+        super("ModuleTarget");
+        this.platform = platform;
+    }
+
+    /**
+     * Creates an empty attribute that can be used as prototype
+     * to be passed as argument of the method
+     * {@link ClassReader#accept(org.objectweb.asm.ClassVisitor, Attribute[], int)}.
+     */
+    public ModuleTargetAttribute() {
+        this(null);
+    }
+
+    @Override
+    protected Attribute read(ClassReader cr, int off, int len, char[] buf,
+            int codeOff, Label[] labels) {
+        String platform = cr.readUTF8(off, buf);
+        return new ModuleTargetAttribute(platform);
+    }
+
+    @Override
+    protected ByteVector write(ClassWriter cw, byte[] code, int len,
+            int maxStack, int maxLocals) {
+        ByteVector v = new ByteVector();
+        int index = (platform == null)? 0: cw.newUTF8(platform);
+        v.putShort(index);
+        return v;
+    }
+}
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/Remapper.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/Remapper.java	Wed Nov 08 16:03:35 2017 -0500
@@ -255,6 +255,28 @@
     }
 
     /**
+     * Map package name to the new name. Subclasses can override.
+     *
+     * @param name name of the package
+     * @return new name of the package
+     */
+    public String mapPackageName(String name) {
+        String fakeName = map(name + ".FakeClassName");
+        int index;
+        return fakeName == null || (index = fakeName.lastIndexOf('.')) == -1 ? name: fakeName.substring(0, index);
+    }
+
+    /**
+     * Map module name to the new name. Subclasses can override.
+     *
+     * @param name name of the module
+     * @return new name of the module
+     */
+    public String mapModuleName(String name) {
+        return name;
+    }
+
+    /**
      * Map type name to the new name. Subclasses can override.
      *
      * @param typeName
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingAnnotationAdapter.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingAnnotationAdapter.java	Wed Nov 08 16:03:35 2017 -0500
@@ -75,7 +75,7 @@
 
     public RemappingAnnotationAdapter(final AnnotationVisitor av,
             final Remapper remapper) {
-        this(Opcodes.ASM5, av, remapper);
+        this(Opcodes.ASM6, av, remapper);
     }
 
     protected RemappingAnnotationAdapter(final int api,
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingClassAdapter.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingClassAdapter.java	Wed Nov 08 16:03:35 2017 -0500
@@ -63,6 +63,7 @@
 import jdk.internal.org.objectweb.asm.ClassVisitor;
 import jdk.internal.org.objectweb.asm.FieldVisitor;
 import jdk.internal.org.objectweb.asm.MethodVisitor;
+import jdk.internal.org.objectweb.asm.ModuleVisitor;
 import jdk.internal.org.objectweb.asm.Opcodes;
 import jdk.internal.org.objectweb.asm.TypePath;
 
@@ -80,7 +81,7 @@
     protected String className;
 
     public RemappingClassAdapter(final ClassVisitor cv, final Remapper remapper) {
-        this(Opcodes.ASM5, cv, remapper);
+        this(Opcodes.ASM6, cv, remapper);
     }
 
     protected RemappingClassAdapter(final int api, final ClassVisitor cv,
@@ -99,6 +100,11 @@
     }
 
     @Override
+    public ModuleVisitor visitModule(String name, int flags, String version) {
+        throw new RuntimeException("RemappingClassAdapter is deprecated, use ClassRemapper instead");
+    }
+
+    @Override
     public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
         AnnotationVisitor av = super.visitAnnotation(remapper.mapDesc(desc),
                 visible);
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingFieldAdapter.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingFieldAdapter.java	Wed Nov 08 16:03:35 2017 -0500
@@ -76,7 +76,7 @@
     private final Remapper remapper;
 
     public RemappingFieldAdapter(final FieldVisitor fv, final Remapper remapper) {
-        this(Opcodes.ASM5, fv, remapper);
+        this(Opcodes.ASM6, fv, remapper);
     }
 
     protected RemappingFieldAdapter(final int api, final FieldVisitor fv,
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingMethodAdapter.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingMethodAdapter.java	Wed Nov 08 16:03:35 2017 -0500
@@ -79,7 +79,7 @@
 
     public RemappingMethodAdapter(final int access, final String desc,
             final MethodVisitor mv, final Remapper remapper) {
-        this(Opcodes.ASM5, access, desc, mv, remapper);
+        this(Opcodes.ASM6, access, desc, mv, remapper);
     }
 
     protected RemappingMethodAdapter(final int api, final int access,
@@ -125,18 +125,20 @@
     }
 
     private Object[] remapEntries(int n, Object[] entries) {
-        for (int i = 0; i < n; i++) {
-            if (entries[i] instanceof String) {
-                Object[] newEntries = new Object[n];
-                if (i > 0) {
-                    System.arraycopy(entries, 0, newEntries, 0, i);
+        if (entries != null) {
+            for (int i = 0; i < n; i++) {
+                if (entries[i] instanceof String) {
+                    Object[] newEntries = new Object[n];
+                    if (i > 0) {
+                        System.arraycopy(entries, 0, newEntries, 0, i);
+                    }
+                    do {
+                        Object t = entries[i];
+                        newEntries[i++] = t instanceof String ? remapper
+                                .mapType((String) t) : t;
+                    } while (i < n);
+                    return newEntries;
                 }
-                do {
-                    Object t = entries[i];
-                    newEntries[i++] = t instanceof String ? remapper
-                            .mapType((String) t) : t;
-                } while (i < n);
-                return newEntries;
             }
         }
         return entries;
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingSignatureAdapter.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingSignatureAdapter.java	Wed Nov 08 16:03:35 2017 -0500
@@ -79,7 +79,7 @@
 
     public RemappingSignatureAdapter(final SignatureVisitor v,
             final Remapper remapper) {
-        this(Opcodes.ASM5, v, remapper);
+        this(Opcodes.ASM6, v, remapper);
     }
 
     protected RemappingSignatureAdapter(final int api,
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/SerialVersionUIDAdder.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/SerialVersionUIDAdder.java	Wed Nov 08 16:03:35 2017 -0500
@@ -80,7 +80,7 @@
  *   ClassWriter cw = new ClassWriter(...);
  *   ClassVisitor sv = new SerialVersionUIDAdder(cw);
  *   ClassVisitor ca = new MyClassAdapter(sv);
- *   new ClassReader(originalClass).accept(ca, false);
+ *   new ClassReader(orginalClass).accept(ca, false);
  * </pre>
  *
  * The SVUID algorithm can be found <a href=
@@ -199,7 +199,7 @@
      *             If a subclass calls this constructor.
      */
     public SerialVersionUIDAdder(final ClassVisitor cv) {
-        this(Opcodes.ASM5, cv);
+        this(Opcodes.ASM6, cv);
         if (getClass() != SerialVersionUIDAdder.class) {
             throw new IllegalStateException();
         }
@@ -210,7 +210,7 @@
      *
      * @param api
      *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      * @param cv
      *            a {@link ClassVisitor} to which this visitor will delegate
      *            calls.
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/SignatureRemapper.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/SignatureRemapper.java	Wed Nov 08 16:03:35 2017 -0500
@@ -78,7 +78,7 @@
     private Stack<String> classNames = new Stack<String>();
 
     public SignatureRemapper(final SignatureVisitor v, final Remapper remapper) {
-        this(Opcodes.ASM5, v, remapper);
+        this(Opcodes.ASM6, v, remapper);
     }
 
     protected SignatureRemapper(final int api, final SignatureVisitor v,
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/StaticInitMerger.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/StaticInitMerger.java	Wed Nov 08 16:03:35 2017 -0500
@@ -78,7 +78,7 @@
     private int counter;
 
     public StaticInitMerger(final String prefix, final ClassVisitor cv) {
-        this(Opcodes.ASM5, prefix, cv);
+        this(Opcodes.ASM6, prefix, cv);
     }
 
     protected StaticInitMerger(final int api, final String prefix,
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/TryCatchBlockSorter.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/TryCatchBlockSorter.java	Wed Nov 08 16:03:35 2017 -0500
@@ -86,7 +86,7 @@
     public TryCatchBlockSorter(final MethodVisitor mv, final int access,
             final String name, final String desc, final String signature,
             final String[] exceptions) {
-        this(Opcodes.ASM5, mv, access, name, desc, signature, exceptions);
+        this(Opcodes.ASM6, mv, access, name, desc, signature, exceptions);
     }
 
     protected TryCatchBlockSorter(final int api, final MethodVisitor mv,
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/signature/SignatureVisitor.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/signature/SignatureVisitor.java	Wed Nov 08 16:03:35 2017 -0500
@@ -102,7 +102,7 @@
 
     /**
      * The ASM API version implemented by this visitor. The value of this field
-     * must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     * must be one of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      */
     protected final int api;
 
@@ -111,10 +111,10 @@
      *
      * @param api
      *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      */
     public SignatureVisitor(final int api) {
-        if (api != Opcodes.ASM4 && api != Opcodes.ASM5) {
+        if (api < Opcodes.ASM4 || api > Opcodes.ASM6) {
             throw new IllegalArgumentException();
         }
         this.api = api;
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/signature/SignatureWriter.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/signature/SignatureWriter.java	Wed Nov 08 16:03:35 2017 -0500
@@ -95,7 +95,7 @@
      * Constructs a new {@link SignatureWriter} object.
      */
     public SignatureWriter() {
-        super(Opcodes.ASM5);
+        super(Opcodes.ASM6);
     }
 
     // ------------------------------------------------------------------------
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/AnnotationNode.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/AnnotationNode.java	Wed Nov 08 16:03:35 2017 -0500
@@ -65,7 +65,7 @@
 import jdk.internal.org.objectweb.asm.Opcodes;
 
 /**
- * A node that represents an annotationn.
+ * A node that represents an annotation.
  *
  * @author Eric Bruneton
  */
@@ -81,8 +81,8 @@
      * as two consecutive elements in the list. The name is a {@link String},
      * and the value may be a {@link Byte}, {@link Boolean}, {@link Character},
      * {@link Short}, {@link Integer}, {@link Long}, {@link Float},
-     * {@link Double}, {@link String} or {@link jdk.internal.org.objectweb.asm.Type}, or an
-     * two elements String array (for enumeration values), a
+     * {@link Double}, {@link String} or {@link jdk.internal.org.objectweb.asm.Type}, or a
+     * two elements String array (for enumeration values), an
      * {@link AnnotationNode}, or a {@link List} of values of one of the
      * preceding types. The list may be <tt>null</tt> if there is no name value
      * pair.
@@ -100,7 +100,7 @@
      *             If a subclass calls this constructor.
      */
     public AnnotationNode(final String desc) {
-        this(Opcodes.ASM5, desc);
+        this(Opcodes.ASM6, desc);
         if (getClass() != AnnotationNode.class) {
             throw new IllegalStateException();
         }
@@ -111,7 +111,7 @@
      *
      * @param api
      *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      * @param desc
      *            the class descriptor of the annotation class.
      */
@@ -127,7 +127,7 @@
      *            where the visited values must be stored.
      */
     AnnotationNode(final List<Object> values) {
-        super(Opcodes.ASM5);
+        super(Opcodes.ASM6);
         this.values = values;
     }
 
@@ -143,7 +143,65 @@
         if (this.desc != null) {
             values.add(name);
         }
-        values.add(value);
+        if (value instanceof byte[]) {
+            byte[] v = (byte[]) value;
+            ArrayList<Byte> l = new ArrayList<Byte>(v.length);
+            for (byte b : v) {
+                l.add(b);
+            }
+            values.add(l);
+        } else if (value instanceof boolean[]) {
+            boolean[] v = (boolean[]) value;
+            ArrayList<Boolean> l = new ArrayList<Boolean>(v.length);
+            for (boolean b : v) {
+                l.add(b);
+            }
+            values.add(l);
+        } else if (value instanceof short[]) {
+            short[] v = (short[]) value;
+            ArrayList<Short> l = new ArrayList<Short>(v.length);
+            for (short s : v) {
+                l.add(s);
+            }
+            values.add(l);
+        } else if (value instanceof char[]) {
+            char[] v = (char[]) value;
+            ArrayList<Character> l = new ArrayList<Character>(v.length);
+            for (char c : v) {
+                l.add(c);
+            }
+            values.add(l);
+        } else if (value instanceof int[]) {
+            int[] v = (int[]) value;
+            ArrayList<Integer> l = new ArrayList<Integer>(v.length);
+            for (int i : v) {
+                l.add(i);
+            }
+            values.add(l);
+        } else if (value instanceof long[]) {
+            long[] v = (long[]) value;
+            ArrayList<Long> l = new ArrayList<Long>(v.length);
+            for (long lng : v) {
+                l.add(lng);
+            }
+            values.add(l);
+        } else if (value instanceof float[]) {
+            float[] v = (float[]) value;
+            ArrayList<Float> l = new ArrayList<Float>(v.length);
+            for (float f : v) {
+                l.add(f);
+            }
+            values.add(l);
+        } else if (value instanceof double[]) {
+            double[] v = (double[]) value;
+            ArrayList<Double> l = new ArrayList<Double>(v.length);
+            for (double d : v) {
+                l.add(d);
+            }
+            values.add(l);
+        } else {
+            values.add(value);
+        }
     }
 
     @Override
@@ -200,8 +258,8 @@
      * versions of the ASM API than the given version.
      *
      * @param api
-     *            an ASM API version. Must be one of {@link Opcodes#ASM4} or
-     *            {@link Opcodes#ASM5}.
+     *            an ASM API version. Must be one of {@link Opcodes#ASM4},
+     *            {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      */
     public void check(final int api) {
         // nothing to do
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/ClassNode.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/ClassNode.java	Wed Nov 08 16:03:35 2017 -0500
@@ -67,6 +67,7 @@
 import jdk.internal.org.objectweb.asm.ClassVisitor;
 import jdk.internal.org.objectweb.asm.FieldVisitor;
 import jdk.internal.org.objectweb.asm.MethodVisitor;
+import jdk.internal.org.objectweb.asm.ModuleVisitor;
 import jdk.internal.org.objectweb.asm.Opcodes;
 import jdk.internal.org.objectweb.asm.TypePath;
 
@@ -127,6 +128,11 @@
     public String sourceDebug;
 
     /**
+     * Module information. May be <tt>null</tt>.
+     */
+    public ModuleNode module;
+
+    /**
      * The internal name of the enclosing class of the class. May be
      * <tt>null</tt>.
      */
@@ -221,7 +227,7 @@
      *             If a subclass calls this constructor.
      */
     public ClassNode() {
-        this(Opcodes.ASM5);
+        this(Opcodes.ASM6);
         if (getClass() != ClassNode.class) {
             throw new IllegalStateException();
         }
@@ -232,7 +238,7 @@
      *
      * @param api
      *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      */
     public ClassNode(final int api) {
         super(api);
@@ -267,6 +273,12 @@
     }
 
     @Override
+    public ModuleVisitor visitModule(final String name, final int access,
+            final String version) {
+        return module = new ModuleNode(name, access, version);
+    }
+
+    @Override
     public void visitOuterClass(final String owner, final String name,
             final String desc) {
         outerClass = owner;
@@ -358,11 +370,16 @@
      * API than the given version.
      *
      * @param api
-     *            an ASM API version. Must be one of {@link Opcodes#ASM4} or
-     *            {@link Opcodes#ASM5}.
+     *            an ASM API version. Must be one of {@link Opcodes#ASM4},
+     *            {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      */
     public void check(final int api) {
-        if (api == Opcodes.ASM4) {
+        if (api < Opcodes.ASM6) {
+            if (module != null) {
+                throw new RuntimeException();
+            }
+        }
+        if (api < Opcodes.ASM5) {
             if (visibleTypeAnnotations != null
                     && visibleTypeAnnotations.size() > 0) {
                 throw new RuntimeException();
@@ -371,12 +388,31 @@
                     && invisibleTypeAnnotations.size() > 0) {
                 throw new RuntimeException();
             }
-            for (FieldNode f : fields) {
-                f.check(api);
-            }
-            for (MethodNode m : methods) {
-                m.check(api);
-            }
+        }
+        // checks attributes
+        int i, n;
+        n = visibleAnnotations == null ? 0 : visibleAnnotations.size();
+        for (i = 0; i < n; ++i) {
+            visibleAnnotations.get(i).check(api);
+        }
+        n = invisibleAnnotations == null ? 0 : invisibleAnnotations.size();
+        for (i = 0; i < n; ++i) {
+            invisibleAnnotations.get(i).check(api);
+        }
+        n = visibleTypeAnnotations == null ? 0 : visibleTypeAnnotations.size();
+        for (i = 0; i < n; ++i) {
+            visibleTypeAnnotations.get(i).check(api);
+        }
+        n = invisibleTypeAnnotations == null ? 0 : invisibleTypeAnnotations
+                .size();
+        for (i = 0; i < n; ++i) {
+            invisibleTypeAnnotations.get(i).check(api);
+        }
+        for (FieldNode f : fields) {
+            f.check(api);
+        }
+        for (MethodNode m : methods) {
+            m.check(api);
         }
     }
 
@@ -395,6 +431,10 @@
         if (sourceFile != null || sourceDebug != null) {
             cv.visitSource(sourceFile, sourceDebug);
         }
+        // visits module
+        if (module != null) {
+            module.accept(cv);
+        }
         // visits outer class
         if (outerClass != null) {
             cv.visitOuterClass(outerClass, outerMethod, outerMethodDesc);
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/FieldNode.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/FieldNode.java	Wed Nov 08 16:03:35 2017 -0500
@@ -173,7 +173,7 @@
      */
     public FieldNode(final int access, final String name, final String desc,
             final String signature, final Object value) {
-        this(Opcodes.ASM5, access, name, desc, signature, value);
+        this(Opcodes.ASM6, access, name, desc, signature, value);
         if (getClass() != FieldNode.class) {
             throw new IllegalStateException();
         }
@@ -276,8 +276,8 @@
      * API than the given version.
      *
      * @param api
-     *            an ASM API version. Must be one of {@link Opcodes#ASM4} or
-     *            {@link Opcodes#ASM5}.
+     *            an ASM API version. Must be one of {@link Opcodes#ASM4},
+     *            {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      */
     public void check(final int api) {
         if (api == Opcodes.ASM4) {
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/InsnList.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/InsnList.java	Wed Nov 08 16:03:35 2017 -0500
@@ -634,14 +634,28 @@
         }
 
         public void add(Object o) {
-            InsnList.this.insertBefore(next, (AbstractInsnNode) o);
+            if (next != null) {
+                InsnList.this.insertBefore(next, (AbstractInsnNode) o);
+            } else if (prev != null) {
+                InsnList.this.insert(prev, (AbstractInsnNode) o);
+            } else {
+                InsnList.this.add((AbstractInsnNode) o);
+            }
             prev = (AbstractInsnNode) o;
             remove = null;
         }
 
         public void set(Object o) {
-            InsnList.this.set(next.prev, (AbstractInsnNode) o);
-            prev = (AbstractInsnNode) o;
+            if (remove != null) {
+                InsnList.this.set(remove, (AbstractInsnNode) o);
+                if (remove == prev) {
+                    prev = (AbstractInsnNode) o;
+                } else {
+                    next = (AbstractInsnNode) o;
+                }
+            } else {
+                throw new IllegalStateException();
+            }
         }
     }
 }
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/LocalVariableAnnotationNode.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/LocalVariableAnnotationNode.java	Wed Nov 08 16:03:35 2017 -0500
@@ -122,7 +122,7 @@
      */
     public LocalVariableAnnotationNode(int typeRef, TypePath typePath,
             LabelNode[] start, LabelNode[] end, int[] index, String desc) {
-        this(Opcodes.ASM5, typeRef, typePath, start, end, index, desc);
+        this(Opcodes.ASM6, typeRef, typePath, start, end, index, desc);
     }
 
     /**
@@ -130,7 +130,7 @@
      *
      * @param api
      *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      * @param typeRef
      *            a reference to the annotated type. See {@link TypeReference}.
      * @param start
@@ -181,6 +181,6 @@
             index[i] = this.index.get(i);
         }
         accept(mv.visitLocalVariableAnnotation(typeRef, typePath, start, end,
-                index, desc, true));
+                index, desc, visible));
     }
 }
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/MethodNode.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/MethodNode.java	Wed Nov 08 16:03:35 2017 -0500
@@ -249,7 +249,7 @@
      *             If a subclass calls this constructor.
      */
     public MethodNode() {
-        this(Opcodes.ASM5);
+        this(Opcodes.ASM6);
         if (getClass() != MethodNode.class) {
             throw new IllegalStateException();
         }
@@ -260,7 +260,7 @@
      *
      * @param api
      *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      */
     public MethodNode(final int api) {
         super(api);
@@ -291,7 +291,7 @@
      */
     public MethodNode(final int access, final String name, final String desc,
             final String signature, final String[] exceptions) {
-        this(Opcodes.ASM5, access, name, desc, signature, exceptions);
+        this(Opcodes.ASM6, access, name, desc, signature, exceptions);
         if (getClass() != MethodNode.class) {
             throw new IllegalStateException();
         }
@@ -302,7 +302,7 @@
      *
      * @param api
      *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      * @param access
      *            the method's access flags (see {@link Opcodes}). This
      *            parameter also indicates if the method is synthetic and/or
@@ -688,8 +688,8 @@
      * versions of the ASM API than the given version.
      *
      * @param api
-     *            an ASM API version. Must be one of {@link Opcodes#ASM4} or
-     *            {@link Opcodes#ASM5}.
+     *            an ASM API version. Must be one of {@link Opcodes#ASM4},
+     *            {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      */
     public void check(final int api) {
         if (api == Opcodes.ASM4) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/ModuleExportNode.java	Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,111 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package jdk.internal.org.objectweb.asm.tree;
+
+import java.util.List;
+
+import jdk.internal.org.objectweb.asm.ModuleVisitor;
+
+/**
+ * A node that represents an exported package with its name and the module that can access to it.
+ *
+ * @author Remi Forax
+ */
+public class ModuleExportNode {
+    /**
+     * The package name.
+     */
+    public String packaze;
+
+    /**
+     * The access flags (see {@link jdk.internal.org.objectweb.asm.Opcodes}).
+     * Valid values are {@code ACC_SYNTHETIC} and {@code ACC_MANDATED}.
+     */
+    public int access;
+
+    /**
+     * A list of modules that can access to this exported package.
+     * May be <tt>null</tt>.
+     */
+    public List<String> modules;
+
+    /**
+     * Constructs a new {@link ModuleExportNode}.
+     *
+     * @param packaze
+     *            the parameter's name.
+     * @param modules
+     *            a list of modules that can access to this exported package.
+     */
+    public ModuleExportNode(final String packaze, final int access, final List<String> modules) {
+        this.packaze = packaze;
+        this.access = access;
+        this.modules = modules;
+    }
+
+    /**
+     * Makes the given module visitor visit this export declaration.
+     *
+     * @param mv
+     *            a module visitor.
+     */
+    public void accept(final ModuleVisitor mv) {
+        mv.visitExport(packaze, access, (modules == null) ? null : modules.toArray(new String[0]));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/ModuleNode.java	Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,280 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package jdk.internal.org.objectweb.asm.tree;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import jdk.internal.org.objectweb.asm.ClassVisitor;
+import jdk.internal.org.objectweb.asm.ModuleVisitor;
+import jdk.internal.org.objectweb.asm.Opcodes;
+
+/**
+ * A node that represents a module declaration.
+ *
+ * @author Remi Forax
+ */
+public class ModuleNode extends ModuleVisitor {
+    /**
+     * Module name
+     */
+    public String name;
+
+    /**
+     * Module access flags, among {@code ACC_OPEN}, {@code ACC_SYNTHETIC}
+     *            and {@code ACC_MANDATED}.
+     */
+    public int access;
+
+    /**
+     * Version of the module.
+     * May be <tt>null</tt>.
+     */
+    public String version;
+
+    /**
+     * Name of the main class in internal form
+     * May be <tt>null</tt>.
+     */
+    public String mainClass;
+
+    /**
+     * A list of packages that are declared by the current module.
+     * May be <tt>null</tt>.
+     */
+    public List<String> packages;
+
+    /**
+     * A list of modules can are required by the current module.
+     * May be <tt>null</tt>.
+     */
+    public List<ModuleRequireNode> requires;
+
+    /**
+     * A list of packages that are exported by the current module.
+     * May be <tt>null</tt>.
+     */
+    public List<ModuleExportNode> exports;
+
+    /**
+     * A list of packages that are opened by the current module.
+     * May be <tt>null</tt>.
+     */
+    public List<ModuleOpenNode> opens;
+
+    /**
+     * A list of classes in their internal forms that are used
+     * as a service by the current module. May be <tt>null</tt>.
+     */
+    public List<String> uses;
+
+    /**
+     * A list of services along with their implementations provided
+     * by the current module. May be <tt>null</tt>.
+     */
+    public List<ModuleProvideNode> provides;
+
+    public ModuleNode(final String name, final int access,
+            final String version) {
+        super(Opcodes.ASM6);
+        this.name = name;
+        this.access = access;
+        this.version = version;
+    }
+
+    public ModuleNode(final int api,
+      final String name,
+      final int access,
+      final String version,
+      final List<ModuleRequireNode> requires,
+      final List<ModuleExportNode> exports,
+      final List<ModuleOpenNode> opens,
+      final List<String> uses,
+      final List<ModuleProvideNode> provides) {
+        super(api);
+        this.name = name;
+        this.access = access;
+        this.version = version;
+        this.requires = requires;
+        this.exports = exports;
+        this.opens = opens;
+        this.uses = uses;
+        this.provides = provides;
+        if (getClass() != ModuleNode.class) {
+            throw new IllegalStateException();
+        }
+    }
+
+    @Override
+    public void visitMainClass(String mainClass) {
+        this.mainClass = mainClass;
+    }
+
+    @Override
+    public void visitPackage(String packaze) {
+        if (packages == null) {
+            packages = new ArrayList<String>(5);
+        }
+        packages.add(packaze);
+    }
+
+    @Override
+    public void visitRequire(String module, int access, String version) {
+        if (requires == null) {
+            requires = new ArrayList<ModuleRequireNode>(5);
+        }
+        requires.add(new ModuleRequireNode(module, access, version));
+    }
+
+    @Override
+    public void visitExport(String packaze, int access, String... modules) {
+        if (exports == null) {
+            exports = new ArrayList<ModuleExportNode>(5);
+        }
+        List<String> moduleList = null;
+        if (modules != null) {
+            moduleList = new ArrayList<String>(modules.length);
+            for (int i = 0; i < modules.length; i++) {
+                moduleList.add(modules[i]);
+            }
+        }
+        exports.add(new ModuleExportNode(packaze, access, moduleList));
+    }
+
+    @Override
+    public void visitOpen(String packaze, int access, String... modules) {
+        if (opens == null) {
+            opens = new ArrayList<ModuleOpenNode>(5);
+        }
+        List<String> moduleList = null;
+        if (modules != null) {
+            moduleList = new ArrayList<String>(modules.length);
+            for (int i = 0; i < modules.length; i++) {
+                moduleList.add(modules[i]);
+            }
+        }
+        opens.add(new ModuleOpenNode(packaze, access, moduleList));
+    }
+
+    @Override
+    public void visitUse(String service) {
+        if (uses == null) {
+            uses = new ArrayList<String>(5);
+        }
+        uses.add(service);
+    }
+
+    @Override
+    public void visitProvide(String service, String... providers) {
+        if (provides == null) {
+            provides = new ArrayList<ModuleProvideNode>(5);
+        }
+        ArrayList<String> providerList =
+                new ArrayList<String>(providers.length);
+        for (int i = 0; i < providers.length; i++) {
+                providerList.add(providers[i]);
+        }
+        provides.add(new ModuleProvideNode(service, providerList));
+    }
+
+    @Override
+    public void visitEnd() {
+    }
+
+    public void accept(final ClassVisitor cv) {
+        ModuleVisitor mv = cv.visitModule(name, access, version);
+        if (mv == null) {
+            return;
+        }
+        if (mainClass != null) {
+            mv.visitMainClass(mainClass);
+        }
+        if (packages != null) {
+            for (int i = 0; i < packages.size(); i++) {
+                mv.visitPackage(packages.get(i));
+            }
+        }
+
+        if (requires != null) {
+            for (int i = 0; i < requires.size(); i++) {
+                requires.get(i).accept(mv);
+            }
+        }
+        if (exports != null) {
+            for (int i = 0; i < exports.size(); i++) {
+                exports.get(i).accept(mv);
+            }
+        }
+        if (opens != null) {
+            for (int i = 0; i < opens.size(); i++) {
+                opens.get(i).accept(mv);
+            }
+        }
+        if (uses != null) {
+            for (int i = 0; i < uses.size(); i++) {
+                mv.visitUse(uses.get(i));
+            }
+        }
+        if (provides != null) {
+            for (int i = 0; i < provides.size(); i++) {
+                provides.get(i).accept(mv);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/ModuleOpenNode.java	Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,111 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package jdk.internal.org.objectweb.asm.tree;
+
+import java.util.List;
+
+import jdk.internal.org.objectweb.asm.ModuleVisitor;
+
+/**
+ * A node that represents an opened package with its name and the module that can access to it.
+ *
+ * @author Remi Forax
+ */
+public class ModuleOpenNode {
+    /**
+     * The package name.
+     */
+    public String packaze;
+
+    /**
+     * The access flags (see {@link jdk.internal.org.objectweb.asm.Opcodes}).
+     * Valid values are {@code ACC_SYNTHETIC} and {@code ACC_MANDATED}.
+     */
+    public int access;
+
+    /**
+     * A list of modules that can access to this exported package.
+     * May be <tt>null</tt>.
+     */
+    public List<String> modules;
+
+    /**
+     * Constructs a new {@link ModuleOpenNode}.
+     *
+     * @param packaze
+     *            the parameter's name.
+     * @param modules
+     *            a list of modules that can access to this open package.
+     */
+    public ModuleOpenNode(final String packaze, final int access, final List<String> modules) {
+        this.packaze = packaze;
+        this.access = access;
+        this.modules = modules;
+    }
+
+    /**
+     * Makes the given module visitor visit this open declaration.
+     *
+     * @param mv
+     *            a module visitor.
+     */
+    public void accept(final ModuleVisitor mv) {
+        mv.visitExport(packaze, access, (modules == null) ? null : modules.toArray(new String[0]));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/ModuleProvideNode.java	Wed Nov 08 16:03:35 2017 -0500
@@ -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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package jdk.internal.org.objectweb.asm.tree;
+
+import java.util.List;
+
+import jdk.internal.org.objectweb.asm.ModuleVisitor;
+
+/**
+ * A node that represents a service and its implementation provided by the current module.
+ *
+ * @author Remi Forax
+ */
+public class ModuleProvideNode {
+    /**
+     * The service name (in its internal form).
+     */
+    public String service;
+
+    /**
+     * The service provider names (in their internal form).
+     */
+    public List<String> providers;
+
+    /**
+     * Constructs a new {@link ModuleProvideNode}.
+     *
+     * @param service
+     *            the service name (in its internal form).
+     * @param providers
+     *            the service provider names (in their internal form).
+     */
+    public ModuleProvideNode(final String service, final List<String> providers) {
+        this.service = service;
+        this.providers = providers;
+    }
+
+    /**
+     * Makes the given module visitor visit this require declaration.
+     *
+     * @param mv
+     *            a module visitor.
+     */
+    public void accept(final ModuleVisitor mv) {
+        mv.visitProvide(service, providers.toArray(new String[0]));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/ModuleRequireNode.java	Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,116 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package jdk.internal.org.objectweb.asm.tree;
+
+import jdk.internal.org.objectweb.asm.ModuleVisitor;
+
+/**
+ * A node that represents a required module with its name and access of a module descriptor.
+ *
+ * @author Remi Forax
+ */
+public class ModuleRequireNode {
+    /**
+     * The name of the required module.
+     */
+    public String module;
+
+    /**
+     * The access flags (see {@link jdk.internal.org.objectweb.asm.Opcodes}).
+     * Valid values are <tt>ACC_TRANSITIVE</tt>, <tt>ACC_STATIC_PHASE</tt>,
+     *        <tt>ACC_SYNTHETIC</tt> and <tt>ACC_MANDATED</tt>.
+     */
+    public int access;
+
+    /**
+     * Version at compile time of the required module or null.
+     */
+    public String version;
+
+    /**
+     * Constructs a new {@link ModuleRequireNode}.
+     *
+     * @param module
+     *            the name of the required module.
+     * @param access
+     *            The access flags. Valid values are
+     *            <tt>ACC_TRANSITIVE</tt>, <tt>ACC_STATIC_PHASE</tt>,
+     *            <tt>ACC_SYNTHETIC</tt> and <tt>ACC_MANDATED</tt>
+     *            (see {@link jdk.internal.org.objectweb.asm.Opcodes}).
+     * @param version
+     *            Version of the required module at compile time,
+     *            null if not defined.
+     */
+    public ModuleRequireNode(final String module, final int access,
+            final String version) {
+        this.module = module;
+        this.access = access;
+        this.version = version;
+    }
+
+    /**
+     * Makes the given module visitor visit this require directive.
+     *
+     * @param mv
+     *            a module visitor.
+     */
+    public void accept(final ModuleVisitor mv) {
+        mv.visitRequire(module, access, version);
+    }
+}
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/TypeAnnotationNode.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/TypeAnnotationNode.java	Wed Nov 08 16:03:35 2017 -0500
@@ -99,7 +99,7 @@
      */
     public TypeAnnotationNode(final int typeRef, final TypePath typePath,
             final String desc) {
-        this(Opcodes.ASM5, typeRef, typePath, desc);
+        this(Opcodes.ASM6, typeRef, typePath, desc);
         if (getClass() != TypeAnnotationNode.class) {
             throw new IllegalStateException();
         }
@@ -110,7 +110,7 @@
      *
      * @param api
      *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      * @param typeRef
      *            a reference to the annotated type. See {@link TypeReference}.
      * @param typePath
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/BasicInterpreter.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/BasicInterpreter.java	Wed Nov 08 16:03:35 2017 -0500
@@ -82,7 +82,7 @@
         Opcodes {
 
     public BasicInterpreter() {
-        super(ASM5);
+        super(ASM6);
     }
 
     protected BasicInterpreter(final int api) {
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/BasicVerifier.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/BasicVerifier.java	Wed Nov 08 16:03:35 2017 -0500
@@ -76,7 +76,7 @@
 public class BasicVerifier extends BasicInterpreter {
 
     public BasicVerifier() {
-        super(ASM5);
+        super(ASM6);
     }
 
     protected BasicVerifier(final int api) {
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/SimpleVerifier.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/SimpleVerifier.java	Wed Nov 08 16:03:35 2017 -0500
@@ -136,7 +136,7 @@
     public SimpleVerifier(final Type currentClass,
             final Type currentSuperClass,
             final List<Type> currentClassInterfaces, final boolean isInterface) {
-        this(ASM5, currentClass, currentSuperClass, currentClassInterfaces,
+        this(ASM6, currentClass, currentSuperClass, currentClassInterfaces,
                 isInterface);
     }
 
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/SourceInterpreter.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/SourceInterpreter.java	Wed Nov 08 16:03:35 2017 -0500
@@ -79,7 +79,7 @@
         Opcodes {
 
     public SourceInterpreter() {
-        super(ASM5);
+        super(ASM6);
     }
 
     protected SourceInterpreter(final int api) {
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/ASMifier.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/ASMifier.java	Wed Nov 08 16:03:35 2017 -0500
@@ -110,6 +110,11 @@
     private static final int ACCESS_INNER = 1048576;
 
     /**
+     * Pseudo access flag used to distinguish module requires/exports flags.
+     */
+    private static final int ACCESS_MODULE = 2097152;
+
+    /**
      * Constructs a new {@link ASMifier}. <i>Subclasses must not use this
      * constructor</i>. Instead, they must use the
      * {@link #ASMifier(int, String, int)} version.
@@ -118,7 +123,7 @@
      *             If a subclass calls this constructor.
      */
     public ASMifier() {
-        this(Opcodes.ASM5, "cw", 0);
+        this(Opcodes.ASM6, "cw", 0);
         if (getClass() != ASMifier.class) {
             throw new IllegalStateException();
         }
@@ -129,7 +134,7 @@
      *
      * @param api
      *            the ASM API version implemented by this class. Must be one of
-     *            {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     *            {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      * @param name
      *            the name of the visitor variable in the produced code.
      * @param id
@@ -196,13 +201,17 @@
             final String signature, final String superName,
             final String[] interfaces) {
         String simpleName;
-        int n = name.lastIndexOf('/');
-        if (n == -1) {
-            simpleName = name;
+        if (name == null) {
+            simpleName = "module-info";
         } else {
-            text.add("package asm." + name.substring(0, n).replace('/', '.')
-                    + ";\n");
-            simpleName = name.substring(n + 1);
+            int n = name.lastIndexOf('/');
+            if (n == -1) {
+                simpleName = name;
+            } else {
+                text.add("package asm." + name.substring(0, n).replace('/', '.')
+                        + ";\n");
+                simpleName = name.substring(n + 1).replace('-', '_');
+            }
         }
         text.add("import java.util.*;\n");
         text.add("import jdk.internal.org.objectweb.asm.*;\n");
@@ -237,6 +246,12 @@
         case Opcodes.V1_7:
             buf.append("V1_7");
             break;
+        case Opcodes.V1_8:
+            buf.append("V1_8");
+            break;
+        case Opcodes.V9:
+            buf.append("V9");
+            break;
         default:
             buf.append(version);
             break;
@@ -276,6 +291,24 @@
     }
 
     @Override
+    public Printer visitModule(final String name, final int flags,
+            final String version) {
+        buf.setLength(0);
+        buf.append("ModuleVisitor mdv = cw.visitModule(");
+        appendConstant(name);
+        buf.append(", ");
+        appendAccess(flags | ACCESS_MODULE);
+        buf.append(", ");
+        appendConstant(version);
+        buf.append(");\n\n");
+        text.add(buf.toString());
+        ASMifier a = createASMifier("mdv", 0);
+        text.add(a.getText());
+        text.add("}\n");
+        return a;
+    }
+
+    @Override
     public void visitOuterClass(final String owner, final String name,
             final String desc) {
         buf.setLength(0);
@@ -386,6 +419,108 @@
     }
 
     // ------------------------------------------------------------------------
+    // Module
+    // ------------------------------------------------------------------------
+
+    @Override
+    public void visitMainClass(String mainClass) {
+        buf.setLength(0);
+        buf.append("mdv.visitMainClass(");
+        appendConstant(buf, mainClass);
+        buf.append(");\n");
+        text.add(buf.toString());
+    }
+
+    @Override
+    public void visitPackage(String packaze) {
+        buf.setLength(0);
+        buf.append("mdv.visitPackage(");
+        appendConstant(buf, packaze);
+        buf.append(");\n");
+        text.add(buf.toString());
+    }
+
+    @Override
+    public void visitRequire(String module, int access, String version) {
+        buf.setLength(0);
+        buf.append("mdv.visitRequire(");
+        appendConstant(buf, module);
+        buf.append(", ");
+        appendAccess(access | ACCESS_MODULE);
+        buf.append(", ");
+        appendConstant(buf, version);
+        buf.append(");\n");
+        text.add(buf.toString());
+    }
+
+    @Override
+    public void visitExport(String packaze, int access, String... modules) {
+        buf.setLength(0);
+        buf.append("mdv.visitExport(");
+        appendConstant(buf, packaze);
+        buf.append(", ");
+        appendAccess(access | ACCESS_MODULE);
+        if (modules != null && modules.length > 0) {
+            buf.append(", new String[] {");
+            for (int i = 0; i < modules.length; ++i) {
+                buf.append(i == 0 ? " " : ", ");
+                appendConstant(modules[i]);
+            }
+            buf.append(" }");
+        }
+        buf.append(");\n");
+        text.add(buf.toString());
+    }
+
+    @Override
+    public void visitOpen(String packaze, int access, String... modules) {
+        buf.setLength(0);
+        buf.append("mdv.visitOpen(");
+        appendConstant(buf, packaze);
+        buf.append(", ");
+        appendAccess(access | ACCESS_MODULE);
+        if (modules != null && modules.length > 0) {
+            buf.append(", new String[] {");
+            for (int i = 0; i < modules.length; ++i) {
+                buf.append(i == 0 ? " " : ", ");
+                appendConstant(modules[i]);
+            }
+            buf.append(" }");
+        }
+        buf.append(");\n");
+        text.add(buf.toString());
+    }
+
+    @Override
+    public void visitUse(String service) {
+        buf.setLength(0);
+        buf.append("mdv.visitUse(");
+        appendConstant(buf, service);
+        buf.append(");\n");
+        text.add(buf.toString());
+    }
+
+    @Override
+    public void visitProvide(String service, String... providers) {
+        buf.setLength(0);
+        buf.append("mdv.visitProvide(");
+        appendConstant(buf, service);
+        buf.append(",  new String[] {");
+        for (int i = 0; i < providers.length; ++i) {
+            buf.append(i == 0 ? " " : ", ");
+            appendConstant(providers[i]);
+        }
+        buf.append(" });\n");
+        text.add(buf.toString());
+    }
+
+    @Override
+    public void visitModuleEnd() {
+        text.add("mdv.visitEnd();\n");
+    }
+
+
+    // ------------------------------------------------------------------------
     // Annotations
     // ------------------------------------------------------------------------
 
@@ -972,7 +1107,7 @@
     // ------------------------------------------------------------------------
 
     protected ASMifier createASMifier(final String name, final int id) {
-        return new ASMifier(Opcodes.ASM5, name, id);
+        return new ASMifier(Opcodes.ASM6, name, id);
     }
 
     /**
@@ -1000,7 +1135,11 @@
             if (!first) {
                 buf.append(" + ");
             }
-            buf.append("ACC_FINAL");
+            if ((access & ACCESS_MODULE) == 0) {
+                buf.append("ACC_FINAL");
+            } else {
+                buf.append("ACC_TRANSITIVE");
+            }
             first = false;
         }
         if ((access & Opcodes.ACC_STATIC) != 0) {
@@ -1010,31 +1149,35 @@
             buf.append("ACC_STATIC");
             first = false;
         }
-        if ((access & Opcodes.ACC_SYNCHRONIZED) != 0) {
+        if ((access & (Opcodes.ACC_SYNCHRONIZED | Opcodes.ACC_SUPER | Opcodes.ACC_TRANSITIVE)) != 0) {
             if (!first) {
                 buf.append(" + ");
             }
             if ((access & ACCESS_CLASS) == 0) {
-                buf.append("ACC_SYNCHRONIZED");
+                if ((access & ACCESS_MODULE) == 0) {
+                    buf.append("ACC_SYNCHRONIZED");
+                } else {
+                    buf.append("ACC_TRANSITIVE");
+                }
             } else {
                 buf.append("ACC_SUPER");
             }
             first = false;
         }
-        if ((access & Opcodes.ACC_VOLATILE) != 0
-                && (access & ACCESS_FIELD) != 0) {
+        if ((access & (Opcodes.ACC_VOLATILE | Opcodes.ACC_BRIDGE | Opcodes.ACC_STATIC_PHASE)) != 0) {
             if (!first) {
                 buf.append(" + ");
             }
-            buf.append("ACC_VOLATILE");
-            first = false;
-        }
-        if ((access & Opcodes.ACC_BRIDGE) != 0 && (access & ACCESS_CLASS) == 0
-                && (access & ACCESS_FIELD) == 0) {
-            if (!first) {
-                buf.append(" + ");
+            if ((access & ACCESS_FIELD) == 0) {
+                if ((access & ACCESS_MODULE) == 0) {
+                    buf.append("ACC_BRIDGE");
+                } else {
+                    buf.append("ACC_STATIC_PHASE");
+                }
+            } else {
+                buf.append("ACC_VOLATILE");
             }
-            buf.append("ACC_BRIDGE");
+
             first = false;
         }
         if ((access & Opcodes.ACC_VARARGS) != 0 && (access & ACCESS_CLASS) == 0
@@ -1113,11 +1256,15 @@
             buf.append("ACC_DEPRECATED");
             first = false;
         }
-        if ((access & Opcodes.ACC_MANDATED) != 0) {
+        if ((access & (Opcodes.ACC_MANDATED | Opcodes.ACC_MODULE)) != 0) {
             if (!first) {
                 buf.append(" + ");
             }
-            buf.append("ACC_MANDATED");
+            if ((access & ACCESS_CLASS) == 0) {
+                buf.append("ACC_MANDATED");
+            } else {
+                buf.append("ACC_MODULE");
+            }
             first = false;
         }
         if (first) {
@@ -1163,7 +1310,8 @@
                     .append(", \"");
             buf.append(h.getOwner()).append("\", \"");
             buf.append(h.getName()).append("\", \"");
-            buf.append(h.getDesc()).append("\")");
+            buf.append(h.getDesc()).append("\", ");
+            buf.append(h.isInterface()).append(")");
         } else if (cst instanceof Byte) {
             buf.append("new Byte((byte)").append(cst).append(')');
         } else if (cst instanceof Boolean) {
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckAnnotationAdapter.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckAnnotationAdapter.java	Wed Nov 08 16:03:35 2017 -0500
@@ -78,7 +78,7 @@
     }
 
     CheckAnnotationAdapter(final AnnotationVisitor av, final boolean named) {
-        super(Opcodes.ASM5, av);
+        super(Opcodes.ASM6, av);
         this.named = named;
     }
 
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckClassAdapter.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckClassAdapter.java	Wed Nov 08 16:03:35 2017 -0500
@@ -73,6 +73,7 @@
 import jdk.internal.org.objectweb.asm.FieldVisitor;
 import jdk.internal.org.objectweb.asm.Label;
 import jdk.internal.org.objectweb.asm.MethodVisitor;
+import jdk.internal.org.objectweb.asm.ModuleVisitor;
 import jdk.internal.org.objectweb.asm.Opcodes;
 import jdk.internal.org.objectweb.asm.Type;
 import jdk.internal.org.objectweb.asm.TypePath;
@@ -181,6 +182,11 @@
     private boolean end;
 
     /**
+     * <tt>true</tt> if the visitModule method has been called.
+     */
+    private boolean module;
+
+    /**
      * The already visited labels. This map associate Integer values to Label
      * keys.
      */
@@ -363,7 +369,7 @@
      *             If a subclass calls this constructor.
      */
     public CheckClassAdapter(final ClassVisitor cv, final boolean checkDataFlow) {
-        this(Opcodes.ASM5, cv, checkDataFlow);
+        this(Opcodes.ASM6, cv, checkDataFlow);
         if (getClass() != CheckClassAdapter.class) {
             throw new IllegalStateException();
         }
@@ -374,7 +380,7 @@
      *
      * @param api
      *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      * @param cv
      *            the class visitor to which this adapter must delegate calls.
      * @param checkDataFlow
@@ -407,8 +413,12 @@
                 + Opcodes.ACC_SUPER + Opcodes.ACC_INTERFACE
                 + Opcodes.ACC_ABSTRACT + Opcodes.ACC_SYNTHETIC
                 + Opcodes.ACC_ANNOTATION + Opcodes.ACC_ENUM
-                + Opcodes.ACC_DEPRECATED + 0x40000); // ClassWriter.ACC_SYNTHETIC_ATTRIBUTE
-        if (name == null || !name.endsWith("package-info")) {
+                + Opcodes.ACC_DEPRECATED + Opcodes.ACC_MODULE
+                + 0x40000); // ClassWriter.ACC_SYNTHETIC_ATTRIBUTE
+        if (name == null) {
+            throw new IllegalArgumentException("Illegal class name (null)");
+        }
+        if (!name.endsWith("package-info")) {
             CheckMethodAdapter.checkInternalName(name, "class name");
         }
         if ("java/lang/Object".equals(name)) {
@@ -450,6 +460,22 @@
     }
 
     @Override
+    public ModuleVisitor visitModule(String name, int access, String version) {
+        checkState();
+        if (module) {
+            throw new IllegalStateException(
+                    "visitModule can be called only once.");
+        }
+        module = true;
+        if (name == null) {
+            throw new IllegalArgumentException("Illegal module name (null)");
+        }
+        checkAccess(access, Opcodes.ACC_OPEN | Opcodes.ACC_SYNTHETIC);
+        return new CheckModuleAdapter(super.visitModule(name, access, version),
+            (access & Opcodes.ACC_OPEN) != 0);
+    }
+
+    @Override
     public void visitOuterClass(final String owner, final String name,
             final String desc) {
         checkState();
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckFieldAdapter.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckFieldAdapter.java	Wed Nov 08 16:03:35 2017 -0500
@@ -83,7 +83,7 @@
      *             If a subclass calls this constructor.
      */
     public CheckFieldAdapter(final FieldVisitor fv) {
-        this(Opcodes.ASM5, fv);
+        this(Opcodes.ASM6, fv);
         if (getClass() != CheckFieldAdapter.class) {
             throw new IllegalStateException();
         }
@@ -94,7 +94,7 @@
      *
      * @param api
      *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      * @param fv
      *            the field visitor to which this adapter must delegate calls.
      */
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckMethodAdapter.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckMethodAdapter.java	Wed Nov 08 16:03:35 2017 -0500
@@ -426,7 +426,7 @@
      */
     public CheckMethodAdapter(final MethodVisitor mv,
             final Map<Label, Integer> labels) {
-        this(Opcodes.ASM5, mv, labels);
+        this(Opcodes.ASM6, mv, labels);
         if (getClass() != CheckMethodAdapter.class) {
             throw new IllegalStateException();
         }
@@ -439,7 +439,8 @@
      *
      * @param api
      *            the ASM API version implemented by this CheckMethodAdapter.
-     *            Must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     *            Must be one of {@link Opcodes#ASM4}, {@link Opcodes#ASM5}
+     *            or {@link Opcodes#ASM6}.
      * @param mv
      *            the method visitor to which this adapter must delegate calls.
      * @param labels
@@ -756,6 +757,12 @@
             throw new IllegalArgumentException(
                     "INVOKEINTERFACE can't be used with classes");
         }
+        if (opcode == Opcodes.INVOKESPECIAL && itf
+                && (version & 0xFFFF) < Opcodes.V1_8) {
+            throw new IllegalArgumentException(
+                    "INVOKESPECIAL can't be used with interfaces prior to Java 8");
+        }
+
         // Calling super.visitMethodInsn requires to call the correct version
         // depending on this.api (otherwise infinite loops can occur). To
         // simplify and to make it easier to automatically remove the backward
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckModuleAdapter.java	Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,180 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package jdk.internal.org.objectweb.asm.util;
+
+import java.util.HashSet;
+
+import jdk.internal.org.objectweb.asm.ModuleVisitor;
+import jdk.internal.org.objectweb.asm.Opcodes;
+
+/**
+ * @author Remi Forax
+ */
+public final class CheckModuleAdapter extends ModuleVisitor {
+    private boolean end;
+    private final boolean isOpen;
+
+    private final HashSet<String> requireNames = new HashSet<String>();
+    private final HashSet<String> exportNames = new HashSet<String>();
+    private final HashSet<String> openNames = new HashSet<String>();
+    private final HashSet<String> useNames = new HashSet<String>();
+    private final HashSet<String> provideNames = new HashSet<String>();
+
+    public CheckModuleAdapter(final ModuleVisitor mv, final boolean isOpen) {
+        super(Opcodes.ASM6, mv);
+        this.isOpen = isOpen;
+    }
+
+    @Override
+    public void visitRequire(String module, int access, String version) {
+        checkEnd();
+        if (module == null) {
+            throw new IllegalArgumentException("require cannot be null");
+        }
+        checkDeclared("requires", requireNames, module);
+        CheckClassAdapter.checkAccess(access, Opcodes.ACC_STATIC_PHASE
+                + Opcodes.ACC_TRANSITIVE + Opcodes.ACC_SYNTHETIC + Opcodes.ACC_MANDATED);
+        super.visitRequire(module, access, version);
+    }
+
+    @Override
+    public void visitExport(String packaze, int access, String... modules) {
+        checkEnd();
+        if (packaze == null) {
+            throw new IllegalArgumentException("packaze cannot be null");
+        }
+        CheckMethodAdapter.checkInternalName(packaze, "package name");
+        checkDeclared("exports", exportNames, packaze);
+        CheckClassAdapter.checkAccess(access, Opcodes.ACC_SYNTHETIC
+                + Opcodes.ACC_MANDATED);
+        if (modules != null) {
+            for (int i = 0; i < modules.length; i++) {
+                if (modules[i] == null) {
+                    throw new IllegalArgumentException("module at index " + i + " cannot be null");
+                }
+            }
+        }
+        super.visitExport(packaze, access, modules);
+    }
+
+    @Override
+    public void visitOpen(String packaze, int access, String... modules) {
+        checkEnd();
+        if (isOpen) {
+            throw new IllegalArgumentException("an open module can not use open directive");
+        }
+        if (packaze == null) {
+            throw new IllegalArgumentException("packaze cannot be null");
+        }
+        CheckMethodAdapter.checkInternalName(packaze, "package name");
+        checkDeclared("opens", openNames, packaze);
+        CheckClassAdapter.checkAccess(access, Opcodes.ACC_SYNTHETIC
+                + Opcodes.ACC_MANDATED);
+        if (modules != null) {
+            for (int i = 0; i < modules.length; i++) {
+                if (modules[i] == null) {
+                    throw new IllegalArgumentException("module at index " + i + " cannot be null");
+                }
+            }
+        }
+        super.visitOpen(packaze, access, modules);
+    }
+
+    @Override
+    public void visitUse(String service) {
+        checkEnd();
+        CheckMethodAdapter.checkInternalName(service, "service");
+        checkDeclared("uses", useNames, service);
+        super.visitUse(service);
+    }
+
+    @Override
+    public void visitProvide(String service, String... providers) {
+        checkEnd();
+        CheckMethodAdapter.checkInternalName(service, "service");
+        checkDeclared("provides", provideNames, service);
+        if (providers == null || providers.length == 0) {
+            throw new IllegalArgumentException("providers cannot be null or empty");
+        }
+        for (int i = 0; i < providers.length; i++) {
+            CheckMethodAdapter.checkInternalName(providers[i], "provider");
+        }
+        super.visitProvide(service, providers);
+    }
+
+    @Override
+    public void visitEnd() {
+        checkEnd();
+        end = true;
+        super.visitEnd();
+    }
+
+    private void checkEnd() {
+        if (end) {
+            throw new IllegalStateException(
+                    "Cannot call a visit method after visitEnd has been called");
+        }
+    }
+
+    private static void checkDeclared(String directive, HashSet<String> names, String name) {
+        if (!names.add(name)) {
+            throw new IllegalArgumentException(directive + " " + name + " already declared");
+        }
+    }
+}
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckSignatureAdapter.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckSignatureAdapter.java	Wed Nov 08 16:03:35 2017 -0500
@@ -142,7 +142,7 @@
      *            <tt>null</tt>.
      */
     public CheckSignatureAdapter(final int type, final SignatureVisitor sv) {
-        this(Opcodes.ASM5, type, sv);
+        this(Opcodes.ASM6, type, sv);
     }
 
     /**
@@ -150,7 +150,7 @@
      *
      * @param api
      *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      * @param type
      *            the type of signature to be checked. See
      *            {@link #CLASS_SIGNATURE}, {@link #METHOD_SIGNATURE} and
@@ -175,7 +175,7 @@
                 || (state != EMPTY && state != FORMAL && state != BOUND)) {
             throw new IllegalStateException();
         }
-        CheckMethodAdapter.checkIdentifier(name, "formal type parameter");
+        checkIdentifier(name, "formal type parameter");
         state = FORMAL;
         if (sv != null) {
             sv.visitFormalTypeParameter(name);
@@ -284,7 +284,7 @@
         if (type != TYPE_SIGNATURE || state != EMPTY) {
             throw new IllegalStateException();
         }
-        CheckMethodAdapter.checkIdentifier(name, "type variable");
+        checkIdentifier(name, "type variable");
         state = SIMPLE_TYPE;
         if (sv != null) {
             sv.visitTypeVariable(name);
@@ -306,7 +306,7 @@
         if (type != TYPE_SIGNATURE || state != EMPTY) {
             throw new IllegalStateException();
         }
-        CheckMethodAdapter.checkInternalName(name, "class name");
+        checkClassName(name, "class name");
         state = CLASS_TYPE;
         if (sv != null) {
             sv.visitClassType(name);
@@ -318,7 +318,7 @@
         if (state != CLASS_TYPE) {
             throw new IllegalStateException();
         }
-        CheckMethodAdapter.checkIdentifier(name, "inner class name");
+        checkIdentifier(name, "inner class name");
         if (sv != null) {
             sv.visitInnerClassType(name);
         }
@@ -356,4 +356,30 @@
             sv.visitEnd();
         }
     }
+
+    private void checkClassName(final String name, final String msg) {
+        if (name == null || name.length() == 0) {
+            throw new IllegalArgumentException("Invalid " + msg
+                    + " (must not be null or empty)");
+        }
+        for (int i = 0; i < name.length(); ++i) {
+            if (".;[<>:".indexOf(name.charAt(i)) != -1) {
+                throw new IllegalArgumentException("Invalid " + msg
+                        + " (must not contain . ; [ < > or :): " + name);
+            }
+        }
+    }
+
+    private void checkIdentifier(final String name, final String msg) {
+        if (name == null || name.length() == 0) {
+            throw new IllegalArgumentException("Invalid " + msg
+                    + " (must not be null or empty)");
+        }
+        for (int i = 0; i < name.length(); ++i) {
+            if (".;[/<>:".indexOf(name.charAt(i)) != -1) {
+                throw new IllegalArgumentException("Invalid " + msg
+                        + " (must not contain . ; [ / < > or :): " + name);
+            }
+        }
+    }
 }
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/Printer.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/Printer.java	Wed Nov 08 16:03:35 2017 -0500
@@ -146,7 +146,7 @@
 
     /**
      * The ASM API version implemented by this class. The value of this field
-     * must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     * must be one of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      */
     protected final int api;
 
@@ -174,7 +174,7 @@
      *
      * @param api
      *            the ASM API version implemented by this printer. Must be one
-     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      */
     protected Printer(final int api) {
         this.api = api;
@@ -226,6 +226,24 @@
      */
     public abstract void visitSource(final String source, final String debug);
 
+
+    /**
+     * Module.
+     * See {@link jdk.internal.org.objectweb.asm.ClassVisitor#visitModule(String, int)}.
+     *
+     * @param name
+     *            module name.
+     * @param access
+     *            module flags, among {@code ACC_OPEN}, {@code ACC_SYNTHETIC}
+     *            and {@code ACC_MANDATED}.
+     * @param version
+     *            module version or null.
+     * @return
+     */
+    public Printer visitModule(String name, int access, String version) {
+        throw new RuntimeException("Must be overriden");
+    }
+
     /**
      * Class outer class.
      * See {@link jdk.internal.org.objectweb.asm.ClassVisitor#visitOuterClass}.
@@ -376,6 +394,45 @@
     public abstract void visitClassEnd();
 
     // ------------------------------------------------------------------------
+    // Module
+    // ------------------------------------------------------------------------
+
+    public void visitMainClass(String mainClass) {
+        throw new RuntimeException("Must be overriden");
+    }
+
+    public void visitPackage(String packaze) {
+        throw new RuntimeException("Must be overriden");
+    }
+
+    public void visitRequire(String module, int access, String version) {
+        throw new RuntimeException("Must be overriden");
+    }
+
+    public void visitExport(String packaze, int access, String... modules) {
+        throw new RuntimeException("Must be overriden");
+    }
+
+    public void visitOpen(String packaze, int access, String... modules) {
+        throw new RuntimeException("Must be overriden");
+    }
+
+    public void visitUse(String service) {
+        throw new RuntimeException("Must be overriden");
+    }
+
+    public void visitProvide(String service, String... providers) {
+        throw new RuntimeException("Must be overriden");
+    }
+
+    /**
+     * Module end. See {@link jdk.internal.org.objectweb.asm.ModuleVisitor#visitEnd}.
+     */
+    public void visitModuleEnd() {
+        throw new RuntimeException("Must be overriden");
+    }
+
+    // ------------------------------------------------------------------------
     // Annotations
     // ------------------------------------------------------------------------
 
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/Textifier.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/Textifier.java	Wed Nov 08 16:03:35 2017 -0500
@@ -182,7 +182,7 @@
      *             If a subclass calls this constructor.
      */
     public Textifier() {
-        this(Opcodes.ASM5);
+        this(Opcodes.ASM6);
         if (getClass() != Textifier.class) {
             throw new IllegalStateException();
         }
@@ -193,7 +193,7 @@
      *
      * @param api
      *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      */
     protected Textifier(final int api) {
         super(api);
@@ -250,6 +250,10 @@
     public void visit(final int version, final int access, final String name,
             final String signature, final String superName,
             final String[] interfaces) {
+        if ((access & Opcodes.ACC_MODULE) != 0) {
+            // visitModule will print the module
+            return;
+        }
         this.access = access;
         int major = version & 0xFFFF;
         int minor = version >>> 16;
@@ -271,7 +275,7 @@
                     .append(sv.getDeclaration()).append('\n');
         }
 
-        appendAccess(access & ~Opcodes.ACC_SUPER);
+        appendAccess(access & ~(Opcodes.ACC_SUPER | Opcodes.ACC_MODULE));
         if ((access & Opcodes.ACC_ANNOTATION) != 0) {
             buf.append("@interface ");
         } else if ((access & Opcodes.ACC_INTERFACE) != 0) {
@@ -315,6 +319,24 @@
     }
 
     @Override
+    public Printer visitModule(final String name, final int access,
+            final String version) {
+        buf.setLength(0);
+        if ((access & Opcodes.ACC_OPEN) != 0) {
+            buf.append("open ");
+        }
+        buf.append("module ")
+           .append(name)
+           .append(" { ")
+           .append(version == null ? "" : "// " + version)
+           .append("\n\n");
+        text.add(buf.toString());
+        Textifier t = createTextifier();
+        text.add(t.getText());
+        return t;
+    }
+
+    @Override
     public void visitOuterClass(final String owner, final String name,
             final String desc) {
         buf.setLength(0);
@@ -443,7 +465,7 @@
         }
 
         buf.append(tab);
-        appendAccess(access & ~Opcodes.ACC_VOLATILE);
+        appendAccess(access & ~(Opcodes.ACC_VOLATILE | Opcodes.ACC_TRANSIENT));
         if ((access & Opcodes.ACC_NATIVE) != 0) {
             buf.append("native ");
         }
@@ -483,6 +505,118 @@
     }
 
     // ------------------------------------------------------------------------
+    // Module
+    // ------------------------------------------------------------------------
+
+    @Override
+    public void visitMainClass(String mainClass) {
+        buf.setLength(0);
+        buf.append("  // main class ").append(mainClass).append('\n');
+        text.add(buf.toString());
+    }
+
+    @Override
+    public void visitPackage(String packaze) {
+        buf.setLength(0);
+        buf.append("  // package ").append(packaze).append('\n');
+        text.add(buf.toString());
+    }
+
+    @Override
+    public void visitRequire(String require, int access, String version) {
+        buf.setLength(0);
+        buf.append(tab).append("requires ");
+        if ((access & Opcodes.ACC_TRANSITIVE) != 0) {
+            buf.append("transitive ");
+        }
+        if ((access & Opcodes.ACC_STATIC_PHASE) != 0) {
+            buf.append("static ");
+        }
+        buf.append(require)
+           .append(";  // access flags 0x")
+           .append(Integer.toHexString(access).toUpperCase())
+           .append('\n');
+        if (version != null) {
+            buf.append("  // version ")
+               .append(version)
+               .append('\n');
+        }
+        text.add(buf.toString());
+    }
+
+    @Override
+    public void visitExport(String export, int access, String... modules) {
+        buf.setLength(0);
+        buf.append(tab).append("exports ");
+        buf.append(export);
+        if (modules != null && modules.length > 0) {
+            buf.append(" to");
+        } else {
+            buf.append(';');
+        }
+        buf.append("  // access flags 0x")
+           .append(Integer.toHexString(access).toUpperCase())
+           .append('\n');
+        if (modules != null && modules.length > 0) {
+            for (int i = 0; i < modules.length; ++i) {
+                buf.append(tab2).append(modules[i]);
+                buf.append(i != modules.length - 1 ? ",\n": ";\n");
+            }
+        }
+        text.add(buf.toString());
+    }
+
+    @Override
+    public void visitOpen(String export, int access, String... modules) {
+        buf.setLength(0);
+        buf.append(tab).append("opens ");
+        buf.append(export);
+        if (modules != null && modules.length > 0) {
+            buf.append(" to");
+        } else {
+            buf.append(';');
+        }
+        buf.append("  // access flags 0x")
+           .append(Integer.toHexString(access).toUpperCase())
+           .append('\n');
+        if (modules != null && modules.length > 0) {
+            for (int i = 0; i < modules.length; ++i) {
+                buf.append(tab2).append(modules[i]);
+                buf.append(i != modules.length - 1 ? ",\n": ";\n");
+            }
+        }
+        text.add(buf.toString());
+    }
+
+    @Override
+    public void visitUse(String use) {
+        buf.setLength(0);
+        buf.append(tab).append("uses ");
+        appendDescriptor(INTERNAL_NAME, use);
+        buf.append(";\n");
+        text.add(buf.toString());
+    }
+
+    @Override
+    public void visitProvide(String provide, String... providers) {
+        buf.setLength(0);
+        buf.append(tab).append("provides ");
+        appendDescriptor(INTERNAL_NAME, provide);
+        buf.append(" with\n");
+        for (int i = 0; i < providers.length; ++i) {
+            buf.append(tab2);
+            appendDescriptor(INTERNAL_NAME, providers[i]);
+            buf.append(i != providers.length - 1 ? ",\n": ";\n");
+        }
+        text.add(buf.toString());
+    }
+
+    @Override
+    public void visitModuleEnd() {
+        // empty
+    }
+
+    // ------------------------------------------------------------------------
     // Annotations
     // ------------------------------------------------------------------------
 
@@ -1296,13 +1430,16 @@
         appendDescriptor(INTERNAL_NAME, h.getOwner());
         buf.append('.');
         buf.append(h.getName());
-        if(!isMethodHandle){
+        if (!isMethodHandle) {
             buf.append('(');
         }
         appendDescriptor(HANDLE_DESCRIPTOR, h.getDesc());
-        if(!isMethodHandle){
+        if (!isMethodHandle) {
             buf.append(')');
         }
+        if (h.isInterface()) {
+            buf.append(" itf");
+        }
     }
 
     /**
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceAnnotationVisitor.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceAnnotationVisitor.java	Wed Nov 08 16:03:35 2017 -0500
@@ -76,7 +76,7 @@
     }
 
     public TraceAnnotationVisitor(final AnnotationVisitor av, final Printer p) {
-        super(Opcodes.ASM5, av);
+        super(Opcodes.ASM6, av);
         this.p = p;
     }
 
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceClassVisitor.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceClassVisitor.java	Wed Nov 08 16:03:35 2017 -0500
@@ -65,6 +65,7 @@
 import jdk.internal.org.objectweb.asm.ClassVisitor;
 import jdk.internal.org.objectweb.asm.FieldVisitor;
 import jdk.internal.org.objectweb.asm.MethodVisitor;
+import jdk.internal.org.objectweb.asm.ModuleVisitor;
 import jdk.internal.org.objectweb.asm.Opcodes;
 import jdk.internal.org.objectweb.asm.TypePath;
 
@@ -160,7 +161,7 @@
      */
     public TraceClassVisitor(final ClassVisitor cv, final Printer p,
             final PrintWriter pw) {
-        super(Opcodes.ASM5, cv);
+        super(Opcodes.ASM6, cv);
         this.pw = pw;
         this.p = p;
     }
@@ -180,6 +181,14 @@
     }
 
     @Override
+    public ModuleVisitor visitModule(String name, int flags,
+            String version) {
+        Printer p = this.p.visitModule(name, flags, version);
+        ModuleVisitor mv = super.visitModule(name, flags, version);
+        return new TraceModuleVisitor(mv, p);
+    }
+
+    @Override
     public void visitOuterClass(final String owner, final String name,
             final String desc) {
         p.visitOuterClass(owner, name, desc);
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceFieldVisitor.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceFieldVisitor.java	Wed Nov 08 16:03:35 2017 -0500
@@ -79,7 +79,7 @@
     }
 
     public TraceFieldVisitor(final FieldVisitor fv, final Printer p) {
-        super(Opcodes.ASM5, fv);
+        super(Opcodes.ASM6, fv);
         this.p = p;
     }
 
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceMethodVisitor.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceMethodVisitor.java	Wed Nov 08 16:03:35 2017 -0500
@@ -81,7 +81,7 @@
     }
 
     public TraceMethodVisitor(final MethodVisitor mv, final Printer p) {
-        super(Opcodes.ASM5, mv);
+        super(Opcodes.ASM6, mv);
         this.p = p;
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceModuleVisitor.java	Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,130 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package jdk.internal.org.objectweb.asm.util;
+
+import jdk.internal.org.objectweb.asm.ModuleVisitor;
+import jdk.internal.org.objectweb.asm.Opcodes;
+
+/**
+ * A {@link ModuleVisitor} that prints the fields it visits with a
+ * {@link Printer}.
+ *
+ * @author Remi Forax
+ */
+public final class TraceModuleVisitor extends ModuleVisitor {
+
+    public final Printer p;
+
+    public TraceModuleVisitor(final Printer p) {
+        this(null, p);
+    }
+
+    public TraceModuleVisitor(final ModuleVisitor mv, final Printer p) {
+        super(Opcodes.ASM6, mv);
+        this.p = p;
+    }
+
+    @Override
+    public void visitMainClass(String mainClass) {
+        p.visitMainClass(mainClass);
+        super.visitMainClass(mainClass);
+    }
+
+    @Override
+    public void visitPackage(String packaze) {
+        p.visitPackage(packaze);
+        super.visitPackage(packaze);
+    }
+
+    @Override
+    public void visitRequire(String module, int access, String version) {
+        p.visitRequire(module, access, version);
+        super.visitRequire(module, access, version);
+    }
+
+    @Override
+    public void visitExport(String packaze, int access, String... modules) {
+        p.visitExport(packaze, access, modules);
+        super.visitExport(packaze, access, modules);
+    }
+
+    @Override
+    public void visitOpen(String packaze, int access, String... modules) {
+        p.visitOpen(packaze, access, modules);
+        super.visitOpen(packaze, access, modules);
+    }
+
+    @Override
+    public void visitUse(String use) {
+        p.visitUse(use);
+        super.visitUse(use);
+    }
+
+    @Override
+    public void visitProvide(String service, String... providers) {
+        p.visitProvide(service, providers);
+        super.visitProvide(service, providers);
+    }
+
+    @Override
+    public void visitEnd() {
+        p.visitModuleEnd();
+        super.visitEnd();
+    }
+}
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceSignatureVisitor.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceSignatureVisitor.java	Wed Nov 08 16:03:35 2017 -0500
@@ -104,13 +104,13 @@
     private String separator = "";
 
     public TraceSignatureVisitor(final int access) {
-        super(Opcodes.ASM5);
+        super(Opcodes.ASM6);
         isInterface = (access & Opcodes.ACC_INTERFACE) != 0;
         this.declaration = new StringBuilder();
     }
 
     private TraceSignatureVisitor(final StringBuilder buf) {
-        super(Opcodes.ASM5);
+        super(Opcodes.ASM6);
         this.declaration = buf;
     }
 
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/version.txt	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/version.txt	Wed Nov 08 16:03:35 2017 -0500
@@ -1,12 +1,4 @@
-Path: .
-Working Copy Root Path: /hudson/jobs/objectweb-init/workspace/asm-svn-2016-01-25
-URL: file:///svnroot/asm/trunk/asm
-Repository Root: file:///svnroot/asm
-Repository UUID: 271bd773-ee82-43a6-9b2b-1890ed8ce7f9
-Revision: 1795
-Node Kind: directory
-Schedule: normal
-Last Changed Author: ebruneton
-Last Changed Rev: 1795
-Last Changed Date: 2016-01-24 14:17:10 +0100 (Sun, 24 Jan 2016)
+ASM_6_0-11-gac81f5f
+origin	https://gitlab.ow2.org/asm/asm.git (fetch)
+ac81f5f Merge branch 'add-class-dump-tool-for-unit-tests' into 'master'
 
--- a/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java	Wed Nov 08 16:03:35 2017 -0500
@@ -2888,7 +2888,7 @@
             /*
              * If we have an input stream this means we received a response
              * from the server. That stream may have been read to EOF and
-             * dependening on the stream type may already be closed or the
+             * depending on the stream type may already be closed or
              * the http client may be returned to the keep-alive cache.
              * If the http client has been returned to the keep-alive cache
              * it may be closed (idle timeout) or may be allocated to
--- a/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/ParameterizedTypeImpl.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/ParameterizedTypeImpl.java	Wed Nov 08 16:03:35 2017 -0500
@@ -66,7 +66,7 @@
     /**
      * Static factory. Given a (generic) class, actual type arguments
      * and an owner type, creates a parameterized type.
-     * This class can be instantiated with a a raw type that does not
+     * This class can be instantiated with a raw type that does not
      * represent a generic type, provided the list of actual type
      * arguments is empty.
      * If the ownerType argument is null, the declaring class of the
--- a/src/java.base/share/classes/sun/security/provider/AuthPolicyFile.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/sun/security/provider/AuthPolicyFile.java	Wed Nov 08 16:03:35 2017 -0500
@@ -411,7 +411,7 @@
                         certs = null;
                     }
 
-                    // only add if we had no signer or we had a
+                    // only add if we had no signer or we had
                     // a signer and found the keys for it.
                     if (certs != null || pe.signedBy == null) {
                             Permission perm = new UnresolvedPermission(
--- a/src/java.base/share/classes/sun/security/provider/PolicyFile.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/sun/security/provider/PolicyFile.java	Wed Nov 08 16:03:35 2017 -0500
@@ -789,7 +789,7 @@
                         certs = null;
                     }
 
-                    // only add if we had no signer or we had a
+                    // only add if we had no signer or we had
                     // a signer and found the keys for it.
                     if (certs != null || pe.signedBy == null) {
                         Permission perm = new UnresolvedPermission(
--- a/src/java.base/share/classes/sun/security/provider/SubjectCodeSource.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/sun/security/provider/SubjectCodeSource.java	Wed Nov 08 16:03:35 2017 -0500
@@ -154,7 +154,7 @@
      *
      * @param codesource the <code>CodeSource</code> to compare against.
      *
-     * @return true if this <code>SubjectCodeSource</code> implies the
+     * @return true if this <code>SubjectCodeSource</code> implies
      *          the specified <code>CodeSource</code>.
      */
     public boolean implies(CodeSource codesource) {
--- a/src/java.base/share/classes/sun/security/ssl/DTLSInputRecord.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/sun/security/ssl/DTLSInputRecord.java	Wed Nov 08 16:03:35 2017 -0500
@@ -539,7 +539,7 @@
 
                 // Should be repacked for suitable fragment length.
                 //
-                // Note that the acquiring processes will reassemble the
+                // Note that the acquiring processes will reassemble
                 // the fragments later.
                 return compareToSequence(o.recordEpoch, o.recordSeq);
             }
--- a/src/java.base/share/classes/sun/security/x509/X509CertImpl.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/sun/security/x509/X509CertImpl.java	Wed Nov 08 16:03:35 2017 -0500
@@ -1485,7 +1485,7 @@
     }
 
     /**
-     * Get the certificate constraints path length from the
+     * Get the certificate constraints path length from
      * the critical BasicConstraints extension, (oid = 2.5.29.19).
      * @return the length of the constraint.
      */
--- a/src/java.base/share/classes/sun/util/logging/PlatformLogger.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.base/share/classes/sun/util/logging/PlatformLogger.java	Wed Nov 08 16:03:35 2017 -0500
@@ -45,7 +45,7 @@
  *
  * If the logging facility is not enabled, the platform loggers
  * will output log messages per the default logging configuration
- * (see below). In this implementation, it does not log the
+ * (see below). In this implementation, it does not log
  * the stack frame information issuing the log message.
  *
  * When the logging facility is enabled (at startup or runtime),
--- a/src/java.compiler/share/classes/javax/lang/model/SourceVersion.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.compiler/share/classes/javax/lang/model/SourceVersion.java	Wed Nov 08 16:03:35 2017 -0500
@@ -183,7 +183,6 @@
                 case "10":
                     return RELEASE_10;
                 case "9":
-                case "1.9":
                     return RELEASE_9;
                 case "1.8":
                     return RELEASE_8;
--- a/src/java.desktop/macosx/classes/com/apple/eawt/FullScreenUtilities.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/macosx/classes/com/apple/eawt/FullScreenUtilities.java	Wed Nov 08 16:03:35 2017 -0500
@@ -25,19 +25,19 @@
 
 package com.apple.eawt;
 
-import java.awt.*;
+import java.awt.Component;
+import java.awt.Window;
 
 import javax.swing.RootPaneContainer;
 
-import sun.lwawt.macosx.*;
-
 import com.apple.eawt.event.GestureUtilities;
+import sun.lwawt.macosx.CPlatformWindow;
 
 /**
  * Utility class perform animated full screen actions to top-level {@link Window}s.
  *
  * This class manages the relationship between {@link Window}s and the {@link FullScreenListener}s
- * attached to them. It's design is similar to the Java SE 6u10 {@link com.sun.awt.AWTUtilities}
+ * attached to them. It's design is similar to the Java SE 6u10 {@code com.sun.awt.AWTUtilities}
  * class which adds additional functionality to AWT Windows, without adding new API to the
  * {@link java.awt.Window} class.
  *
@@ -45,7 +45,6 @@
  *
  * @see FullScreenAdapter
  * @see GestureUtilities
- * @see com.sun.awt.AWTUtilities
  *
  * @since Java for Mac OS X 10.7 Update 1
  */
--- a/src/java.desktop/macosx/classes/com/apple/eawt/event/GestureUtilities.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/macosx/classes/com/apple/eawt/event/GestureUtilities.java	Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,13 +25,15 @@
 
 package com.apple.eawt.event;
 
-import javax.swing.*;
+import javax.swing.JComponent;
+import javax.swing.JFrame;
+import javax.swing.JRootPane;
 
 /**
  * Registration utility class to add {@link GestureListener}s to Swing components.
  *
  * This class manages the relationship between {@link JComponent}s and the {@link GestureListener}s
- * attached to them. It's design is similar to the Java SE 6u10 {@link com.sun.awt.AWTUtilities}
+ * attached to them. It's design is similar to the Java SE 6u10 {@code com.sun.awt.AWTUtilities}
  * class which adds additional functionality to AWT Windows, without adding new API to the
  * {@link java.awt.Window} class.
  *
@@ -40,7 +42,6 @@
  *
  * @see GestureAdapter
  * @see JFrame#getRootPane()
- * @see com.sun.awt.AWTUtilities
  *
  * @since Java for Mac OS X 10.5 Update 7, Java for Mac OS X 10.6 Update 2
  */
--- a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java	Wed Nov 08 16:03:35 2017 -0500
@@ -25,35 +25,50 @@
 
 package sun.lwawt.macosx;
 
-import com.apple.eawt.FullScreenAdapter;
-import com.apple.eawt.FullScreenUtilities;
-import com.apple.eawt.event.FullScreenEvent;
-import java.awt.*;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.DefaultKeyboardFocusManager;
+import java.awt.Dialog;
 import java.awt.Dialog.ModalityType;
-import java.awt.event.*;
-import java.beans.*;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Frame;
+import java.awt.GraphicsDevice;
+import java.awt.Insets;
+import java.awt.MenuBar;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.Toolkit;
+import java.awt.Window;
+import java.awt.event.FocusEvent;
+import java.awt.event.WindowEvent;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
 import java.lang.reflect.InvocationTargetException;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Comparator;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.concurrent.atomic.AtomicReference;
 
-import javax.swing.*;
+import javax.swing.JRootPane;
+import javax.swing.RootPaneContainer;
+import javax.swing.SwingUtilities;
 
-import sun.awt.*;
+import com.apple.laf.ClientPropertyApplicator;
+import com.apple.laf.ClientPropertyApplicator.Property;
+import sun.awt.AWTAccessor;
 import sun.awt.AWTAccessor.ComponentAccessor;
 import sun.awt.AWTAccessor.WindowAccessor;
 import sun.java2d.SurfaceData;
 import sun.java2d.opengl.CGLSurfaceData;
-import sun.lwawt.*;
+import sun.lwawt.LWToolkit;
+import sun.lwawt.LWWindowPeer;
+import sun.lwawt.LWWindowPeer.PeerType;
+import sun.lwawt.PlatformWindow;
 import sun.util.logging.PlatformLogger;
 
-import com.apple.laf.*;
-import com.apple.laf.ClientPropertyApplicator.Property;
-import com.sun.awt.AWTUtilities;
-import sun.lwawt.LWWindowPeer.PeerType;
-
 public class CPlatformWindow extends CFRetainedResource implements PlatformWindow {
     private native long nativeCreateNSWindow(long nsViewPtr,long ownerPtr, long styleBits, double x, double y, double w, double h);
     private static native void nativeSetNSWindowStyleBits(long nsWindowPtr, int mask, int data);
@@ -172,7 +187,7 @@
             c.setStyleBits(TEXTURED, Boolean.parseBoolean(value.toString()));
         }},
         new Property<CPlatformWindow>(WINDOW_ALPHA) { public void applyProperty(final CPlatformWindow c, final Object value) {
-            AWTUtilities.setWindowOpacity(c.target, value == null ? 1.0f : Float.parseFloat(value.toString()));
+            c.target.setOpacity(value == null ? 1.0f : Float.parseFloat(value.toString()));
         }},
         new Property<CPlatformWindow>(WINDOW_SHADOW) { public void applyProperty(final CPlatformWindow c, final Object value) {
             c.setStyleBits(HAS_SHADOW, value == null ? true : Boolean.parseBoolean(value.toString()));
@@ -224,6 +239,20 @@
             return (CPlatformWindow)((LWWindowPeer)acc.getPeer(root)).getPlatformWindow();
         }
     };
+    private final Comparator<Window> siblingsComparator = (w1, w2) -> {
+        if (w1 == w2) {
+            return 0;
+        }
+        ComponentAccessor componentAccessor = AWTAccessor.getComponentAccessor();
+        Object p1 = componentAccessor.getPeer(w1);
+        Object p2 = componentAccessor.getPeer(w2);
+        if (p1 instanceof LWWindowPeer && p2 instanceof LWWindowPeer) {
+            return Long.compare(
+                    ((CPlatformWindow) (((LWWindowPeer) p1).getPlatformWindow())).lastBecomeMainTime,
+                    ((CPlatformWindow) (((LWWindowPeer) p2).getPlatformWindow())).lastBecomeMainTime);
+        }
+        return 0;
+    };
 
     // Bounds of the native widget but in the Java coordinate system.
     // In order to keep it up-to-date we will update them on
@@ -245,6 +274,7 @@
     private boolean undecorated; // initialized in getInitialStyleBits()
     private Rectangle normalBounds = null; // not-null only for undecorated maximized windows
     private CPlatformResponder responder;
+    private long lastBecomeMainTime; // this is necessary to preserve right siblings order
 
     public CPlatformWindow() {
         super(0, true);
@@ -1172,8 +1202,9 @@
 
         final ComponentAccessor componentAccessor = AWTAccessor.getComponentAccessor();
         final WindowAccessor windowAccessor = AWTAccessor.getWindowAccessor();
-
+        Arrays.sort(windows, siblingsComparator);
         // Go through the list of windows and perform ordering.
+        CPlatformWindow pwUnder = null;
         for (Window w : windows) {
             boolean iconified = false;
             final Object p = componentAccessor.getPeer(w);
@@ -1187,11 +1218,15 @@
                     if (pw.isOneOfOwnersOrSelf(this)) {
                         pw.execute(CWrapper.NSWindow::orderFront);
                     } else {
-                        pw.owner.execute(ownerPtr -> {
+                        if (pwUnder == null) {
+                            pwUnder = pw.owner;
+                        }
+                        pwUnder.execute(underPtr -> {
                             pw.execute(ptr -> {
-                                CWrapper.NSWindow.orderWindow(ptr, CWrapper.NSWindow.NSWindowAbove, ownerPtr);
+                                CWrapper.NSWindow.orderWindow(ptr, CWrapper.NSWindow.NSWindowAbove, underPtr);
                             });
                         });
+                        pwUnder = pw;
                     }
                     pw.applyWindowLevel(w);
                 }
@@ -1228,6 +1263,7 @@
     }
 
     private void windowDidBecomeMain() {
+        lastBecomeMainTime = System.currentTimeMillis();
         if (checkBlockingAndOrder()) return;
         // If it's not blocked, make sure it's above its siblings
         orderAboveSiblings();
--- a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CTrayIcon.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CTrayIcon.java	Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,26 +25,37 @@
 
 package sun.lwawt.macosx;
 
-import sun.awt.AWTAccessor;
-import sun.awt.SunToolkit;
-
-import javax.swing.*;
-import java.awt.*;
-import java.awt.event.*;
+import java.awt.AWTEvent;
+import java.awt.Button;
+import java.awt.Frame;
+import java.awt.Graphics2D;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsDevice;
+import java.awt.GraphicsEnvironment;
+import java.awt.Image;
+import java.awt.MediaTracker;
+import java.awt.PopupMenu;
+import java.awt.RenderingHints;
+import java.awt.Toolkit;
+import java.awt.Transparency;
+import java.awt.TrayIcon;
+import java.awt.event.ActionEvent;
+import java.awt.event.MouseEvent;
 import java.awt.geom.Point2D;
 import java.awt.image.BufferedImage;
 import java.awt.peer.TrayIconPeer;
-import java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
-import java.util.concurrent.atomic.AtomicReference;
+
+import javax.swing.Icon;
+import javax.swing.UIManager;
 
-import static sun.awt.AWTAccessor.*;
+import sun.awt.SunToolkit;
+
+import static sun.awt.AWTAccessor.MenuComponentAccessor;
+import static sun.awt.AWTAccessor.getMenuComponentAccessor;
 
 public class CTrayIcon extends CFRetainedResource implements TrayIconPeer {
     private TrayIcon target;
     private PopupMenu popup;
-    private JDialog messageDialog;
-    private DialogEventHandler handler;
 
     // In order to construct MouseEvent object, we need to specify a
     // Component target. Because TrayIcon isn't Component's subclass,
@@ -59,8 +70,6 @@
     CTrayIcon(TrayIcon target) {
         super(0, true);
 
-        this.messageDialog = null;
-        this.handler = null;
         this.target = target;
         this.popup = target.getPopupMenu();
         this.dummyFrame = new Frame();
@@ -129,28 +138,25 @@
      */
     public void displayMessage(final String caption, final String text,
                                final String messageType) {
-
-        if (SwingUtilities.isEventDispatchThread()) {
-            displayMessageOnEDT(caption, text, messageType);
+        // obtain icon to show along the message
+        Icon icon = getIconForMessageType(messageType);
+        CImage cimage = null;
+        if (icon != null) {
+            BufferedImage image = scaleIcon(icon, 0.75);
+            cimage = CImage.getCreator().createFromImage(image);
+        }
+        if (cimage != null) {
+            cimage.execute(imagePtr -> {
+                execute(ptr -> nativeShowNotification(ptr, caption, text,
+                                                      imagePtr));
+            });
         } else {
-            try {
-                SwingUtilities.invokeAndWait(new Runnable() {
-                    public void run() {
-                        displayMessageOnEDT(caption, text, messageType);
-                    }
-                });
-            } catch (Exception e) {
-                throw new AssertionError(e);
-            }
+            execute(ptr -> nativeShowNotification(ptr, caption, text, 0));
         }
     }
 
     @Override
     public void dispose() {
-        if (messageDialog != null) {
-            disposeMessageDialog();
-        }
-
         dummyFrame.dispose();
 
         if (popup != null) {
@@ -276,154 +282,14 @@
         }
     }
 
-    private native Point2D nativeGetIconLocation(long trayIconModel);
-
-    public void displayMessageOnEDT(String caption, String text,
-                                    String messageType) {
-        if (messageDialog != null) {
-            disposeMessageDialog();
-        }
-
-        // obtain icon to show along the message
-        Icon icon = getIconForMessageType(messageType);
-        if (icon != null) {
-            icon = new ImageIcon(scaleIcon(icon, 0.75));
-        }
-
-        // We want the message dialog text area to be about 1/8 of the screen
-        // size. There is nothing special about this value, it's just makes the
-        // message dialog to look nice
-        Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
-        int textWidth = screenSize.width / 8;
-
-        // create dialog to show
-        messageDialog = createMessageDialog(caption, text, textWidth, icon);
-
-        // finally, show the dialog to user
-        showMessageDialog();
-    }
+    private native void nativeShowNotification(long trayIconModel,
+                                               String caption, String text,
+                                               long nsimage);
 
     /**
-     * Creates dialog window used to display the message
+     * Used by the automated tests.
      */
-    private JDialog createMessageDialog(String caption, String text,
-                                     int textWidth, Icon icon) {
-        JDialog dialog;
-        handler = new DialogEventHandler();
-
-        JTextArea captionArea = null;
-        if (caption != null) {
-            captionArea = createTextArea(caption, textWidth, false, true);
-        }
-
-        JTextArea textArea = null;
-        if (text != null){
-            textArea = createTextArea(text, textWidth, true, false);
-        }
-
-        Object[] panels = null;
-        if (captionArea != null) {
-            if (textArea != null) {
-                panels = new Object[] {captionArea, new JLabel(), textArea};
-            } else {
-                panels = new Object[] {captionArea};
-            }
-        } else {
-           if (textArea != null) {
-                panels = new Object[] {textArea};
-            }
-        }
-
-        // We want message dialog with small title bar. There is a client
-        // property property that does it, however, it must be set before
-        // dialog's native window is created. This is why we create option
-        // pane and dialog separately
-        final JOptionPane op = new JOptionPane(panels);
-        op.setIcon(icon);
-        op.addPropertyChangeListener(handler);
-
-        // Make Ok button small. Most likely won't work for L&F other then Aqua
-        try {
-            JPanel buttonPanel = (JPanel)op.getComponent(1);
-            JButton ok = (JButton)buttonPanel.getComponent(0);
-            ok.putClientProperty("JComponent.sizeVariant", "small");
-        } catch (Throwable t) {
-            // do nothing, we tried and failed, no big deal
-        }
-
-        dialog = new JDialog((Dialog) null);
-        JRootPane rp = dialog.getRootPane();
-
-        // gives us dialog window with small title bar and not zoomable
-        rp.putClientProperty(CPlatformWindow.WINDOW_STYLE, "small");
-        rp.putClientProperty(CPlatformWindow.WINDOW_ZOOMABLE, "false");
-
-        dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
-        dialog.setModal(false);
-        dialog.setModalExclusionType(Dialog.ModalExclusionType.TOOLKIT_EXCLUDE);
-        dialog.setAlwaysOnTop(true);
-        dialog.setAutoRequestFocus(false);
-        dialog.setResizable(false);
-        dialog.setContentPane(op);
-
-        dialog.addWindowListener(handler);
-
-        // suppress security warning for untrusted windows
-        AWTAccessor.getWindowAccessor().setTrayIconWindow(dialog, true);
-
-        dialog.pack();
-
-        return dialog;
-    }
-
-    private void showMessageDialog() {
-
-        Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
-        AtomicReference<Point2D> ref = new AtomicReference<>();
-        execute(ptr -> {
-            ref.set(nativeGetIconLocation(ptr));
-        });
-        Point2D iconLoc = ref.get();
-        if (iconLoc == null) {
-            return;
-        }
-
-        int dialogY = (int)iconLoc.getY();
-        int dialogX = (int)iconLoc.getX();
-        if (dialogX + messageDialog.getWidth() > screenSize.width) {
-            dialogX = screenSize.width - messageDialog.getWidth();
-        }
-
-        messageDialog.setLocation(dialogX, dialogY);
-        messageDialog.setVisible(true);
-    }
-
-   private void disposeMessageDialog() {
-        if (SwingUtilities.isEventDispatchThread()) {
-            disposeMessageDialogOnEDT();
-        } else {
-            try {
-                SwingUtilities.invokeAndWait(new Runnable() {
-                    public void run() {
-                        disposeMessageDialogOnEDT();
-                    }
-                });
-            } catch (Exception e) {
-                throw new AssertionError(e);
-            }
-        }
-   }
-
-    private void disposeMessageDialogOnEDT() {
-        if (messageDialog != null) {
-            messageDialog.removeWindowListener(handler);
-            messageDialog.removePropertyChangeListener(handler);
-            messageDialog.dispose();
-
-            messageDialog = null;
-            handler = null;
-        }
-    }
+    private native Point2D nativeGetIconLocation(long trayIconModel);
 
     /**
      * Scales an icon using specified scale factor
@@ -480,56 +346,5 @@
             return UIManager.getIcon("OptionPane.informationIcon");
         }
     }
-
-    private static JTextArea createTextArea(String text, int width,
-                                            boolean isSmall, boolean isBold) {
-        JTextArea textArea = new JTextArea(text);
-
-        textArea.setLineWrap(true);
-        textArea.setWrapStyleWord(true);
-        textArea.setEditable(false);
-        textArea.setFocusable(false);
-        textArea.setBorder(null);
-        textArea.setBackground(new JLabel().getBackground());
-
-        if (isSmall) {
-            textArea.putClientProperty("JComponent.sizeVariant", "small");
-        }
-
-        if (isBold) {
-            Font font = textArea.getFont();
-            Font boldFont = new Font(font.getName(), Font.BOLD, font.getSize());
-            textArea.setFont(boldFont);
-        }
-
-        textArea.setSize(width, 1);
-
-        return textArea;
-    }
-
-    /**
-     * Implements all the Listeners needed by message dialog
-     */
-    private final class DialogEventHandler extends WindowAdapter
-            implements PropertyChangeListener {
-
-        public void windowClosing(WindowEvent we) {
-                disposeMessageDialog();
-        }
-
-        public void propertyChange(PropertyChangeEvent e) {
-            if (messageDialog == null) {
-                return;
-            }
-
-            String prop = e.getPropertyName();
-            Container cp = messageDialog.getContentPane();
-
-            if (messageDialog.isVisible() && e.getSource() == cp &&
-                    (prop.equals(JOptionPane.VALUE_PROPERTY))) {
-                disposeMessageDialog();
-            }
-        }
-    }
 }
 
--- a/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTView.m	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTView.m	Wed Nov 08 16:03:35 2017 -0500
@@ -74,20 +74,20 @@
     // Initialize ourselves
     self = [super initWithFrame: rect];
     if (self == nil) return self;
-    
+
     m_cPlatformView = cPlatformView;
     fInputMethodLOCKABLE = NULL;
     fKeyEventsNeeded = NO;
     fProcessingKeystroke = NO;
-    
+
     fEnablePressAndHold = shouldUsePressAndHold();
     fInPressAndHold = NO;
     fPAHNeedsToSelect = NO;
-    
+
     mouseIsOver = NO;
     [self resetTrackingArea];
     [self setAutoresizesSubviews:NO];
-    
+
     if (windowLayer != nil) {
         self.cglLayer = windowLayer;
         //Layer hosting view
@@ -98,7 +98,7 @@
         //[self setLayerContentsRedrawPolicy: NSViewLayerContentsRedrawDuringViewResize];
         //[self setLayerContentsPlacement: NSViewLayerContentsPlacementTopLeft];
         //[self setAutoresizingMask: NSViewHeightSizable | NSViewWidthSizable];
-        
+
 #ifdef REMOTELAYER
         CGLLayer *parentLayer = (CGLLayer*)self.cglLayer;
         parentLayer.parentLayer = NULL;
@@ -120,36 +120,36 @@
         }
 #endif /* REMOTELAYER */
     }
-    
+
     return self;
 }
 
 - (void) dealloc {
     AWT_ASSERT_APPKIT_THREAD;
-    
+
     self.cglLayer = nil;
-    
+
     JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
     (*env)->DeleteWeakGlobalRef(env, m_cPlatformView);
     m_cPlatformView = NULL;
-    
+
     if (fInputMethodLOCKABLE != NULL)
     {
         JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
-        
+
         JNFDeleteGlobalRef(env, fInputMethodLOCKABLE);
         fInputMethodLOCKABLE = NULL;
     }
-    
-    
+
+
     [super dealloc];
 }
 
 - (void) viewDidMoveToWindow {
     AWT_ASSERT_APPKIT_THREAD;
-    
+
     [AWTToolkit eventCountPlusPlus];
-    
+
     [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^() {
         [[self window] makeFirstResponder: self];
     }];
@@ -230,10 +230,10 @@
 
 - (void) mouseMoved: (NSEvent *)event {
     // TODO: better way to redirect move events to the "under" view
-    
+
     NSPoint eventLocation = [event locationInWindow];
     NSPoint localPoint = [self convertPoint: eventLocation fromView: nil];
-    
+
     if  ([self mouse: localPoint inRect: [self bounds]]) {
         [self deliverJavaMouseEvent: event];
     } else {
@@ -277,10 +277,10 @@
 - (void) keyDown: (NSEvent *)event {
     fProcessingKeystroke = YES;
     fKeyEventsNeeded = YES;
-    
+
     // Allow TSM to look at the event and potentially send back NSTextInputClient messages.
     [self interpretKeyEvents:[NSArray arrayWithObject:event]];
-    
+
     if (fEnablePressAndHold && [event willBeHandledByComplexInputMethod] && fInputMethodLOCKABLE) {
         fProcessingKeystroke = NO;
         if (!fInPressAndHold) {
@@ -289,14 +289,14 @@
         }
         return;
     }
-    
+
     NSString *eventCharacters = [event characters];
     BOOL isDeadKey = (eventCharacters != nil && [eventCharacters length] == 0);
-    
+
     if ((![self hasMarkedText] && fKeyEventsNeeded) || isDeadKey) {
         [self deliverJavaKeyEventHelper: event];
     }
-    
+
     fProcessingKeystroke = NO;
 }
 
@@ -313,7 +313,7 @@
     if (![self hasMarkedText] && !fInPressAndHold) {
         [self deliverJavaKeyEventHelper: event];
     }
-    
+
     // Workaround for 8020209: special case for "Cmd =" and "Cmd ."
     // because Cocoa calls performKeyEquivalent twice for these keystrokes
     NSUInteger modFlags = [event modifierFlags] &
@@ -327,9 +327,9 @@
                 return YES;
             }
         }
-        
+
     }
-    
+
     return NO;
 }
 
@@ -343,36 +343,36 @@
     if ([window isKindOfClass: [AWTWindow_Panel class]] || [window isKindOfClass: [AWTWindow_Normal class]]) {
         isEnabled = [(AWTWindow*)[window delegate] isEnabled];
     }
-    
+
     if (!isEnabled) {
         return;
     }
-    
+
     NSEventType type = [event type];
-    
+
     // check synthesized mouse entered/exited events
     if ((type == NSMouseEntered && mouseIsOver) || (type == NSMouseExited && !mouseIsOver)) {
         return;
     }else if ((type == NSMouseEntered && !mouseIsOver) || (type == NSMouseExited && mouseIsOver)) {
         mouseIsOver = !mouseIsOver;
     }
-    
+
     [AWTToolkit eventCountPlusPlus];
-    
+
     JNIEnv *env = [ThreadUtilities getJNIEnv];
-    
+
     NSPoint eventLocation = [event locationInWindow];
     NSPoint localPoint = [self convertPoint: eventLocation fromView: nil];
     NSPoint absP = [NSEvent mouseLocation];
-    
+
     // Convert global numbers between Cocoa's coordinate system and Java.
     // TODO: need consitent way for doing that both with global as well as with local coordinates.
     // The reason to do it here is one more native method for getting screen dimension otherwise.
-    
+
     NSRect screenRect = [[[NSScreen screens] objectAtIndex:0] frame];
     absP.y = screenRect.size.height - absP.y;
     jint clickCount;
-    
+
     if (type == NSMouseEntered ||
         type == NSMouseExited ||
         type == NSScrollWheel ||
@@ -388,7 +388,7 @@
         deltaX = [event scrollingDeltaX] * 0.1;
         deltaY = [event scrollingDeltaY] * 0.1;
     }
-    
+
     static JNF_CLASS_CACHE(jc_NSEvent, "sun/lwawt/macosx/NSEvent");
     static JNF_CTOR_CACHE(jctor_NSEvent, jc_NSEvent, "(IIIIIIIIDDI)V");
     jobject jEvent = JNFNewObject(env, jctor_NSEvent,
@@ -402,7 +402,7 @@
                                   deltaX,
                                   [AWTToolkit scrollStateWithEvent: event]);
     CHECK_NULL(jEvent);
-    
+
     static JNF_CLASS_CACHE(jc_PlatformView, "sun/lwawt/macosx/CPlatformView");
     static JNF_MEMBER_CACHE(jm_deliverMouseEvent, jc_PlatformView, "deliverMouseEvent", "(Lsun/lwawt/macosx/NSEvent;)V");
     jobject jlocal = (*env)->NewLocalRef(env, m_cPlatformView);
@@ -418,10 +418,10 @@
         [self removeTrackingArea:rolloverTrackingArea];
         [rolloverTrackingArea release];
     }
-    
+
     int options = (NSTrackingActiveAlways | NSTrackingMouseEnteredAndExited |
                    NSTrackingMouseMoved | NSTrackingEnabledDuringMouseDrag);
-    
+
     rolloverTrackingArea = [[NSTrackingArea alloc] initWithRect:[self visibleRect]
                                                         options: options
                                                           owner:self
@@ -448,17 +448,17 @@
     }
     [sLastKeyEvent release];
     sLastKeyEvent = [event retain];
-    
+
     [AWTToolkit eventCountPlusPlus];
     JNIEnv *env = [ThreadUtilities getJNIEnv];
-    
+
     jstring characters = NULL;
     jstring charactersIgnoringModifiers = NULL;
     if ([event type] != NSFlagsChanged) {
         characters = JNFNSToJavaString(env, [event characters]);
         charactersIgnoringModifiers = JNFNSToJavaString(env, [event charactersIgnoringModifiers]);
     }
-    
+
     static JNF_CLASS_CACHE(jc_NSEvent, "sun/lwawt/macosx/NSEvent");
     static JNF_CTOR_CACHE(jctor_NSEvent, jc_NSEvent, "(IISLjava/lang/String;Ljava/lang/String;)V");
     jobject jEvent = JNFNewObject(env, jctor_NSEvent,
@@ -468,7 +468,7 @@
                                   characters,
                                   charactersIgnoringModifiers);
     CHECK_NULL(jEvent);
-    
+
     static JNF_CLASS_CACHE(jc_PlatformView, "sun/lwawt/macosx/CPlatformView");
     static JNF_MEMBER_CACHE(jm_deliverKeyEvent, jc_PlatformView,
                             "deliverKeyEvent", "(Lsun/lwawt/macosx/NSEvent;)V");
@@ -502,7 +502,7 @@
 
 - (void) drawRect:(NSRect)dirtyRect {
     AWT_ASSERT_APPKIT_THREAD;
-    
+
     [super drawRect:dirtyRect];
     JNIEnv *env = [ThreadUtilities getJNIEnv];
     if (env != NULL) {
@@ -615,17 +615,17 @@
 - (id)accessibilityAttributeValue:(NSString *)attribute
 {
     AWT_ASSERT_APPKIT_THREAD;
-    
+
     if ([attribute isEqualToString:NSAccessibilityChildrenAttribute])
     {
         JNIEnv *env = [ThreadUtilities getJNIEnv];
-        
+
         (*env)->PushLocalFrame(env, 4);
-        
+
         id result = NSAccessibilityUnignoredChildrenForOnlyChild([self getAxData:env]);
-        
+
         (*env)->PopLocalFrame(env, NULL);
-        
+
         return result;
     }
     else
@@ -642,28 +642,28 @@
 {
     AWT_ASSERT_APPKIT_THREAD;
     JNIEnv *env = [ThreadUtilities getJNIEnv];
-    
+
     (*env)->PushLocalFrame(env, 4);
-    
+
     id result = [[self getAxData:env] accessibilityHitTest:point withEnv:env];
-    
+
     (*env)->PopLocalFrame(env, NULL);
-    
+
     return result;
 }
 
 - (id)accessibilityFocusedUIElement
 {
     AWT_ASSERT_APPKIT_THREAD;
-    
+
     JNIEnv *env = [ThreadUtilities getJNIEnv];
-    
+
     (*env)->PushLocalFrame(env, 4);
-    
+
     id result = [[self getAxData:env] accessibilityFocusedUIElement];
-    
+
     (*env)->PopLocalFrame(env, NULL);
-    
+
     return result;
 }
 
@@ -702,12 +702,12 @@
 - (id)validRequestorForSendType:(NSString *)sendType returnType:(NSString *)returnType
 {
     if ([[self window] firstResponder] != self) return nil; // let AWT components handle themselves
-    
+
     if ([sendType isEqual:NSStringPboardType] || [returnType isEqual:NSStringPboardType]) {
         NSString *selectedText = [self accessibleSelectedText];
         if (selectedText) return self;
     }
-    
+
     return nil;
 }
 
@@ -719,13 +719,13 @@
         [pboard declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:nil];
         return [pboard setString:[self accessibleSelectedText] forType:NSStringPboardType];
     }
-    
+
     if ([types containsObject:NSRTFDPboardType])
     {
         [pboard declareTypes:[NSArray arrayWithObject:NSRTFDPboardType] owner:nil];
         return [pboard setData:[self accessibleSelectedTextAsRTFD] forType:NSRTFDPboardType];
     }
-    
+
     return NO;
 }
 
@@ -737,17 +737,17 @@
         NSString *text = [pboard stringForType:NSStringPboardType];
         return [self replaceAccessibleTextSelection:text];
     }
-    
+
     if ([[pboard types] containsObject:NSRTFDPboardType])
     {
         NSData *rtfdData = [pboard dataForType:NSRTFDPboardType];
         NSAttributedString *styledText = [[NSAttributedString alloc] initWithRTFD:rtfdData documentAttributes:NULL];
         NSString *text = [styledText string];
         [styledText release];
-        
+
         return [self replaceAccessibleTextSelection:text];
     }
-    
+
     return NO;
 }
 
@@ -769,7 +769,7 @@
     // If draggingSource is nil route the message to the superclass (if responding to the selector):
     CDragSource *dragSource = self._dragSource;
     NSDragOperation dragOp = NSDragOperationNone;
-    
+
     if (dragSource != nil) {
         dragOp = [dragSource draggingSourceOperationMaskForLocal:flag];
     }
@@ -781,7 +781,7 @@
     // If draggingSource is nil route the message to the superclass (if responding to the selector):
     CDragSource *dragSource = self._dragSource;
     NSArray* array = nil;
-    
+
     if (dragSource != nil) {
         array = [dragSource namesOfPromisedFilesDroppedAtDestination:dropDestination];
     }
@@ -792,7 +792,7 @@
 {
     // If draggingSource is nil route the message to the superclass (if responding to the selector):
     CDragSource *dragSource = self._dragSource;
-    
+
     if (dragSource != nil) {
         [dragSource draggedImage:image beganAt:screenPoint];
     }
@@ -802,7 +802,7 @@
 {
     // If draggingSource is nil route the message to the superclass (if responding to the selector):
     CDragSource *dragSource = self._dragSource;
-    
+
     if (dragSource != nil) {
         [dragSource draggedImage:image endedAt:screenPoint operation:operation];
     }
@@ -812,7 +812,7 @@
 {
     // If draggingSource is nil route the message to the superclass (if responding to the selector):
     CDragSource *dragSource = self._dragSource;
-    
+
     if (dragSource != nil) {
         [dragSource draggedImage:image movedTo:screenPoint];
     }
@@ -823,7 +823,7 @@
     // If draggingSource is nil route the message to the superclass (if responding to the selector):
     CDragSource *dragSource = self._dragSource;
     BOOL result = FALSE;
-    
+
     if (dragSource != nil) {
         result = [dragSource ignoreModifierKeysWhileDragging];
     }
@@ -839,7 +839,7 @@
     // If draggingDestination is nil route the message to the superclass:
     CDropTarget *dropTarget = self._dropTarget;
     NSDragOperation dragOp = NSDragOperationNone;
-    
+
     if (dropTarget != nil) {
         dragOp = [dropTarget draggingEntered:sender];
     }
@@ -851,7 +851,7 @@
     // If draggingDestination is nil route the message to the superclass:
     CDropTarget *dropTarget = self._dropTarget;
     NSDragOperation dragOp = NSDragOperationNone;
-    
+
     if (dropTarget != nil) {
         dragOp = [dropTarget draggingUpdated:sender];
     }
@@ -862,7 +862,7 @@
 {
     // If draggingDestination is nil route the message to the superclass:
     CDropTarget *dropTarget = self._dropTarget;
-    
+
     if (dropTarget != nil) {
         [dropTarget draggingExited:sender];
     }
@@ -873,7 +873,7 @@
     // If draggingDestination is nil route the message to the superclass:
     CDropTarget *dropTarget = self._dropTarget;
     BOOL result = FALSE;
-    
+
     if (dropTarget != nil) {
         result = [dropTarget prepareForDragOperation:sender];
     }
@@ -885,7 +885,7 @@
     // If draggingDestination is nil route the message to the superclass:
     CDropTarget *dropTarget = self._dropTarget;
     BOOL result = FALSE;
-    
+
     if (dropTarget != nil) {
         result = [dropTarget performDragOperation:sender];
     }
@@ -896,7 +896,7 @@
 {
     // If draggingDestination is nil route the message to the superclass:
     CDropTarget *dropTarget = self._dropTarget;
-    
+
     if (dropTarget != nil) {
         [dropTarget concludeDragOperation:sender];
     }
@@ -906,7 +906,7 @@
 {
     // If draggingDestination is nil route the message to the superclass:
     CDropTarget *dropTarget = self._dropTarget;
-    
+
     if (dropTarget != nil) {
         [dropTarget draggingEnded:sender];
     }
@@ -924,20 +924,20 @@
 #ifdef IM_DEBUG
     fprintf(stderr, "AWTView InputMethod Selector Called : [insertText]: %s\n", [aString UTF8String]);
 #endif // IM_DEBUG
-    
+
     if (fInputMethodLOCKABLE == NULL) {
         return;
     }
-    
+
     // Insert happens at the end of PAH
     fInPressAndHold = NO;
-    
+
     // insertText gets called when the user commits text generated from an input method.  It also gets
     // called during ordinary input as well.  We only need to send an input method event when we have marked
     // text, or 'text in progress'.  We also need to send the event if we get an insert text out of the blue!
     // (i.e., when the user uses the Character palette or Inkwell), or when the string to insert is a complex
     // Unicode value.
-    
+
     NSMutableString * useString = [self parseString:aString];
     NSUInteger utf16Length = [useString lengthOfBytesUsingEncoding:NSUTF16StringEncoding];
     NSUInteger utf8Length = [useString lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
@@ -946,22 +946,22 @@
         ((utf8Length > 1) && [self isCodePointInUnicodeBlockNeedingIMEvent:[useString characterAtIndex:0]])) {
         aStringIsComplex = YES;
     }
-    
+
     if ([self hasMarkedText] || !fProcessingKeystroke || aStringIsComplex) {
         JNIEnv *env = [ThreadUtilities getJNIEnv];
-        
+
         static JNF_MEMBER_CACHE(jm_selectPreviousGlyph, jc_CInputMethod, "selectPreviousGlyph", "()V");
         // We need to select the previous glyph so that it is overwritten.
         if (fPAHNeedsToSelect) {
             JNFCallVoidMethod(env, fInputMethodLOCKABLE, jm_selectPreviousGlyph);
             fPAHNeedsToSelect = NO;
         }
-        
+
         static JNF_MEMBER_CACHE(jm_insertText, jc_CInputMethod, "insertText", "(Ljava/lang/String;)V");
         jstring insertedText =  JNFNSToJavaString(env, useString);
         JNFCallVoidMethod(env, fInputMethodLOCKABLE, jm_insertText, insertedText); // AWT_THREADING Safe (AWTRunLoopMode)
         (*env)->DeleteLocalRef(env, insertedText);
-        
+
         // The input method event will create psuedo-key events for each character in the committed string.
         // We also don't want to send the character that triggered the insertText, usually a return. [3337563]
         fKeyEventsNeeded = NO;
@@ -993,7 +993,7 @@
 {
     if (!fInputMethodLOCKABLE)
         return;
-    
+
     BOOL isAttributedString = [aString isKindOfClass:[NSAttributedString class]];
     NSAttributedString *attrString = (isAttributedString ? (NSAttributedString *)aString : nil);
     NSString *incomingString = (isAttributedString ? [aString string] : aString);
@@ -1004,14 +1004,14 @@
     static JNF_MEMBER_CACHE(jm_addAttribute, jc_CInputMethod, "addAttribute", "(ZZII)V");
     static JNF_MEMBER_CACHE(jm_dispatchText, jc_CInputMethod, "dispatchText", "(IIZ)V");
     JNIEnv *env = [ThreadUtilities getJNIEnv];
-    
+
     // NSInputContext already did the analysis of the TSM event and created attributes indicating
     // the underlining and color that should be done to the string.  We need to look at the underline
     // style and color to determine what kind of Java hilighting needs to be done.
     jstring inProcessText = JNFNSToJavaString(env, incomingString);
     JNFCallVoidMethod(env, fInputMethodLOCKABLE, jm_startIMUpdate, inProcessText); // AWT_THREADING Safe (AWTRunLoopMode)
     (*env)->DeleteLocalRef(env, inProcessText);
-    
+
     if (isAttributedString) {
         NSUInteger length;
         NSRange effectiveRange;
@@ -1027,25 +1027,25 @@
                 (NSNumber *)[attributes objectForKey:NSUnderlineStyleAttributeName];
                 NSInteger underlineSize = [underlineSizeObj integerValue];
                 isThickUnderline = (underlineSize > 1);
-                
+
                 NSColor *underlineColorObj =
                 (NSColor *)[attributes objectForKey:NSUnderlineColorAttributeName];
                 isGray = !([underlineColorObj isEqual:[NSColor blackColor]]);
-                
+
                 JNFCallVoidMethod(env, fInputMethodLOCKABLE, jm_addAttribute, isThickUnderline, isGray, effectiveRange.location, effectiveRange.length); // AWT_THREADING Safe (AWTRunLoopMode)
             }
         }
     }
-    
+
     static JNF_MEMBER_CACHE(jm_selectPreviousGlyph, jc_CInputMethod, "selectPreviousGlyph", "()V");
     // We need to select the previous glyph so that it is overwritten.
     if (fPAHNeedsToSelect) {
         JNFCallVoidMethod(env, fInputMethodLOCKABLE, jm_selectPreviousGlyph);
         fPAHNeedsToSelect = NO;
     }
-    
+
     JNFCallVoidMethod(env, fInputMethodLOCKABLE, jm_dispatchText, selectionRange.location, selectionRange.length, JNI_FALSE); // AWT_THREADING Safe (AWTRunLoopMode)
-    
+
     // If the marked text is being cleared (zero-length string) don't handle the key event.
     if ([incomingString length] == 0) {
         fKeyEventsNeeded = NO;
@@ -1057,16 +1057,16 @@
 #ifdef IM_DEBUG
     fprintf(stderr, "AWTView InputMethod Selector Called : [unmarkText]\n");
 #endif // IM_DEBUG
-    
+
     if (!fInputMethodLOCKABLE) {
         return;
     }
-    
+
     // unmarkText cancels any input in progress and commits it to the text field.
     static JNF_MEMBER_CACHE(jm_unmarkText, jc_CInputMethod, "unmarkText", "()V");
     JNIEnv *env = [ThreadUtilities getJNIEnv];
     JNFCallVoidMethod(env, fInputMethodLOCKABLE, jm_unmarkText); // AWT_THREADING Safe (AWTRunLoopMode)
-    
+
 }
 
 - (BOOL) hasMarkedText
@@ -1074,24 +1074,24 @@
 #ifdef IM_DEBUG
     fprintf(stderr, "AWTView InputMethod Selector Called : [hasMarkedText]\n");
 #endif // IM_DEBUG
-    
+
     if (!fInputMethodLOCKABLE) {
         return NO;
     }
-    
+
     static JNF_MEMBER_CACHE(jf_fCurrentText, jc_CInputMethod, "fCurrentText", "Ljava/text/AttributedString;");
     static JNF_MEMBER_CACHE(jf_fCurrentTextLength, jc_CInputMethod, "fCurrentTextLength", "I");
     JNIEnv *env = [ThreadUtilities getJNIEnv];
     jobject currentText = JNFGetObjectField(env, fInputMethodLOCKABLE, jf_fCurrentText);
-    
+
     jint currentTextLength = JNFGetIntField(env, fInputMethodLOCKABLE, jf_fCurrentTextLength);
-    
+
     BOOL hasMarkedText = (currentText != NULL && currentTextLength > 0);
-    
+
     if (currentText != NULL) {
         (*env)->DeleteLocalRef(env, currentText);
     }
-    
+
     return hasMarkedText;
 }
 
@@ -1100,7 +1100,7 @@
 #ifdef IM_DEBUG
     fprintf(stderr, "AWTView InputMethod Selector Called : [conversationIdentifier]\n");
 #endif // IM_DEBUG
-    
+
     return (NSInteger) self;
 }
 
@@ -1112,16 +1112,16 @@
 #ifdef IM_DEBUG
     fprintf(stderr, "AWTView InputMethod Selector Called : [attributedSubstringFromRange] location=%lu, length=%lu\n", (unsigned long)theRange.location, (unsigned long)theRange.length);
 #endif // IM_DEBUG
-    
+
     static JNF_MEMBER_CACHE(jm_substringFromRange, jc_CInputMethod, "attributedSubstringFromRange", "(II)Ljava/lang/String;");
     JNIEnv *env = [ThreadUtilities getJNIEnv];
     jobject theString = JNFCallObjectMethod(env, fInputMethodLOCKABLE, jm_substringFromRange, theRange.location, theRange.length); // AWT_THREADING Safe (AWTRunLoopMode)
-    
+
     id result = [[[NSAttributedString alloc] initWithString:JNFJavaToNSString(env, theString)] autorelease];
 #ifdef IM_DEBUG
     NSLog(@"attributedSubstringFromRange returning \"%@\"", result);
 #endif // IM_DEBUG
-    
+
     (*env)->DeleteLocalRef(env, theString);
     return result;
 }
@@ -1131,24 +1131,24 @@
  */
 - (NSRange) markedRange
 {
-    
+
 #ifdef IM_DEBUG
     fprintf(stderr, "AWTView InputMethod Selector Called : [markedRange]\n");
 #endif // IM_DEBUG
-    
+
     if (!fInputMethodLOCKABLE) {
         return NSMakeRange(NSNotFound, 0);
     }
-    
+
     static JNF_MEMBER_CACHE(jm_markedRange, jc_CInputMethod, "markedRange", "()[I");
     JNIEnv *env = [ThreadUtilities getJNIEnv];
     jarray array;
     jboolean isCopy;
     jint *_array;
     NSRange range = NSMakeRange(NSNotFound, 0);
-    
+
     array = JNFCallObjectMethod(env, fInputMethodLOCKABLE, jm_markedRange); // AWT_THREADING Safe (AWTRunLoopMode)
-    
+
     if (array) {
         _array = (*env)->GetIntArrayElements(env, array, &isCopy);
         if (_array != NULL) {
@@ -1162,7 +1162,7 @@
         }
         (*env)->DeleteLocalRef(env, array);
     }
-    
+
     return range;
 }
 
@@ -1174,18 +1174,18 @@
     if (!fInputMethodLOCKABLE) {
         return NSMakeRange(NSNotFound, 0);
     }
-    
+
     static JNF_MEMBER_CACHE(jm_selectedRange, jc_CInputMethod, "selectedRange", "()[I");
     JNIEnv *env = [ThreadUtilities getJNIEnv];
     jarray array;
     jboolean isCopy;
     jint *_array;
     NSRange range = NSMakeRange(NSNotFound, 0);
-    
+
 #ifdef IM_DEBUG
     fprintf(stderr, "AWTView InputMethod Selector Called : [selectedRange]\n");
 #endif // IM_DEBUG
-    
+
     array = JNFCallObjectMethod(env, fInputMethodLOCKABLE, jm_selectedRange); // AWT_THREADING Safe (AWTRunLoopMode)
     if (array) {
         _array = (*env)->GetIntArrayElements(env, array, &isCopy);
@@ -1196,7 +1196,7 @@
         }
         (*env)->DeleteLocalRef(env, array);
     }
-    
+
     return range;
 }
 
@@ -1207,7 +1207,7 @@
     if (!fInputMethodLOCKABLE) {
         return NSZeroRect;
     }
-    
+
     static JNF_MEMBER_CACHE(jm_firstRectForCharacterRange, jc_CInputMethod,
                             "firstRectForCharacterRange", "(I)[I");
     JNIEnv *env = [ThreadUtilities getJNIEnv];
@@ -1215,16 +1215,16 @@
     jboolean isCopy;
     jint *_array;
     NSRect rect;
-    
+
 #ifdef IM_DEBUG
     fprintf(stderr,
             "AWTView InputMethod Selector Called : [firstRectForCharacterRange:] location=%lu, length=%lu\n",
             (unsigned long)theRange.location, (unsigned long)theRange.length);
 #endif // IM_DEBUG
-    
+
     array = JNFCallObjectMethod(env, fInputMethodLOCKABLE, jm_firstRectForCharacterRange,
                                 theRange.location); // AWT_THREADING Safe (AWTRunLoopMode)
-    
+
     _array = (*env)->GetIntArrayElements(env, array, &isCopy);
     if (_array) {
         rect = ConvertNSScreenRect(env, NSMakeRect(_array[0], _array[1], _array[2], _array[3]));
@@ -1233,7 +1233,7 @@
         rect = NSZeroRect;
     }
     (*env)->DeleteLocalRef(env, array);
-    
+
 #ifdef IM_DEBUG
     fprintf(stderr,
             "firstRectForCharacterRange returning x=%f, y=%f, width=%f, height=%f\n",
@@ -1250,23 +1250,23 @@
     if (!fInputMethodLOCKABLE) {
         return NSNotFound;
     }
-    
+
     static JNF_MEMBER_CACHE(jm_characterIndexForPoint, jc_CInputMethod,
                             "characterIndexForPoint", "(II)I");
     JNIEnv *env = [ThreadUtilities getJNIEnv];
-    
+
     NSPoint flippedLocation = ConvertNSScreenPoint(env, thePoint);
-    
+
 #ifdef IM_DEBUG
     fprintf(stderr, "AWTView InputMethod Selector Called : [characterIndexForPoint:(NSPoint)thePoint] x=%f, y=%f\n", flippedLocation.x, flippedLocation.y);
 #endif // IM_DEBUG
-    
+
     jint index = JNFCallIntMethod(env, fInputMethodLOCKABLE, jm_characterIndexForPoint, (jint)flippedLocation.x, (jint)flippedLocation.y); // AWT_THREADING Safe (AWTRunLoopMode)
-    
+
 #ifdef IM_DEBUG
     fprintf(stderr, "characterIndexForPoint returning %ld\n", index);
 #endif // IM_DEBUG
-    
+
     if (index == -1) {
         return NSNotFound;
     } else {
@@ -1279,7 +1279,7 @@
 #ifdef IM_DEBUG
     fprintf(stderr, "AWTView InputMethod Selector Called : [validAttributesForMarkedText]\n");
 #endif // IM_DEBUG
-    
+
     return [NSArray array];
 }
 
@@ -1288,14 +1288,14 @@
 #ifdef IM_DEBUG
     fprintf(stderr, "AWTView InputMethod Selector Called : [setInputMethod]\n");
 #endif // IM_DEBUG
-    
+
     JNIEnv *env = [ThreadUtilities getJNIEnv];
-    
+
     // Get rid of the old one
     if (fInputMethodLOCKABLE) {
         JNFDeleteGlobalRef(env, fInputMethodLOCKABLE);
     }
-    
+
     // Save a global ref to the new input method.
     if (inputMethod != NULL)
         fInputMethodLOCKABLE = JNFNewGlobalRef(env, inputMethod);
@@ -1308,7 +1308,7 @@
 #ifdef IM_DEBUG
     fprintf(stderr, "AWTView InputMethod Selector Called : [abandonInput]\n");
 #endif // IM_DEBUG
-    
+
     [ThreadUtilities performOnMainThread:@selector(markedTextAbandoned:) on:[NSInputManager currentInputManager] withObject:self waitUntilDone:YES];
     [self unmarkText];
 }
@@ -1330,22 +1330,22 @@
 (JNIEnv *env, jobject obj, jint originX, jint originY, jint width, jint height, jlong windowLayerPtr)
 {
     __block AWTView *newView = nil;
-    
+
     JNF_COCOA_ENTER(env);
-    
+
     NSRect rect = NSMakeRect(originX, originY, width, height);
     jobject cPlatformView = (*env)->NewWeakGlobalRef(env, obj);
-    
+
     [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
-        
+
         CALayer *windowLayer = jlong_to_ptr(windowLayerPtr);
         newView = [[AWTView alloc] initWithRect:rect
                                    platformView:cPlatformView
                                     windowLayer:windowLayer];
     }];
-    
+
     JNF_COCOA_EXIT(env);
-    
+
     return ptr_to_jlong(newView);
 }
 
@@ -1360,21 +1360,21 @@
 (JNIEnv *env, jclass cls, jlong viewPtr, jboolean toResize)
 {
     JNF_COCOA_ENTER(env);
-    
+
     NSView *view = (NSView *)jlong_to_ptr(viewPtr);
-    
+
     [ThreadUtilities performOnMainThreadWaiting:NO block:^(){
-        
+
         if (toResize) {
             [view setAutoresizingMask: NSViewHeightSizable | NSViewWidthSizable];
         } else {
             [view setAutoresizingMask: NSViewMinYMargin | NSViewMaxXMargin];
         }
-        
+
         if ([view superview] != nil) {
             [[view superview] setAutoresizesSubviews:(BOOL)toResize];
         }
-        
+
     }];
     JNF_COCOA_EXIT(env);
 }
@@ -1390,19 +1390,19 @@
 (JNIEnv *env, jclass cls, jlong viewPtr)
 {
     __block jint ret; //CGDirectDisplayID
-    
+
     JNF_COCOA_ENTER(env);
-    
+
     NSView *view = (NSView *)jlong_to_ptr(viewPtr);
     NSWindow *window = [view window];
-    
+
     [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
-        
+
         ret = (jint)[[AWTWindow getNSWindowDisplayID_AppKitThread: window] intValue];
     }];
-    
+
     JNF_COCOA_EXIT(env);
-    
+
     return ret;
 }
 
@@ -1417,25 +1417,25 @@
 (JNIEnv *env, jclass cls, jlong viewPtr)
 {
     jobject jRect = NULL;
-    
+
     JNF_COCOA_ENTER(env);
-    
+
     __block NSRect rect = NSZeroRect;
-    
+
     NSView *view = (NSView *)jlong_to_ptr(viewPtr);
     [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
-        
+
         NSRect viewBounds = [view bounds];
         NSRect frameInWindow = [view convertRect:viewBounds toView:nil];
         rect = [[view window] convertRectToScreen:frameInWindow];
-        NSRect screenRect = [[NSScreen mainScreen] frame];
         //Convert coordinates to top-left corner origin
-        rect.origin.y = screenRect.size.height - rect.origin.y - viewBounds.size.height;
+        rect = ConvertNSScreenRect(NULL, rect);
+
     }];
     jRect = NSToJavaRect(env, rect);
-    
+
     JNF_COCOA_EXIT(env);
-    
+
     return jRect;
 }
 
@@ -1449,17 +1449,17 @@
 (JNIEnv *env, jclass clazz, jlong viewPtr)
 {
     __block jboolean underMouse = JNI_FALSE;
-    
+
     JNF_COCOA_ENTER(env);
-    
+
     NSView *nsView = OBJC(viewPtr);
-    [ThreadUtilities performOnMainThreadWaiting:YES block:^(){       
+    [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
         NSPoint ptWindowCoords = [[nsView window] mouseLocationOutsideOfEventStream];
         NSPoint ptViewCoords = [nsView convertPoint:ptWindowCoords fromView:nil];
         underMouse = [nsView hitTest:ptViewCoords] != nil;
     }];
-    
+
     JNF_COCOA_EXIT(env);
-    
+
     return underMouse;
 }
--- a/src/java.desktop/macosx/native/libawt_lwawt/awt/CTrayIcon.m	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/CTrayIcon.m	Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -134,8 +134,7 @@
     NSPoint absP = [NSEvent mouseLocation];
     NSEventType type = [event type];
 
-    NSRect screenRect = [[NSScreen mainScreen] frame];
-    absP.y = screenRect.size.height - absP.y;
+    absP = ConvertNSScreenPoint(NULL, absP);
     jint clickCount;
 
     clickCount = [event clickCount];
@@ -179,15 +178,15 @@
     isHighlighted = NO;
     image = nil;
     trackingArea = nil;
-	
+
     [self addTrackingArea];
-	
+
     return self;
 }
 
 - (void)addTrackingArea {
-    NSTrackingAreaOptions options = NSTrackingMouseMoved | 
-                                    NSTrackingInVisibleRect | 
+    NSTrackingAreaOptions options = NSTrackingMouseMoved |
+                                    NSTrackingInVisibleRect |
                                     NSTrackingActiveAlways;
     trackingArea = [[NSTrackingArea alloc] initWithRect: CGRectZero
                                                 options: options
@@ -410,3 +409,28 @@
 
     return jpt;
 }
+
+JNIEXPORT void JNICALL
+Java_sun_lwawt_macosx_CTrayIcon_nativeShowNotification
+(JNIEnv *env, jobject self, jlong model, jobject jcaption, jobject jtext,
+              long nsimage) {
+JNF_COCOA_ENTER(env);
+
+    AWTTrayIcon *icon = jlong_to_ptr(model);
+    NSString *caption = JNFJavaToNSString(env, jcaption);
+    NSString *text = JNFJavaToNSString(env, jtext);
+    NSImage * contentImage = jlong_to_ptr(nsimage);
+
+    [ThreadUtilities performOnMainThreadWaiting:NO block:^(){
+        NSUserNotification *notification = [[NSUserNotification alloc] init];
+        notification.title = caption;
+        notification.informativeText = text;
+        notification.contentImage = contentImage;
+        notification.soundName = NSUserNotificationDefaultSoundName;
+
+        [[NSUserNotificationCenter defaultUserNotificationCenter]
+            deliverNotification:notification];
+    }];
+
+JNF_COCOA_EXIT(env);
+}
--- a/src/java.desktop/macosx/native/libosxapp/NSApplicationAWT.h	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/macosx/native/libosxapp/NSApplicationAWT.h	Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -32,7 +32,7 @@
 #import <Cocoa/Cocoa.h>
 #import <JavaNativeFoundation/JavaNativeFoundation.h>
 
-@interface NSApplicationAWT : NSApplication {
+@interface NSApplicationAWT : NSApplication <NSUserNotificationCenterDelegate> {
     NSString *fApplicationName;
     NSWindow *eventTransparentWindow;
     NSTimeInterval dummyEventTimestamp;
--- a/src/java.desktop/macosx/native/libosxapp/NSApplicationAWT.m	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/macosx/native/libosxapp/NSApplicationAWT.m	Wed Nov 08 16:03:35 2017 -0500
@@ -77,6 +77,8 @@
 
 - (void)dealloc
 {
+    [[NSUserNotificationCenter defaultUserNotificationCenter] setDelegate:nil];
+
     [fApplicationName release];
     fApplicationName = nil;
 
@@ -138,10 +140,18 @@
 
     [super finishLaunching];
 
+    [[NSUserNotificationCenter defaultUserNotificationCenter] setDelegate:self];
+
     // inform any interested parties that the AWT has arrived and is pumping
     [[NSNotificationCenter defaultCenter] postNotificationName:JNFRunLoopDidStartNotification object:self];
 }
 
+- (BOOL)userNotificationCenter:(NSUserNotificationCenter *)center
+     shouldPresentNotification:(NSUserNotification *)notification
+{
+    return YES; // We always show notifications to the user
+}
+
 - (void) registerWithProcessManager
 {
     // Headless: NO
--- a/src/java.desktop/share/classes/com/sun/awt/AWTUtilities.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/com/sun/awt/AWTUtilities.java	Wed Nov 08 16:03:35 2017 -0500
@@ -25,7 +25,16 @@
 
 package com.sun.awt;
 
-import java.awt.*;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Dialog;
+import java.awt.Frame;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsDevice;
+import java.awt.GraphicsEnvironment;
+import java.awt.Shape;
+import java.awt.Toolkit;
+import java.awt.Window;
 
 import javax.swing.JRootPane;
 
@@ -64,6 +73,7 @@
  * drastically between update release, and it may even be
  * removed or be moved in some other package(s)/class(es).
  */
+@Deprecated(forRemoval = true, since = "10")
 public final class AWTUtilities {
 
     /**
@@ -114,7 +124,10 @@
      *                         (either PERPIXEL_TRANSPARENT,
      *                         TRANSLUCENT, or PERPIXEL_TRANSLUCENT)
      * @return whether the given translucency kind is supported
+     * @deprecated use {@link GraphicsDevice#isWindowTranslucencySupported}
+     *             instead
      */
+    @Deprecated(forRemoval = true, since = "10")
     public static boolean isTranslucencySupported(Translucency translucencyKind) {
         switch (translucencyKind) {
             case PERPIXEL_TRANSPARENT:
@@ -166,14 +179,15 @@
      *                                  and the opacity is less than 1.0f
      * @throws UnsupportedOperationException if the TRANSLUCENT translucency
      *                                       kind is not supported
+     * @deprecated use {@link Window#setOpacity} instead
      */
+    @Deprecated(forRemoval = true, since = "10")
     public static void setWindowOpacity(Window window, float opacity) {
         if (window == null) {
             throw new NullPointerException(
                     "The window argument should not be null.");
         }
-
-        AWTAccessor.getWindowAccessor().setOpacity(window, opacity);
+        window.setOpacity(opacity);
     }
 
     /**
@@ -182,14 +196,16 @@
      *
      * @param window the window to get the opacity level from
      * @throws NullPointerException if the window argument is null
+     * @deprecated use {@link Window#getOpacity} instead
      */
+    @Deprecated(forRemoval = true, since = "10")
     public static float getWindowOpacity(Window window) {
         if (window == null) {
             throw new NullPointerException(
                     "The window argument should not be null.");
         }
 
-        return AWTAccessor.getWindowAccessor().getOpacity(window);
+        return window.getOpacity();
     }
 
     /**
@@ -198,7 +214,10 @@
      * Note that this method may sometimes return true, but the native
      * windowing system may still not support the concept of
      * shaping (due to the bugs in the windowing system).
+     * @deprecated use {@link GraphicsDevice#isWindowTranslucencySupported}
+     *             instead
      */
+    @Deprecated(forRemoval = true, since = "10")
     public static boolean isWindowShapingSupported() {
         Toolkit curToolkit = Toolkit.getDefaultToolkit();
         if (!(curToolkit instanceof SunToolkit)) {
@@ -216,13 +235,15 @@
      * @param window the window to get the shape from
      * @return the current shape of the window
      * @throws NullPointerException if the window argument is null
+     * @deprecated use {@link Window#getShape} instead
      */
+    @Deprecated(forRemoval = true, since = "10")
     public static Shape getWindowShape(Window window) {
         if (window == null) {
             throw new NullPointerException(
                     "The window argument should not be null.");
         }
-        return AWTAccessor.getWindowAccessor().getShape(window);
+        return window.getShape();
     }
 
     /**
@@ -247,13 +268,15 @@
      *                                  and the shape is not null
      * @throws UnsupportedOperationException if the PERPIXEL_TRANSPARENT
      *                                       translucency kind is not supported
+     * @deprecated use {@link Window#setShape} instead
      */
+    @Deprecated(forRemoval = true, since = "10")
     public static void setWindowShape(Window window, Shape shape) {
         if (window == null) {
             throw new NullPointerException(
                     "The window argument should not be null.");
         }
-        AWTAccessor.getWindowAccessor().setShape(window, shape);
+        window.setShape(shape);
     }
 
     private static boolean isWindowTranslucencySupported() {
@@ -349,7 +372,9 @@
      * isOpaque argument is {@code false}.
      * @throws UnsupportedOperationException if the PERPIXEL_TRANSLUCENT
      *                                       translucency kind is not supported
+     * @deprecated use {@link Window#setBackground} instead
      */
+    @Deprecated(forRemoval = true, since = "10")
     public static void setWindowOpaque(Window window, boolean isOpaque) {
         if (window == null) {
             throw new NullPointerException(
@@ -359,7 +384,12 @@
             throw new UnsupportedOperationException(
                     "The PERPIXEL_TRANSLUCENT translucency kind is not supported");
         }
-        AWTAccessor.getWindowAccessor().setOpaque(window, isOpaque);
+        Color bg = window.getBackground();
+        if (bg == null) {
+            bg = new Color(0, 0, 0, 0);
+        }
+        window.setBackground(new Color(bg.getRed(), bg.getGreen(), bg.getBlue(),
+                                       isOpaque ? 255 : 0));
     }
 
     /**
@@ -369,7 +399,9 @@
      * @return whether the window is currently opaque (true)
      *         or translucent (false)
      * @throws NullPointerException if the window argument is null
+     * @deprecated use {@link Window#isOpaque} instead
      */
+    @Deprecated(forRemoval = true, since = "10")
     public static boolean isWindowOpaque(Window window) {
         if (window == null) {
             throw new NullPointerException(
@@ -395,7 +427,10 @@
      * @throws NullPointerException if the gc argument is null
      * @return whether the given GraphicsConfiguration supports
      *         the translucency effects.
+     * @deprecated use {@link GraphicsConfiguration#isTranslucencyCapable}
+     *             instead
      */
+    @Deprecated(forRemoval = true, since = "10")
     public static boolean isTranslucencyCapable(GraphicsConfiguration gc) {
         if (gc == null) {
             throw new NullPointerException("The gc argument should not be null");
@@ -448,8 +483,9 @@
      * 'mixing-cutout' shape
      * @param shape the new 'mixing-cutout' shape
      * @throws NullPointerException if the component argument is {@code null}
+     * @deprecated use {@link Component#setMixingCutoutShape} instead
      */
-    @Deprecated(since = "9")
+    @Deprecated(forRemoval = true, since = "9")
     public static void setComponentMixingCutoutShape(Component component,
             Shape shape)
     {
--- a/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFCompressor.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFCompressor.java	Wed Nov 08 16:03:35 2017 -0500
@@ -68,12 +68,7 @@
     protected ImageOutputStream stream;
 
     /**
-     * Creates a compressor object for use in compressing TIFF data. This
-     * object may be passed to the
-     * {@link TIFFImageWriteParam#setTIFFCompressor(TIFFCompressor)}
-     * method to override the compressor of a supported compression type or
-     * to provide the implementation of the compression algorithm of an
-     * unsupported compression type.
+     * Creates a compressor object for use in compressing TIFF data.
      *
      * <p>The parameters {@code compressionTagValue} and
      * {@code isCompressionLossless} are provided to accomodate
--- a/src/java.desktop/share/classes/java/applet/AppletContext.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/java/applet/AppletContext.java	Wed Nov 08 16:03:35 2017 -0500
@@ -117,24 +117,30 @@
      * <table class="striped">
      * <caption>Target arguments and their descriptions</caption>
      * <thead>
-     * <tr><th>Target Argument</th>
-     * <th>Description</th></tr>
+     *   <tr>
+     *     <th scope="col">Target Argument
+     *     <th scope="col">Description
      * </thead>
      * <tbody>
-     * <tr><td>{@code "_self"}  <td>Show in the window and frame that
-     *                                   contain the applet.</tr>
-     * <tr><td>{@code "_parent"}<td>Show in the applet's parent frame. If
-     *                                   the applet's frame has no parent frame,
-     *                                   acts the same as "_self".</tr>
-     * <tr><td>{@code "_top"}   <td>Show in the top-level frame of the applet's
-     *                                   window. If the applet's frame is the
-     *                                   top-level frame, acts the same as "_self".</tr>
-     * <tr><td>{@code "_blank"} <td>Show in a new, unnamed
-     *                                   top-level window.</tr>
-     * <tr><td><i>name</i><td>Show in the frame or window named <i>name</i>. If
-     *                        a target named <i>name</i> does not already exist, a
-     *                        new top-level window with the specified name is created,
-     *                        and the document is shown there.</tr>
+     *   <tr>
+     *     <th scope="row">{@code "_self"}
+     *     <td>Show in the window and frame that contain the applet.
+     *   <tr>
+     *     <th scope="row">{@code "_parent"}
+     *     <td>Show in the applet's parent frame. If the applet's frame has no
+     *     parent frame, acts the same as "_self".
+     *   <tr>
+     *     <th scope="row">{@code "_top"}
+     *     <td>Show in the top-level frame of the applet's window. If the
+     *     applet's frame is the top-level frame, acts the same as "_self".
+     *   <tr>
+     *     <th scope="row">{@code "_blank"}
+     *     <td>Show in a new, unnamed top-level window.
+     *   <tr>
+     *     <th scope="row"><i>name</i>
+     *     <td>Show in the frame or window named <i>name</i>. If a target named
+     *     <i>name</i> does not already exist, a new top-level window with the
+     *     specified name is created, and the document is shown there.
      * </tbody>
      * </table>
      * <p>
--- a/src/java.desktop/share/classes/java/awt/AWTKeyStroke.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/java/awt/AWTKeyStroke.java	Wed Nov 08 16:03:35 2017 -0500
@@ -94,25 +94,23 @@
      * <table class="striped">
      * <caption>AWTKeyStroke default values</caption>
      * <thead>
-     * <tr><th>Property</th><th>Default Value</th></tr>
+     *   <tr>
+     *     <th scope="col">Property
+     *     <th scope="col">Default Value
      * </thead>
      * <tbody>
-     * <tr>
-     *    <td>Key Char</td>
-     *    <td>{@code KeyEvent.CHAR_UNDEFINED}</td>
-     * </tr>
-     * <tr>
-     *    <td>Key Code</td>
-     *    <td>{@code KeyEvent.VK_UNDEFINED}</td>
-     * </tr>
-     * <tr>
-     *    <td>Modifiers</td>
-     *    <td>none</td>
-     * </tr>
-     * <tr>
-     *    <td>On key release?</td>
-     *    <td>{@code false}</td>
-     * </tr>
+     *   <tr>
+     *     <th scope="row">Key Char
+     *     <td>{@code KeyEvent.CHAR_UNDEFINED}
+     *   <tr>
+     *     <th scope="row">Key Code
+     *     <td>{@code KeyEvent.VK_UNDEFINED}
+     *   <tr>
+     *     <th scope="row">Modifiers
+     *     <td>none
+     *   <tr>
+     *     <th scope="row">On key release?
+     *     <td>{@code false}
      * </tbody>
      * </table>
      *
--- a/src/java.desktop/share/classes/java/awt/AWTPermission.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/java/awt/AWTPermission.java	Wed Nov 08 16:03:35 2017 -0500
@@ -48,144 +48,116 @@
  * <caption>AWTPermission target names, descriptions, and associated risks
  * </caption>
  * <thead>
- * <tr>
- * <th>Permission Target Name</th>
- * <th>What the Permission Allows</th>
- * <th>Risks of Allowing this Permission</th>
- * </tr>
+ *   <tr>
+ *     <th scope="col">Permission Target Name
+ *     <th scope="col">What the Permission Allows
+ *     <th scope="col">Risks of Allowing this Permission
  * </thead>
  * <tbody>
- * <tr>
- *   <td>accessClipboard</td>
- *   <td>Posting and retrieval of information to and from the AWT clipboard</td>
- *   <td>This would allow malfeasant code to share
- * potentially sensitive or confidential information.</td>
- * </tr>
- *
- * <tr>
- *   <td>accessEventQueue</td>
- *   <td>Access to the AWT event queue</td>
- *   <td>After retrieving the AWT event queue,
- * malicious code may peek at and even remove existing events
- * from its event queue, as well as post bogus events which may purposefully
- * cause the application or applet to misbehave in an insecure manner.</td>
- * </tr>
- *
- * <tr>
- *   <td>accessSystemTray</td>
- *   <td>Access to the AWT SystemTray instance</td>
- *   <td>This would allow malicious code to add tray icons to the system tray.
- * First, such an icon may look like the icon of some known application
- * (such as a firewall or anti-virus) and order a user to do something unsafe
- * (with help of balloon messages). Second, the system tray may be glutted with
- * tray icons so that no one could add a tray icon anymore.</td>
- * </tr>
- *
- * <tr>
- *   <td>createRobot</td>
- *   <td>Create java.awt.Robot objects</td>
- *   <td>The java.awt.Robot object allows code to generate native-level
- * mouse and keyboard events as well as read the screen. It could allow
- * malicious code to control the system, run other programs, read the
- * display, and deny mouse and keyboard access to the user.</td>
- * </tr>
- *
- * <tr>
- *   <td>fullScreenExclusive</td>
- *   <td>Enter full-screen exclusive mode</td>
- *   <td>Entering full-screen exclusive mode allows direct access to
- * low-level graphics card memory.  This could be used to spoof the
- * system, since the program is in direct control of rendering. Depending on
- * the implementation, the security warning may not be shown for the windows
- * used to enter the full-screen exclusive mode (assuming that the {@code
- * fullScreenExclusive} permission has been granted to this application). Note
- * that this behavior does not mean that the {@code
- * showWindowWithoutWarningBanner} permission will be automatically granted to
- * the application which has the {@code fullScreenExclusive} permission:
- * non-full-screen windows will continue to be shown with the security
- * warning.</td>
- * </tr>
- *
- * <tr>
- *   <td>listenToAllAWTEvents</td>
- *   <td>Listen to all AWT events, system-wide</td>
- *   <td>After adding an AWT event listener,
- * malicious code may scan all AWT events dispatched in the system,
- * allowing it to read all user input (such as passwords).  Each
- * AWT event listener is called from within the context of that
- * event queue's EventDispatchThread, so if the accessEventQueue
- * permission is also enabled, malicious code could modify the
- * contents of AWT event queues system-wide, causing the application
- * or applet to misbehave in an insecure manner.</td>
- * </tr>
- *
- * <tr>
- *   <td>readDisplayPixels</td>
- *   <td>Readback of pixels from the display screen</td>
- *   <td>Interfaces such as the java.awt.Composite interface or the
- * java.awt.Robot class allow arbitrary code to examine pixels on the
- * display enable malicious code to snoop on the activities of the user.</td>
- * </tr>
- *
- * <tr>
- *   <td>replaceKeyboardFocusManager</td>
- *   <td>Sets the {@code KeyboardFocusManager} for
- *       a particular thread.
- *   <td>When {@code SecurityManager} is installed, the invoking
- *       thread must be granted this permission in order to replace
- *       the current {@code KeyboardFocusManager}.  If permission
- *       is not granted, a {@code SecurityException} will be thrown.
- * </tr>
- *
- * <tr>
- *   <td>setAppletStub</td>
- *   <td>Setting the stub which implements Applet container services</td>
- *   <td>Malicious code could set an applet's stub and result in unexpected
- * behavior or denial of service to an applet.</td>
- * </tr>
- *
- * <tr>
- *   <td>setWindowAlwaysOnTop</td>
- *   <td>Setting always-on-top property of the window: {@link Window#setAlwaysOnTop}</td>
- *   <td>The malicious window might make itself look and behave like a real full desktop, so that
- * information entered by the unsuspecting user is captured and subsequently misused </td>
- * </tr>
- *
- * <tr>
- *   <td>showWindowWithoutWarningBanner</td>
- *   <td>Display of a window without also displaying a banner warning
- * that the window was created by an applet</td>
- *   <td>Without this warning,
- * an applet may pop up windows without the user knowing that they
- * belong to an applet.  Since users may make security-sensitive
- * decisions based on whether or not the window belongs to an applet
- * (entering a username and password into a dialog box, for example),
- * disabling this warning banner may allow applets to trick the user
- * into entering such information.</td>
- * </tr>
- *
- * <tr>
- *   <td>toolkitModality</td>
- *   <td>Creating {@link Dialog.ModalityType#TOOLKIT_MODAL TOOLKIT_MODAL} dialogs
- *       and setting the {@link Dialog.ModalExclusionType#TOOLKIT_EXCLUDE
- *       TOOLKIT_EXCLUDE} window property.</td>
- *   <td>When a toolkit-modal dialog is shown from an applet, it blocks all other
- * applets in the browser. When launching applications from Java Web Start,
- * its windows (such as the security dialog) may also be blocked by toolkit-modal
- * dialogs, shown from these applications.</td>
- * </tr>
- *
- * <tr>
- *   <td>watchMousePointer</td>
- *   <td>Getting the information about the mouse pointer position at any
- * time</td>
- *   <td>Constantly watching the mouse pointer,
- * an applet can make guesses about what the user is doing, i.e. moving
- * the mouse to the lower left corner of the screen most likely means that
- * the user is about to launch an application. If a virtual keypad is used
- * so that keyboard is emulated using the mouse, an applet may guess what
- * is being typed.</td>
- * </tr>
+ *   <tr>
+ *     <th scope="row">accessClipboard
+ *     <td>Posting and retrieval of information to and from the AWT clipboard
+ *     <td>This would allow malfeasant code to share potentially sensitive or
+ *     confidential information.
+ *   <tr>
+ *     <th scope="row">accessEventQueue
+ *     <td>Access to the AWT event queue
+ *     <td>After retrieving the AWT event queue, malicious code may peek at and
+ *     even remove existing events from its event queue, as well as post bogus
+ *     events which may purposefully cause the application or applet to
+ *     misbehave in an insecure manner.
+ *   <tr>
+ *     <th scope="row">accessSystemTray
+ *     <td>Access to the AWT SystemTray instance
+ *     <td>This would allow malicious code to add tray icons to the system tray.
+ *     First, such an icon may look like the icon of some known application
+ *     (such as a firewall or anti-virus) and order a user to do something
+ *     unsafe (with help of balloon messages). Second, the system tray may be
+ *     glutted with tray icons so that no one could add a tray icon anymore.
+ *   <tr>
+ *     <th scope="row">createRobot
+ *     <td>Create java.awt.Robot objects
+ *     <td>The java.awt.Robot object allows code to generate native-level mouse
+ *     and keyboard events as well as read the screen. It could allow malicious
+ *     code to control the system, run other programs, read the display, and
+ *     deny mouse and keyboard access to the user.
+ *   <tr>
+ *     <th scope="row">fullScreenExclusive
+ *     <td>Enter full-screen exclusive mode
+ *     <td>Entering full-screen exclusive mode allows direct access to low-level
+ *     graphics card memory. This could be used to spoof the system, since the
+ *     program is in direct control of rendering. Depending on the
+ *     implementation, the security warning may not be shown for the windows
+ *     used to enter the full-screen exclusive mode (assuming that the
+ *     {@code fullScreenExclusive} permission has been granted to this
+ *     application). Note that this behavior does not mean that the
+ *     {@code showWindowWithoutWarningBanner} permission will be automatically
+ *     granted to the application which has the {@code fullScreenExclusive}
+ *     permission: non-full-screen windows will continue to be shown with the
+ *     security warning.
+ *   <tr>
+ *     <th scope="row">listenToAllAWTEvents
+ *     <td>Listen to all AWT events, system-wide
+ *     <td>After adding an AWT event listener, malicious code may scan all AWT
+ *     events dispatched in the system, allowing it to read all user input (such
+ *     as passwords). Each AWT event listener is called from within the context
+ *     of that event queue's EventDispatchThread, so if the accessEventQueue
+ *     permission is also enabled, malicious code could modify the contents of
+ *     AWT event queues system-wide, causing the application or applet to
+ *     misbehave in an insecure manner.
+ *   <tr>
+ *     <th scope="row">readDisplayPixels
+ *     <td>Readback of pixels from the display screen
+ *     <td>Interfaces such as the java.awt.Composite interface or the
+ *     java.awt.Robot class allow arbitrary code to examine pixels on the
+ *     display enable malicious code to snoop on the activities of the user.
+ *   <tr>
+ *     <th scope="row">replaceKeyboardFocusManager
+ *     <td>Sets the {@code KeyboardFocusManager} for a particular thread.
+ *     <td>When {@code SecurityManager} is installed, the invoking thread must
+ *     be granted this permission in order to replace the current
+ *     {@code KeyboardFocusManager}. If permission is not granted, a
+ *     {@code SecurityException} will be thrown.
+ *   <tr>
+ *     <th scope="row">setAppletStub
+ *     <td>Setting the stub which implements Applet container services
+ *     <td>Malicious code could set an applet's stub and result in unexpected
+ *     behavior or denial of service to an applet.
+ *   <tr>
+ *     <th scope="row">setWindowAlwaysOnTop
+ *     <td>Setting always-on-top property of the window:
+ *     {@link Window#setAlwaysOnTop}
+ *     <td>The malicious window might make itself look and behave like a real
+ *     full desktop, so that information entered by the unsuspecting user is
+ *     captured and subsequently misused
+ *   <tr>
+ *     <th scope="row">showWindowWithoutWarningBanner
+ *     <td>Display of a window without also displaying a banner warning that the
+ *     window was created by an applet
+ *     <td>Without this warning, an applet may pop up windows without the user
+ *     knowing that they belong to an applet. Since users may make
+ *     security-sensitive decisions based on whether or not the window belongs
+ *     to an applet (entering a username and password into a dialog box, for
+ *     example), disabling this warning banner may allow applets to trick the
+ *     user into entering such information.
+ *   <tr>
+ *     <th scope="row">toolkitModality
+ *     <td>Creating {@link Dialog.ModalityType#TOOLKIT_MODAL TOOLKIT_MODAL}
+ *     dialogs and setting the
+ *     {@link Dialog.ModalExclusionType#TOOLKIT_EXCLUDE TOOLKIT_EXCLUDE} window
+ *     property.
+ *     <td>When a toolkit-modal dialog is shown from an applet, it blocks all
+ *     other applets in the browser. When launching applications from Java Web
+ *     Start, its windows (such as the security dialog) may also be blocked by
+ *     toolkit-modal dialogs, shown from these applications.
+ *   <tr>
+ *     <th scope="row">watchMousePointer
+ *     <td>Getting the information about the mouse pointer position at any time
+ *     <td>Constantly watching the mouse pointer, an applet can make guesses
+ *     about what the user is doing, i.e. moving the mouse to the lower left
+ *     corner of the screen most likely means that the user is about to launch
+ *     an application. If a virtual keypad is used so that keyboard is emulated
+ *     using the mouse, an applet may guess what is being typed.
  * </tbody>
  * </table>
  *
@@ -195,11 +167,9 @@
  * @see java.security.PermissionCollection
  * @see java.lang.SecurityManager
  *
- *
  * @author Marianne Mueller
  * @author Roland Schemers
  */
-
 public final class AWTPermission extends BasicPermission {
 
     /** use serialVersionUID from the Java 2 platform for interoperability */
--- a/src/java.desktop/share/classes/java/awt/AlphaComposite.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/java/awt/AlphaComposite.java	Wed Nov 08 16:03:35 2017 -0500
@@ -72,22 +72,40 @@
  * The following factors are used in the description of the blending
  * equation in the Porter and Duff paper:
  *
- * <blockquote>
- * <table class="borderless">
+ * <table class="striped">
  * <caption style="display:none">Factors</caption>
- * <tr><th style="text-align:left">Factor&nbsp;&nbsp;<th style="text-align:left">Definition
- * <tr><td><em>A<sub>s</sub></em><td>the alpha component of the source pixel
- * <tr><td><em>C<sub>s</sub></em><td>a color component of the source pixel in premultiplied form
- * <tr><td><em>A<sub>d</sub></em><td>the alpha component of the destination pixel
- * <tr><td><em>C<sub>d</sub></em><td>a color component of the destination pixel in premultiplied form
- * <tr><td><em>F<sub>s</sub></em><td>the fraction of the source pixel that contributes to the output
- * <tr><td><em>F<sub>d</sub></em><td>the fraction of the destination pixel that contributes
- * to the output
- * <tr><td><em>A<sub>r</sub></em><td>the alpha component of the result
- * <tr><td><em>C<sub>r</sub></em><td>a color component of the result in premultiplied form
+ * <thead>
+ *   <tr>
+ *     <th scope="col">Factor
+ *     <th scope="col">Definition
+ * </thead>
+ * <tbody>
+ *   <tr>
+ *     <th scope="row"><em>A<sub>s</sub></em>
+ *     <td>the alpha component of the source pixel
+ *   <tr>
+ *     <th scope="row"><em>C<sub>s</sub></em>
+ *     <td>a color component of the source pixel in premultiplied form
+ *   <tr>
+ *     <th scope="row"><em>A<sub>d</sub></em>
+ *     <td>the alpha component of the destination pixel
+ *   <tr>
+ *     <th scope="row"><em>C<sub>d</sub></em>
+ *     <td>a color component of the destination pixel in premultiplied form
+ *   <tr>
+ *     <th scope="row"><em>F<sub>s</sub></em>
+ *     <td>the fraction of the source pixel that contributes to the output
+ *   <tr>
+ *     <th scope="row"><em>F<sub>d</sub></em>
+ *     <td>the fraction of the destination pixel that contributes to the output
+ *   <tr>
+ *     <th scope="row"><em>A<sub>r</sub></em>
+ *     <td>the alpha component of the result
+ *   <tr>
+ *     <th scope="row"><em>C<sub>r</sub></em>
+ *     <td>a color component of the result in premultiplied form
+ * </tbody>
  * </table>
- * </blockquote>
- *
  * <p>
  * Using these factors, Porter and Duff define 12 ways of choosing
  * the blending factors <em>F<sub>s</sub></em> and <em>F<sub>d</sub></em> to
@@ -113,19 +131,37 @@
  * The following factors will be used to discuss our extensions to
  * the blending equation in the Porter and Duff paper:
  *
- * <blockquote>
- * <table class="borderless">
+ * <table class="striped">
  * <caption style="display:none">Factors</caption>
- * <tr><th style="text-align:left">Factor&nbsp;&nbsp;<th style="text-align:left">Definition
- * <tr><td><em>C<sub>sr</sub></em> <td>one of the raw color components of the source pixel
- * <tr><td><em>C<sub>dr</sub></em> <td>one of the raw color components of the destination pixel
- * <tr><td><em>A<sub>ac</sub></em>  <td>the "extra" alpha component from the AlphaComposite instance
- * <tr><td><em>A<sub>sr</sub></em> <td>the raw alpha component of the source pixel
- * <tr><td><em>A<sub>dr</sub></em><td>the raw alpha component of the destination pixel
- * <tr><td><em>A<sub>df</sub></em> <td>the final alpha component stored in the destination
- * <tr><td><em>C<sub>df</sub></em> <td>the final raw color component stored in the destination
+ * <thead>
+ *   <tr>
+ *     <th scope="col">Factor
+ *     <th scope="col">Definition
+ * </thead>
+ * <tbody>
+ *   <tr>
+ *     <th scope="row"><em>C<sub>sr</sub></em>
+ *     <td>one of the raw color components of the source pixel
+ *   <tr>
+ *     <th scope="row"><em>C<sub>dr</sub></em>
+ *     <td>one of the raw color components of the destination pixel
+ *   <tr>
+ *     <th scope="row"><em>A<sub>ac</sub></em>
+ *     <td>the "extra" alpha component from the AlphaComposite instance
+ *   <tr>
+ *     <th scope="row"><em>A<sub>sr</sub></em>
+ *     <td>the raw alpha component of the source pixel
+ *   <tr>
+ *     <th scope="row"><em>A<sub>dr</sub></em>
+ *     <td>the raw alpha component of the destination pixel
+ *   <tr>
+ *     <th scope="row"><em>A<sub>df</sub></em>
+ *     <td>the final alpha component stored in the destination
+ *   <tr>
+ *     <th scope="row"><em>C<sub>df</sub></em>
+ *     <td>the final raw color component stored in the destination
+ * </tbody>
  * </table>
- *</blockquote>
  *
  * <h3>Preparing Inputs</h3>
  *
--- a/src/java.desktop/share/classes/java/awt/Component.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/java/awt/Component.java	Wed Nov 08 16:03:35 2017 -0500
@@ -843,10 +843,6 @@
             public Rectangle getBounds(Component comp) {
                 return new Rectangle(comp.x, comp.y, comp.width, comp.height);
             }
-            public void setMixingCutoutShape(Component comp, Shape shape) {
-                comp.setMixingCutoutShape(shape);
-            }
-
             public void setGraphicsConfiguration(Component comp,
                     GraphicsConfiguration gc)
             {
@@ -7247,28 +7243,24 @@
      * <caption>Recommended default values for a Component's focus traversal
      * keys</caption>
      * <thead>
-     * <tr>
-     *    <th>Identifier</th>
-     *    <th>Meaning</th>
-     *    <th>Default</th>
-     * </tr>
+     *   <tr>
+     *     <th scope="col">Identifier
+     *     <th scope="col">Meaning
+     *     <th scope="col">Default
      * </thead>
      * <tbody>
-     * <tr>
-     *    <td>KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS</td>
-     *    <td>Normal forward keyboard traversal</td>
-     *    <td>TAB on KEY_PRESSED, CTRL-TAB on KEY_PRESSED</td>
-     * </tr>
-     * <tr>
-     *    <td>KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS</td>
-     *    <td>Normal reverse keyboard traversal</td>
-     *    <td>SHIFT-TAB on KEY_PRESSED, CTRL-SHIFT-TAB on KEY_PRESSED</td>
-     * </tr>
-     * <tr>
-     *    <td>KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS</td>
-     *    <td>Go up one focus traversal cycle</td>
-     *    <td>none</td>
-     * </tr>
+     *   <tr>
+     *     <th scope="row">KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS
+     *     <td>Normal forward keyboard traversal
+     *     <td>TAB on KEY_PRESSED, CTRL-TAB on KEY_PRESSED
+     *   <tr>
+     *     <th scope="row">KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS
+     *     <td>Normal reverse keyboard traversal
+     *     <td>SHIFT-TAB on KEY_PRESSED, CTRL-SHIFT-TAB on KEY_PRESSED
+     *   <tr>
+     *     <th scope="row">KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS
+     *     <td>Go up one focus traversal cycle
+     *     <td>none
      * </tbody>
      * </table>
      *
--- a/src/java.desktop/share/classes/java/awt/Container.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/java/awt/Container.java	Wed Nov 08 16:03:35 2017 -0500
@@ -3069,33 +3069,28 @@
      * <caption>Recommended default values for a Container's focus traversal
      * keys</caption>
      * <thead>
-     * <tr>
-     *    <th>Identifier</th>
-     *    <th>Meaning</th>
-     *    <th>Default</th>
-     * </tr>
+     *   <tr>
+     *     <th scope="col">Identifier
+     *     <th scope="col">Meaning
+     *     <th scope="col">Default
      * </thead>
      * <tbody>
-     * <tr>
-     *    <td>KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS</td>
-     *    <td>Normal forward keyboard traversal</td>
-     *    <td>TAB on KEY_PRESSED, CTRL-TAB on KEY_PRESSED</td>
-     * </tr>
-     * <tr>
-     *    <td>KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS</td>
-     *    <td>Normal reverse keyboard traversal</td>
-     *    <td>SHIFT-TAB on KEY_PRESSED, CTRL-SHIFT-TAB on KEY_PRESSED</td>
-     * </tr>
-     * <tr>
-     *    <td>KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS</td>
-     *    <td>Go up one focus traversal cycle</td>
-     *    <td>none</td>
-     * </tr>
-     * <tr>
-     *    <td>KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS</td>
-     *    <td>Go down one focus traversal cycle</td>
-     *    <td>none</td>
-     * </tr>
+     *   <tr>
+     *     <th scope="row">KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS
+     *     <td>Normal forward keyboard traversal
+     *     <td>TAB on KEY_PRESSED, CTRL-TAB on KEY_PRESSED
+     *   <tr>
+     *     <th scope="row">KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS
+     *     <td>Normal reverse keyboard traversal
+     *     <td>SHIFT-TAB on KEY_PRESSED, CTRL-SHIFT-TAB on KEY_PRESSED
+     *   <tr>
+     *     <th scope="row">KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS
+     *     <td>Go up one focus traversal cycle
+     *     <td>none
+     *   <tr>
+     *     <th scope="row">KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS
+     *     <td>Go down one focus traversal cycle
+     *     <td>none
      * </tbody>
      * </table>
      *
--- a/src/java.desktop/share/classes/java/awt/Desktop.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/java/awt/Desktop.java	Wed Nov 08 16:03:35 2017 -0500
@@ -768,13 +768,13 @@
      * Installs the handler which is notified when the application is asked to
      * open a list of files.
      *
-     * @implNote Please note that for Mac OS, notifications
+     * @implNote Please note that for macOS, notifications
      * are only sent if the Java app is a bundled application,
      * with a {@code CFBundleDocumentTypes} array present in its
-     * Info.plist. See the
-     * <a href="http://developer.apple.com/mac/library/documentation/General/Reference/InfoPlistKeyReference">
-     * Info.plist Key Reference</a> for more information about adding a
-     * {@code CFBundleDocumentTypes} key to your app's Info.plist.
+     * {@code Info.plist}. Check the
+     * <a href="https://developer.apple.com/documentation">
+     * Apple Developer Documentation</a> for more information about
+     * {@code Info.plist}.
      *
      * @param openFileHandler handler
      *
@@ -800,13 +800,13 @@
      * Installs the handler which is notified when the application is asked to
      * print a list of files.
      *
-     * @implNote Please note that for Mac OS, notifications
+     * @implNote Please note that for macOS, notifications
      * are only sent if the Java app is a bundled application,
      * with a {@code CFBundleDocumentTypes} array present in its
-     * Info.plist. See the
-     * <a href="http://developer.apple.com/mac/library/documentation/General/Reference/InfoPlistKeyReference">
-     * Info.plist Key Reference</a> for more information about adding a
-     * {@code CFBundleDocumentTypes} key to your app's Info.plist.
+     * {@code Info.plist}. Check the
+     * <a href="https://developer.apple.com/documentation">
+     * Apple Developer Documentation</a> for more information about
+     * {@code Info.plist}.
      *
      * @param printFileHandler handler
      * @throws SecurityException if a security manager exists and its
@@ -835,13 +835,13 @@
      * {@link OpenURIHandler#openURI(OpenURIEvent)} requests to be
      * enqueued until another handler is set.
      *
-     * @implNote Please note that for Mac OS, notifications
+     * @implNote Please note that for macOS, notifications
      * are only sent if the Java app is a bundled application,
      * with a {@code CFBundleDocumentTypes} array present in its
-     * Info.plist. See the
-     * <a href="http://developer.apple.com/mac/library/documentation/General/Reference/InfoPlistKeyReference">
-     * Info.plist Key Reference</a> for more information about adding a
-     * {@code CFBundleDocumentTypes} key to your app's Info.plist.
+     * {@code Info.plist}. Check the
+     * <a href="https://developer.apple.com/documentation">
+     * Apple Developer Documentation</a> for more information about
+     * {@code Info.plist}.
      *
      * @param openURIHandler handler
      *
--- a/src/java.desktop/share/classes/java/awt/EventQueue.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/java/awt/EventQueue.java	Wed Nov 08 16:03:35 2017 -0500
@@ -680,33 +680,28 @@
      * <table class="striped">
      * <caption>Event types, source types, and dispatch methods</caption>
      * <thead>
-     * <tr>
-     *     <th>Event Type</th>
-     *     <th>Source Type</th>
-     *     <th>Dispatched To</th>
-     * </tr>
+     *   <tr>
+     *     <th scope="col">Event Type
+     *     <th scope="col">Source Type
+     *     <th scope="col">Dispatched To
      * </thead>
      * <tbody>
-     * <tr>
-     *     <td>ActiveEvent</td>
-     *     <td>Any</td>
-     *     <td>event.dispatch()</td>
-     * </tr>
-     * <tr>
-     *     <td>Other</td>
-     *     <td>Component</td>
-     *     <td>source.dispatchEvent(AWTEvent)</td>
-     * </tr>
-     * <tr>
-     *     <td>Other</td>
-     *     <td>MenuComponent</td>
-     *     <td>source.dispatchEvent(AWTEvent)</td>
-     * </tr>
-     * <tr>
-     *     <td>Other</td>
-     *     <td>Other</td>
-     *     <td>No action (ignored)</td>
-     * </tr>
+     *   <tr>
+     *     <th scope="row">ActiveEvent
+     *     <td>Any
+     *     <td>event.dispatch()
+     *   <tr>
+     *     <th scope="row">Other
+     *     <td>Component
+     *     <td>source.dispatchEvent(AWTEvent)
+     *   <tr>
+     *     <th scope="row">Other
+     *     <td>MenuComponent
+     *     <td>source.dispatchEvent(AWTEvent)
+     *   <tr>
+     *     <th scope="row">Other
+     *     <td>Other
+     *     <td>No action (ignored)
      * </tbody>
      * </table>
      *
--- a/src/java.desktop/share/classes/java/awt/GraphicsDevice.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/java/awt/GraphicsDevice.java	Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,12 +23,10 @@
  * questions.
  */
 
-
 package java.awt;
 
 import java.awt.image.ColorModel;
 
-import sun.awt.AWTAccessor;
 import sun.awt.AppContext;
 import sun.awt.SunToolkit;
 
--- a/src/java.desktop/share/classes/java/awt/KeyboardFocusManager.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/java/awt/KeyboardFocusManager.java	Wed Nov 08 16:03:35 2017 -0500
@@ -1042,35 +1042,30 @@
      * <table class="striped">
      * <caption>Recommended default values for focus traversal keys</caption>
      * <thead>
-     * <tr>
-     *    <th>Identifier</th>
-     *    <th>Meaning</th>
-     *    <th>Default</th>
-     * </tr>
+     *   <tr>
+     *     <th scope="col">Identifier
+     *     <th scope="col">Meaning
+     *     <th scope="col">Default
      * </thead>
      * <tbody>
-     * <tr>
-     *    <td>{@code KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS}</td>
-     *    <td>Normal forward keyboard traversal</td>
-     *    <td>{@code TAB} on {@code KEY_PRESSED},
-     *        {@code CTRL-TAB} on {@code KEY_PRESSED}</td>
-     * </tr>
-     * <tr>
-     *    <td>{@code KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS}</td>
-     *    <td>Normal reverse keyboard traversal</td>
-     *    <td>{@code SHIFT-TAB} on {@code KEY_PRESSED},
-     *        {@code CTRL-SHIFT-TAB} on {@code KEY_PRESSED}</td>
-     * </tr>
-     * <tr>
-     *    <td>{@code KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS}</td>
-     *    <td>Go up one focus traversal cycle</td>
-     *    <td>none</td>
-     * </tr>
-     * <tr>
-     *    <td>{@code KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS}</td>
-     *    <td>Go down one focus traversal cycle</td>
-     *    <td>none</td>
-     * </tr>
+     *   <tr>
+     *     <th scope="row">{@code KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS}
+     *     <td>Normal forward keyboard traversal
+     *     <td>{@code TAB} on {@code KEY_PRESSED}, {@code CTRL-TAB} on
+     *     {@code KEY_PRESSED}
+     *   <tr>
+     *     <th scope="row">{@code KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS}
+     *     <td>Normal reverse keyboard traversal
+     *     <td>{@code SHIFT-TAB} on {@code KEY_PRESSED}, {@code CTRL-SHIFT-TAB}
+     *     on {@code KEY_PRESSED}
+     *   <tr>
+     *     <th scope="row">{@code KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS}
+     *     <td>Go up one focus traversal cycle
+     *     <td>none
+     *   <tr>
+     *     <th scope="row">{@code KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS}
+     *     <td>Go down one focus traversal cycle
+     *     <td>none
      * </tbody>
      * </table>
      *
--- a/src/java.desktop/share/classes/java/awt/Scrollbar.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/java/awt/Scrollbar.java	Wed Nov 08 16:03:35 2017 -0500
@@ -299,58 +299,44 @@
      * <table class="striped">
      * <caption>Scrollbar default properties</caption>
      * <thead>
-     * <tr>
-     *   <th>Property</th>
-     *   <th>Description</th>
-     *   <th>Default Value</th>
-     * </tr>
+     *   <tr>
+     *     <th scope="col">Property
+     *     <th scope="col">Description
+     *     <th scope="col">Default Value
      * </thead>
      * <tbody>
-     * <tr>
-     *   <td>orientation</td>
-     *   <td>indicates whether the scroll bar is vertical
-     *   <br>or horizontal</td>
-     *   <td>{@code Scrollbar.VERTICAL}</td>
-     * </tr>
-     * <tr>
-     *   <td>value</td>
-     *   <td>value which controls the location
-     *   <br>of the scroll bar's bubble</td>
-     *   <td>0</td>
-     * </tr>
-     * <tr>
-     *   <td>visible amount</td>
-     *   <td>visible amount of the scroll bar's range,
-     *   <br>typically represented by the size of the
-     *   <br>scroll bar's bubble</td>
-     *   <td>10</td>
-     * </tr>
-     * <tr>
-     *   <td>minimum</td>
-     *   <td>minimum value of the scroll bar</td>
-     *   <td>0</td>
-     * </tr>
-     * <tr>
-     *   <td>maximum</td>
-     *   <td>maximum value of the scroll bar</td>
-     *   <td>100</td>
-     * </tr>
-     * <tr>
-     *   <td>unit increment</td>
-     *   <td>amount the value changes when the
-     *   <br>Line Up or Line Down key is pressed,
-     *   <br>or when the end arrows of the scrollbar
-     *   <br>are clicked </td>
-     *   <td>1</td>
-     * </tr>
-     * <tr>
-     *   <td>block increment</td>
-     *   <td>amount the value changes when the
-     *   <br>Page Up or Page Down key is pressed,
-     *   <br>or when the scrollbar track is clicked
-     *   <br>on either side of the bubble </td>
-     *   <td>10</td>
-     * </tr>
+     *   <tr>
+     *     <th scope="row">orientation
+     *     <td>indicates whether the scroll bar is vertical or horizontal
+     *     <td>{@code Scrollbar.VERTICAL}
+     *   <tr>
+     *     <th scope="row">value
+     *     <td>value which controls the location of the scroll bar's bubble
+     *     <td>0
+     *   <tr>
+     *     <th scope="row">visible amount
+     *     <td>visible amount of the scroll bar's range, typically represented
+     *     by the size of the scroll bar's bubble
+     *     <td>10
+     *   <tr>
+     *     <th scope="row">minimum
+     *     <td>minimum value of the scroll bar
+     *     <td>0
+     *   <tr>
+     *     <th scope="row">maximum
+     *     <td>maximum value of the scroll bar
+     *     <td>100
+     *   <tr>
+     *     <th scope="row">unit increment
+     *     <td>amount the value changes when the Line Up or Line Down key is
+     *     pressed, or when the end arrows of the scrollbar are clicked
+     *     <td>1
+     *   <tr>
+     *     <th scope="row">block increment
+     *     <td>amount the value changes when the Page Up or Page Down key is
+     *     pressed, or when the scrollbar track is clicked<br>on either side of
+     *     the bubble
+     *     <td>10
      * </tbody>
      * </table>
      *
--- a/src/java.desktop/share/classes/java/awt/SystemTray.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/java/awt/SystemTray.java	Wed Nov 08 16:03:35 2017 -0500
@@ -371,28 +371,26 @@
      * <table class="striped">
      * <caption>SystemTray properties</caption>
      * <thead>
-     * <tr>
-     *    <th>Property</th>
-     *    <th>Description</th>
-     * </tr>
+     *   <tr>
+     *     <th scope="col">Property
+     *     <th scope="col">Description
      * </thead>
      * <tbody>
-     * <tr>
-     *    <td>{@code trayIcons}</td>
-     *    <td>The {@code SystemTray}'s array of {@code TrayIcon} objects.
-     *        The array is accessed via the {@link #getTrayIcons} method.<br>
-     *        This property is changed when a tray icon is added to (or removed
-     *        from) the system tray.<br> For example, this property is changed
-     *        when the system tray becomes unavailable on the desktop<br>
-     *        and the tray icons are automatically removed.</td>
-     * </tr>
-     * <tr>
-     *    <td>{@code systemTray}</td>
-     *    <td>This property contains {@code SystemTray} instance when the system tray
-     *        is available or {@code null} otherwise.<br> This property is changed
-     *        when the system tray becomes available or unavailable on the desktop.<br>
-     *        The property is accessed by the {@link #getSystemTray} method.</td>
-     * </tr>
+     *   <tr>
+     *     <th scope="row">{@code trayIcons}
+     *     <td>The {@code SystemTray}'s array of {@code TrayIcon} objects. The
+     *     array is accessed via the {@link #getTrayIcons} method. This property
+     *     is changed when a tray icon is added to (or removed from) the system
+     *     tray. For example, this property is changed when the system tray
+     *     becomes unavailable on the desktop and the tray icons are
+     *     automatically removed.
+     *   <tr>
+     *     <th scope="row">{@code systemTray}
+     *     <td>This property contains {@code SystemTray} instance when the
+     *     system tray is available or {@code null} otherwise. This property is
+     *     changed when the system tray becomes available or unavailable on the
+     *     desktop. The property is accessed by the {@link #getSystemTray}
+     *     method.
      * </tbody>
      * </table>
      * <p>
--- a/src/java.desktop/share/classes/java/awt/Window.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/java/awt/Window.java	Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1995, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -22,9 +22,17 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
+
 package java.awt;
 
-import java.awt.event.*;
+import java.awt.event.ComponentEvent;
+import java.awt.event.FocusEvent;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseWheelEvent;
+import java.awt.event.WindowEvent;
+import java.awt.event.WindowFocusListener;
+import java.awt.event.WindowListener;
+import java.awt.event.WindowStateListener;
 import java.awt.geom.Path2D;
 import java.awt.geom.Point2D;
 import java.awt.im.InputContext;
@@ -48,7 +56,13 @@
 import java.util.Set;
 import java.util.Vector;
 import java.util.concurrent.atomic.AtomicBoolean;
-import javax.accessibility.*;
+
+import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+import javax.accessibility.AccessibleState;
+import javax.accessibility.AccessibleStateSet;
+
 import sun.awt.AWTAccessor;
 import sun.awt.AWTPermissions;
 import sun.awt.AppContext;
@@ -4050,26 +4064,6 @@
 
     static {
         AWTAccessor.setWindowAccessor(new AWTAccessor.WindowAccessor() {
-            public float getOpacity(Window window) {
-                return window.opacity;
-            }
-            public void setOpacity(Window window, float opacity) {
-                window.setOpacity(opacity);
-            }
-            public Shape getShape(Window window) {
-                return window.getShape();
-            }
-            public void setShape(Window window, Shape shape) {
-                window.setShape(shape);
-            }
-            public void setOpaque(Window window, boolean opaque) {
-                Color bg = window.getBackground();
-                if (bg == null) {
-                    bg = new Color(0, 0, 0, 0);
-                }
-                window.setBackground(new Color(bg.getRed(), bg.getGreen(), bg.getBlue(),
-                                               opaque ? 255 : 0));
-            }
             public void updateWindow(Window window) {
                 window.updateWindow();
             }
--- a/src/java.desktop/share/classes/java/awt/event/MouseEvent.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/java/awt/event/MouseEvent.java	Wed Nov 08 16:03:35 2017 -0500
@@ -745,7 +745,6 @@
      * @see #getClickCount()
      * @see #isPopupTrigger()
      * @see #getButton()
-     * @see #button
      * @see Toolkit#areExtraMouseButtonsEnabled()
      * @see java.awt.MouseInfo#getNumberOfButtons()
      * @see InputEvent#getMaskForButton(int)
--- a/src/java.desktop/share/classes/java/awt/font/NumericShaper.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/java/awt/font/NumericShaper.java	Wed Nov 08 16:03:35 2017 -0500
@@ -108,39 +108,36 @@
  *
  * <table class="plain">
  * <caption>NumericShaper constants precedence</caption>
- *    <thead>
- *    <tr>
- *       <th class="TableHeadingColor">Unicode Range</th>
- *       <th class="TableHeadingColor">{@code NumericShaper} Constants</th>
- *       <th class="TableHeadingColor">Precedence</th>
- *    </tr>
- *    </thead>
- *    <tbody>
- *    <tr>
- *       <td rowspan="2">Arabic</td>
- *       <td>{@link NumericShaper#ARABIC NumericShaper.ARABIC}<br>
- *           {@link NumericShaper#EASTERN_ARABIC NumericShaper.EASTERN_ARABIC}</td>
- *       <td>{@link NumericShaper#EASTERN_ARABIC NumericShaper.EASTERN_ARABIC}</td>
- *    </tr>
- *    <tr>
- *       <td>{@link NumericShaper.Range#ARABIC}<br>
- *           {@link NumericShaper.Range#EASTERN_ARABIC}</td>
- *       <td>{@link NumericShaper.Range#EASTERN_ARABIC}</td>
- *    </tr>
- *    </tbody>
- *    <tbody>
- *    <tr>
- *       <td>Tai Tham</td>
- *       <td>{@link NumericShaper.Range#TAI_THAM_HORA}<br>
- *           {@link NumericShaper.Range#TAI_THAM_THAM}</td>
- *       <td>{@link NumericShaper.Range#TAI_THAM_THAM}</td>
- *    </tr>
- *    </tbody>
+ * <thead>
+ *   <tr>
+ *     <th scope="col">Unicode Range
+ *     <th scope="col">{@code NumericShaper} Constants
+ *     <th scope="col">Precedence
+ * </thead>
+ * <tbody>
+ *   <tr>
+ *     <th scope="row" rowspan="2">Arabic
+ *     <td>{@link NumericShaper#ARABIC NumericShaper.ARABIC}
+ *     <br>
+ *     {@link NumericShaper#EASTERN_ARABIC NumericShaper.EASTERN_ARABIC}
+ *     <td>{@link NumericShaper#EASTERN_ARABIC NumericShaper.EASTERN_ARABIC}
+ *   </tr>
+ *   <tr>
+ *     <th scope="row">{@link NumericShaper.Range#ARABIC}
+ *     <br>
+ *     {@link NumericShaper.Range#EASTERN_ARABIC}
+ *     <td>{@link NumericShaper.Range#EASTERN_ARABIC}
+ *   <tr>
+ *     <th scope="row">Tai Tham
+ *     <td>{@link NumericShaper.Range#TAI_THAM_HORA}
+ *     <br>
+ *     {@link NumericShaper.Range#TAI_THAM_THAM}
+ *     <td>{@link NumericShaper.Range#TAI_THAM_THAM}
+ * </tbody>
  * </table>
  *
  * @since 1.4
  */
-
 public final class NumericShaper implements java.io.Serializable {
 
     // For access from java.text.Bidi
--- a/src/java.desktop/share/classes/java/awt/font/TextAttribute.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/java/awt/font/TextAttribute.java	Wed Nov 08 16:03:35 2017 -0500
@@ -96,159 +96,141 @@
  * </UL>
  *
  * <h4>Summary of attributes</h4>
- * <table style="float:center;width:95%" class="striped">
- * <caption>Key, value type, principal constants, and
- * default value behavior of all TextAttributes</caption>
+ *
+ * <table style="width:95%;margin: 0px auto" class="striped">
+ * <caption>Key, value type, principal constants, and default value behavior of
+ * all TextAttributes</caption>
  * <thead>
- * <tr>
- * <th valign="TOP" style="text-align:center">Key</th>
- * <th valign="TOP" style="text-align:center">Value Type</th>
- * <th valign="TOP" style="text-align:center">Principal Constants</th>
- * <th valign="TOP" style="text-align:center">Default Value</th>
- * </tr>
+ *   <tr>
+ *     <th scope="col">Key
+ *     <th scope="col">Value Type
+ *     <th scope="col">Principal Constants
+ *     <th scope="col">Default Value
  * </thead>
  * <tbody>
- * <tr>
- * <td valign="TOP">{@link #FAMILY}</td>
- * <td valign="TOP">String</td>
- * <td valign="TOP">See Font {@link java.awt.Font#DIALOG DIALOG},
- * {@link java.awt.Font#DIALOG_INPUT DIALOG_INPUT},<br> {@link java.awt.Font#SERIF SERIF},
- * {@link java.awt.Font#SANS_SERIF SANS_SERIF}, and {@link java.awt.Font#MONOSPACED MONOSPACED}.
- * </td>
- * <td valign="TOP">"Default" (use platform default)</td>
- * </tr>
- * <tr>
- * <td valign="TOP">{@link #WEIGHT}</td>
- * <td valign="TOP">Number</td>
- * <td valign="TOP">WEIGHT_REGULAR, WEIGHT_BOLD</td>
- * <td valign="TOP">WEIGHT_REGULAR</td>
- * </tr>
- * <tr>
- * <td valign="TOP">{@link #WIDTH}</td>
- * <td valign="TOP">Number</td>
- * <td valign="TOP">WIDTH_CONDENSED, WIDTH_REGULAR,<br>WIDTH_EXTENDED</td>
- * <td valign="TOP">WIDTH_REGULAR</td>
- * </tr>
- * <tr>
- * <td valign="TOP">{@link #POSTURE}</td>
- * <td valign="TOP">Number</td>
- * <td valign="TOP">POSTURE_REGULAR, POSTURE_OBLIQUE</td>
- * <td valign="TOP">POSTURE_REGULAR</td>
- * </tr>
- * <tr>
- * <td valign="TOP">{@link #SIZE}</td>
- * <td valign="TOP">Number</td>
- * <td valign="TOP">none</td>
- * <td valign="TOP">12.0</td>
- * </tr>
- * <tr>
- * <td valign="TOP">{@link #TRANSFORM}</td>
- * <td valign="TOP">{@link TransformAttribute}</td>
- * <td valign="TOP">See TransformAttribute {@link TransformAttribute#IDENTITY IDENTITY}</td>
- * <td valign="TOP">TransformAttribute.IDENTITY</td>
- * </tr>
- * <tr>
- * <td valign="TOP">{@link #SUPERSCRIPT}</td>
- * <td valign="TOP">Integer</td>
- * <td valign="TOP">SUPERSCRIPT_SUPER, SUPERSCRIPT_SUB</td>
- * <td valign="TOP">0 (use the standard glyphs and metrics)</td>
- * </tr>
- * <tr>
- * <td valign="TOP">{@link #FONT}</td>
- * <td valign="TOP">{@link java.awt.Font}</td>
- * <td valign="TOP">none</td>
- * <td valign="TOP">null (do not override font resolution)</td>
- * </tr>
- * <tr>
- * <td valign="TOP">{@link #CHAR_REPLACEMENT}</td>
- * <td valign="TOP">{@link GraphicAttribute}</td>
- * <td valign="TOP">none</td>
- * <td valign="TOP">null (draw text using font glyphs)</td>
- * </tr>
- * <tr>
- * <td valign="TOP">{@link #FOREGROUND}</td>
- * <td valign="TOP">{@link java.awt.Paint}</td>
- * <td valign="TOP">none</td>
- * <td valign="TOP">null (use current graphics paint)</td>
- * </tr>
- * <tr>
- * <td valign="TOP">{@link #BACKGROUND}</td>
- * <td valign="TOP">{@link java.awt.Paint}</td>
- * <td valign="TOP">none</td>
- * <td valign="TOP">null (do not render background)</td>
- * </tr>
- * <tr>
- * <td valign="TOP">{@link #UNDERLINE}</td>
- * <td valign="TOP">Integer</td>
- * <td valign="TOP">UNDERLINE_ON</td>
- * <td valign="TOP">-1 (do not render underline)</td>
- * </tr>
- * <tr>
- * <td valign="TOP">{@link #STRIKETHROUGH}</td>
- * <td valign="TOP">Boolean</td>
- * <td valign="TOP">STRIKETHROUGH_ON</td>
- * <td valign="TOP">false (do not render strikethrough)</td>
- * </tr>
- * <tr>
- * <td valign="TOP">{@link #RUN_DIRECTION}</td>
- * <td valign="TOP">Boolean</td>
- * <td valign="TOP">RUN_DIRECTION_LTR<br>RUN_DIRECTION_RTL</td>
- * <td valign="TOP">null (use {@link java.text.Bidi} standard default)</td>
- * </tr>
- * <tr>
- * <td valign="TOP">{@link #BIDI_EMBEDDING}</td>
- * <td valign="TOP">Integer</td>
- * <td valign="TOP">none</td>
- * <td valign="TOP">0 (use base line direction)</td>
- * </tr>
- * <tr>
- * <td valign="TOP">{@link #JUSTIFICATION}</td>
- * <td valign="TOP">Number</td>
- * <td valign="TOP">JUSTIFICATION_FULL</td>
- * <td valign="TOP">JUSTIFICATION_FULL</td>
- * </tr>
- * <tr>
- * <td valign="TOP">{@link #INPUT_METHOD_HIGHLIGHT}</td>
- * <td valign="TOP">{@link java.awt.im.InputMethodHighlight},<br>{@link java.text.Annotation}</td>
- * <td valign="TOP">(see class)</td>
- * <td valign="TOP">null (do not apply input highlighting)</td>
- * </tr>
- * <tr>
- * <td valign="TOP">{@link #INPUT_METHOD_UNDERLINE}</td>
- * <td valign="TOP">Integer</td>
- * <td valign="TOP">UNDERLINE_LOW_ONE_PIXEL,<br>UNDERLINE_LOW_TWO_PIXEL</td>
- * <td valign="TOP">-1 (do not render underline)</td>
- * </tr>
- * <tr>
- * <td valign="TOP">{@link #SWAP_COLORS}</td>
- * <td valign="TOP">Boolean</td>
- * <td valign="TOP">SWAP_COLORS_ON</td>
- * <td valign="TOP">false (do not swap colors)</td>
- * </tr>
- * <tr>
- * <td valign="TOP">{@link #NUMERIC_SHAPING}</td>
- * <td valign="TOP">{@link java.awt.font.NumericShaper}</td>
- * <td valign="TOP">none</td>
- * <td valign="TOP">null (do not shape digits)</td>
- * </tr>
- * <tr>
- * <td valign="TOP">{@link #KERNING}</td>
- * <td valign="TOP">Integer</td>
- * <td valign="TOP">KERNING_ON</td>
- * <td valign="TOP">0 (do not request kerning)</td>
- * </tr>
- * <tr>
- * <td valign="TOP">{@link #LIGATURES}</td>
- * <td valign="TOP">Integer</td>
- * <td valign="TOP">LIGATURES_ON</td>
- * <td valign="TOP">0 (do not form optional ligatures)</td>
- * </tr>
- * <tr>
- * <td valign="TOP">{@link #TRACKING}</td>
- * <td valign="TOP">Number</td>
- * <td valign="TOP">TRACKING_LOOSE, TRACKING_TIGHT</td>
- * <td valign="TOP">0 (do not add tracking)</td>
- * </tr>
+ *   <tr>
+ *     <th scope="row">{@link #FAMILY}
+ *     <td>String
+ *     <td>See Font {@link java.awt.Font#DIALOG DIALOG},
+ *     {@link java.awt.Font#DIALOG_INPUT DIALOG_INPUT},
+ *     <br>
+ *     {@link java.awt.Font#SERIF SERIF},
+ *     {@link java.awt.Font#SANS_SERIF SANS_SERIF}, and
+ *     {@link java.awt.Font#MONOSPACED MONOSPACED}.
+ *     <td>"Default" (use platform default)
+ *   <tr>
+ *     <th scope="row">{@link #WEIGHT}
+ *     <td>Number
+ *     <td>WEIGHT_REGULAR, WEIGHT_BOLD
+ *     <td>WEIGHT_REGULAR
+ *   <tr>
+ *     <th scope="row">{@link #WIDTH}
+ *     <td>Number
+ *     <td>WIDTH_CONDENSED, WIDTH_REGULAR,<br>WIDTH_EXTENDED
+ *     <td>WIDTH_REGULAR
+ *   <tr>
+ *     <th scope="row">{@link #POSTURE}
+ *     <td>Number
+ *     <td>POSTURE_REGULAR, POSTURE_OBLIQUE
+ *     <td>POSTURE_REGULAR
+ *   <tr>
+ *     <th scope="row">{@link #SIZE}
+ *     <td>Number
+ *     <td>none
+ *     <td>12.0
+ *   <tr>
+ *     <th scope="row">{@link #TRANSFORM}
+ *     <td>{@link TransformAttribute}
+ *     <td>See TransformAttribute {@link TransformAttribute#IDENTITY IDENTITY}
+ *     <td>TransformAttribute.IDENTITY
+ *   <tr>
+ *     <th scope="row">{@link #SUPERSCRIPT}
+ *     <td>Integer
+ *     <td>SUPERSCRIPT_SUPER, SUPERSCRIPT_SUB
+ *     <td>0 (use the standard glyphs and metrics)
+ *   <tr>
+ *     <th scope="row">{@link #FONT}
+ *     <td>{@link java.awt.Font}
+ *     <td>none
+ *     <td>null (do not override font resolution)
+ *   <tr>
+ *     <th scope="row">{@link #CHAR_REPLACEMENT}
+ *     <td>{@link GraphicAttribute}
+ *     <td>none
+ *     <td>null (draw text using font glyphs)
+ *   <tr>
+ *     <th scope="row">{@link #FOREGROUND}
+ *     <td>{@link java.awt.Paint}
+ *     <td>none
+ *     <td>null (use current graphics paint)
+ *   <tr>
+ *     <th scope="row">{@link #BACKGROUND}
+ *     <td>{@link java.awt.Paint}
+ *     <td>none
+ *     <td>null (do not render background)
+ *   <tr>
+ *     <th scope="row">{@link #UNDERLINE}
+ *     <td>Integer
+ *     <td>UNDERLINE_ON
+ *     <td>-1 (do not render underline)
+ *   <tr>
+ *     <th scope="row">{@link #STRIKETHROUGH}
+ *     <td>Boolean
+ *     <td>STRIKETHROUGH_ON
+ *     <td>false (do not render strikethrough)
+ *   <tr>
+ *     <th scope="row">{@link #RUN_DIRECTION}
+ *     <td>Boolean
+ *     <td>RUN_DIRECTION_LTR<br>RUN_DIRECTION_RTL
+ *     <td>null (use {@link java.text.Bidi} standard default)
+ *   <tr>
+ *     <th scope="row">{@link #BIDI_EMBEDDING}
+ *     <td>Integer
+ *     <td>none
+ *     <td>0 (use base line direction)
+ *   <tr>
+ *     <th scope="row">{@link #JUSTIFICATION}
+ *     <td>Number
+ *     <td>JUSTIFICATION_FULL
+ *     <td>JUSTIFICATION_FULL
+ *   <tr>
+ *     <th scope="row">{@link #INPUT_METHOD_HIGHLIGHT}
+ *     <td>{@link java.awt.im.InputMethodHighlight},
+ *     <br>
+ *     {@link java.text.Annotation}
+ *     <td>(see class)
+ *     <td>null (do not apply input highlighting)
+ *   <tr>
+ *     <th scope="row">{@link #INPUT_METHOD_UNDERLINE}
+ *     <td>Integer
+ *     <td>UNDERLINE_LOW_ONE_PIXEL,<br>UNDERLINE_LOW_TWO_PIXEL
+ *     <td>-1 (do not render underline)
+ *   <tr>
+ *     <th scope="row">{@link #SWAP_COLORS}
+ *     <td>Boolean
+ *     <td>SWAP_COLORS_ON
+ *     <td>false (do not swap colors)
+ *   <tr>
+ *     <th scope="row">{@link #NUMERIC_SHAPING}
+ *     <td>{@link java.awt.font.NumericShaper}
+ *     <td>none
+ *     <td>null (do not shape digits)
+ *   <tr>
+ *     <th scope="row">{@link #KERNING}
+ *     <td>Integer
+ *     <td>KERNING_ON
+ *     <td>0 (do not request kerning)
+ *   <tr>
+ *     <th scope="row">{@link #LIGATURES}
+ *     <td>Integer
+ *     <td>LIGATURES_ON
+ *     <td>0 (do not form optional ligatures)
+ *   <tr>
+ *     <th scope="row">{@link #TRACKING}
+ *     <td>Number
+ *     <td>TRACKING_LOOSE, TRACKING_TIGHT
+ *     <td>0 (do not add tracking)
+ *   </tr>
  * </tbody>
  * </table>
  *
--- a/src/java.desktop/share/classes/java/awt/image/RescaleOp.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/java/awt/image/RescaleOp.java	Wed Nov 08 16:03:35 2017 -0500
@@ -360,7 +360,8 @@
      *         of {@code src} is an {@code IndexColorModel},
      *         or if the number of scaling factors and offsets in this
      *         {@code RescaleOp} do not meet the requirements
-     *         stated in the class comments.
+     *         stated in the class comments, or if the source and
+     *         destination images differ in size.
      */
     public final BufferedImage filter (BufferedImage src, BufferedImage dst) {
         ColorModel srcCM = src.getColorModel();
@@ -473,7 +474,8 @@
      *         {@code dst} do not have the same number of bands,
      *         or if the number of scaling factors and offsets in this
      *         {@code RescaleOp} do not meet the requirements
-     *         stated in the class comments.
+     *         stated in the class comments, or if the source and
+     *         destination rasters differ in size.
      */
     public final WritableRaster filter (Raster src, WritableRaster dst)  {
         return filterRasterImpl(src, dst, length, true);
--- a/src/java.desktop/share/classes/javax/imageio/package-info.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/imageio/package-info.java	Wed Nov 08 16:03:35 2017 -0500
@@ -39,84 +39,77 @@
  * <p>
  * All implementations of javax.imageio provide the following standard image
  * format plug-ins:
- * <div>
- * <table border=1 cellpadding=5 style="margin: 0px auto;" summary="Standard
- * image format plug-ins">
- *     <tr>
- *         <th>&nbsp;</th><th>Reading</th><th>Writing</th><th>Notes</th>
- *         <th>Metadata</th>
- *     </tr>
  *
+ * <table class="striped">
+ * <caption>Standard image format plug-ins</caption>
+ * <thead>
+ *   <tr>
+ *     <th scope="col">Image format
+ *     <th scope="col">Reading
+ *     <th scope="col">Writing
+ *     <th scope="col">Notes
+ *     <th scope="col">Metadata
+ * </thead>
+ * <tbody>
  * <!-- BMP plugin -->
- *     <tr>
- *         <td><a href="https://msdn.microsoft.com/en-us/library/dd183391.aspx">
- *         BMP</a></td>
- *         <td align='center'>yes</td>
- *         <td align='center'>yes</td>
- *         <td align='center'>none</td>
- *         <td align='center'><a href='metadata/doc-files/bmp_metadata.html'>BMP
- *         metadata format</a></td>
- *     </tr>
- *
+ *   <tr>
+ *     <th scope="row">
+ *     <a href="https://msdn.microsoft.com/en-us/library/dd183391.aspx">BMP</a>
+ *     <td>yes
+ *     <td>yes
+ *     <td>none
+ *     <td><a href='metadata/doc-files/bmp_metadata.html'>BMP
+ *     metadata format</a>
  * <!-- GIF plugin -->
- *     <tr>
- *         <td><a href="http://www.w3.org/Graphics/GIF/spec-gif89a.txt">GIF</a>
- *         </td>
- *         <td align='center'>yes</td>
- *         <td align='center'>yes</td>
- *         <td align='center'><a href="#gif_plugin_notes">GIF plug-in notes</a>
- *         </td>
- *         <td align='center'><a href='metadata/doc-files/gif_metadata.html'>GIF
- *         metadata format</a></td>
- *     </tr>
- *
+ *   <tr>
+ *     <th scope="row">
+ *     <a href="http://www.w3.org/Graphics/GIF/spec-gif89a.txt">GIF</a>
+ *     <td>yes
+ *     <td>yes
+ *     <td><a href="#gif_plugin_notes">GIF plug-in notes</a>
+ *     <td><a href='metadata/doc-files/gif_metadata.html'>GIF
+ *     metadata format</a>
  * <!-- JPEG plugin -->
- *     <tr>
- *         <td><a href="http://www.jpeg.org">JPEG</a></td>
- *         <td align='center'>yes</td>
- *         <td align='center'>yes</td>
- *         <td align='center'>none</td>
- *         <td align='center'><a href='metadata/doc-files/jpeg_metadata.html'>
- *         JPEG metadata format</a></td>
- *     </tr>
- *
+ *   <tr>
+ *     <th scope="row"><a href="http://www.jpeg.org">JPEG</a>
+ *     <td>yes
+ *     <td>yes
+ *     <td>none
+ *     <td><a href='metadata/doc-files/jpeg_metadata.html'>
+ *     JPEG metadata format</a>
  * <!-- PNG plugin -->
- *     <tr>
- *         <td><a href="http://www.libpng.org/pub/png/spec/">PNG</a></td>
- *         <td align='center'>yes</td>
- *         <td align='center'>yes</td>
- *         <td align='center'>none</td>
- *         <td align='center'><a href='metadata/doc-files/png_metadata.html'>PNG
- *         metadata format</a></td>
- *     </tr>
- *
+ *   <tr>
+ *     <th scope="row"><a href="http://www.libpng.org/pub/png/spec/">PNG</a>
+ *     <td>yes
+ *     <td>yes
+ *     <td>none
+ *     <td><a href='metadata/doc-files/png_metadata.html'>PNG
+ *     metadata format</a>
  * <!-- TIFF plugin -->
- *     <tr>
- *         <td><a href="https://partners.adobe.com/public/developer/en/tiff/TIFF6.pdf">
- *         TIFF</a></td>
- *         <td align='center'>yes</td>
- *         <td align='center'>yes</td>
- *         <td align='center'><a href='metadata/doc-files/tiff_metadata.html#Reading'>
- *         TIFF plug-in notes</a></td>
- *         <td align='center'><a href='metadata/doc-files/tiff_metadata.html#StreamMetadata'>
- *         TIFF metadata format</a></td>
- *     </tr>
- *
+ *   <tr>
+ *     <th scope="row">
+ *     <a href="https://partners.adobe.com/public/developer/en/tiff/TIFF6.pdf">
+ *     TIFF</a>
+ *     <td>yes
+ *     <td>yes
+ *     <td>
+ *     <a href='metadata/doc-files/tiff_metadata.html#Reading'>TIFF plug-in
+ *     notes</a>
+ *     <td>
+ *     <a href='metadata/doc-files/tiff_metadata.html#StreamMetadata'>TIFF
+ *     metadata format</a>
  * <!-- WBMP plugin -->
- *     <tr>
- *         <td><a href="http://www.wapforum.org/what/technical/SPEC-WAESpec-19990524.pdf">
- *         WBMP</a></td>
- *         <td align='center'>yes</td>
- *         <td align='center'>yes</td>
- *         <td align='center'>none</td>
- *         <td align='center'><a href='metadata/doc-files/wbmp_metadata.html'>
- *         WBMP metadata format</a></td>
- *     </tr>
+ *   <tr>
+ *     <th scope="row">
+ *     <a href="http://www.wapforum.org/what/technical/SPEC-WAESpec-19990524.pdf">
+ *     WBMP</a>
+ *     <td>yes
+ *     <td>yes
+ *     <td>none
+ *     <td><a href='metadata/doc-files/wbmp_metadata.html'>
+ *     WBMP metadata format</a>
+ * </tbody>
  * </table>
- * </div>
- * <BR>
- * <BR>
- * <BR>
  *
  * <h2> Standard Plug-in Notes</h2>
  *
--- a/src/java.desktop/share/classes/javax/imageio/plugins/bmp/BMPImageWriteParam.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/imageio/plugins/bmp/BMPImageWriteParam.java	Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -54,13 +54,32 @@
  * listed in the following
  * table:
  *
- * <table border=1>
- * <caption><b>Compression Types</b></caption>
- * <tr><th>Type String</th> <th>Description</th>  <th>Image Types</th></tr>
- * <tr><td>BI_RGB</td>  <td>Uncompressed RLE</td> <td>{@literal <= } 8-bits/sample</td></tr>
- * <tr><td>BI_RLE8</td> <td>8-bit Run Length Encoding</td> <td>{@literal <=} 8-bits/sample</td></tr>
- * <tr><td>BI_RLE4</td> <td>4-bit Run Length Encoding</td> <td>{@literal <=} 4-bits/sample</td></tr>
- * <tr><td>BI_BITFIELDS</td> <td>Packed data</td> <td> 16 or 32 bits/sample</td></tr>
+ * <table class="striped">
+ * <caption>Compression Types</caption>
+ * <thead>
+ *   <tr>
+ *     <th scope="col">Type String
+ *     <th scope="col">Description
+ *     <th scope="col">Image Types
+ * </thead>
+ * <tbody>
+ *   <tr>
+ *     <th scope="row">BI_RGB
+ *     <td>Uncompressed RLE
+ *     <td>{@literal <= } 8-bits/sample
+ *   <tr>
+ *     <th scope="row">BI_RLE8
+ *     <td>8-bit Run Length Encoding
+ *     <td>{@literal <=} 8-bits/sample
+ *   <tr>
+ *     <th scope="row">BI_RLE4
+ *     <td>4-bit Run Length Encoding
+ *     <td>{@literal <=} 4-bits/sample
+ *   <tr>
+ *     <th scope="row">BI_BITFIELDS
+ *     <td>Packed data
+ *     <td>16 or 32 bits/sample
+ * </tbody>
  * </table>
  */
 public class BMPImageWriteParam extends ImageWriteParam {
--- a/src/java.desktop/share/classes/javax/imageio/plugins/tiff/TIFFField.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/imageio/plugins/tiff/TIFFField.java	Wed Nov 08 16:03:35 2017 -0500
@@ -40,221 +40,83 @@
  * TIFF data types are referred to by Java constants and mapped internally
  * onto Java language data types and type names as follows:
  *
- * <br>
- * <br>
- * <table border="1">
+ * <table class="striped">
  * <caption>TIFF Data Type to Java Data Type Mapping</caption>
- *
- * <tr>
- * <th>
- * <b>TIFF Data Type</b>
- * </th>
- * <th>
- * <b>Java Constant</b>
- * </th>
- * <th>
- * <b>Java Data Type</b>
- * </th>
- * <th>
- * <b>Java Type Name</b>
- * </th>
- * </tr>
- *
- * <tr>
- * <td>
- * {@code BYTE}
- * </td>
- * <td>
- * {@link TIFFTag#TIFF_BYTE}
- * </td>
- * <td>
- * {@code byte}
- * </td>
- * <td>
- * {@code "Byte"}
- * </td>
- * </tr>
- *
- * <tr>
- * <td>
- * {@code ASCII}
- * </td>
- * <td>
- * {@link TIFFTag#TIFF_ASCII}
- * </td>
- * <td>
- * {@code String}
- * </td>
- * <td>
- * {@code "Ascii"}
- * </td>
- * </tr>
- *
- * <tr>
- * <td>
- * {@code SHORT}
- * </td>
- * <td>
- * {@link TIFFTag#TIFF_SHORT}
- * </td>
- * <td>
- * {@code char}
- * </td>
- * <td>
- * {@code "Short"}
- * </td>
- * </tr>
- *
- * <tr>
- * <td>
- * {@code LONG}
- * </td>
- * <td>
- * {@link TIFFTag#TIFF_LONG}
- * </td>
- * <td>
- * {@code long}
- * </td>
- * <td>
- * {@code "Long"}
- * </td>
- * </tr>
- *
- * <tr>
- * <td>
- * {@code RATIONAL}
- * </td>
- * <td>
- * {@link TIFFTag#TIFF_RATIONAL}
- * </td>
- * <td>
- * {@code long[2]} {numerator, denominator}
- * </td>
- * <td>
- * {@code "Rational"}
- * </td>
- * </tr>
- *
- * <tr>
- * <td>
- * {@code SBYTE}
- * </td>
- * <td>
- * {@link TIFFTag#TIFF_SBYTE}
- * </td>
- * <td>
- * {@code byte}
- * </td>
- * <td>
- * {@code "SByte"}
- * </td>
- * </tr>
- *
- * <tr>
- * <td>
- * {@code UNDEFINED}
- * </td>
- * <td>
- * {@link TIFFTag#TIFF_UNDEFINED}
- * </td>
- * <td>
- * {@code byte}
- * </td>
- * <td>
- * {@code "Undefined"}
- * </td>
- * </tr>
- *
- * <tr>
- * <td>
- * {@code SSHORT}
- * </td>
- * <td>
- * {@link TIFFTag#TIFF_SSHORT}
- * </td>
- * <td>
- * {@code short}
- * </td>
- * <td>
- * {@code "SShort"}
- * </td>
- * </tr>
- *
- * <tr>
- * <td>
- * {@code SLONG}
- * </td>
- * <td>
- * {@link TIFFTag#TIFF_SLONG}
- * </td>
- * <td>
- * {@code int}
- * </td>
- * <td>
- * {@code "SLong"}
- * </td>
- * </tr>
- *
- * <tr>
- * <td>
- * {@code SRATIONAL}
- * </td>
- * <td>
- * {@link TIFFTag#TIFF_SRATIONAL}
- * </td>
- * <td>
- * {@code int[2]} {numerator, denominator}
- * </td>
- * <td>
- * {@code "SRational"}
- * </td>
- * </tr>
- *
- * <tr>
- * <td>
- * {@code FLOAT}
- * </td>
- * <td>
- * {@link TIFFTag#TIFF_FLOAT}
- * </td>
- * <td>
- * {@code float}
- * </td>
- * <td>
- * {@code "Float"}
- * </td>
- * </tr>
- *
- * <tr>
- * <td>
- * {@code DOUBLE}
- * </td>
- * <td>
- * {@link TIFFTag#TIFF_DOUBLE}
- * </td>
- * <td>
- * {@code double}
- * </td>
- * <td>
- * {@code "Double"}
- * </td>
- * </tr>
- *
- * <tr>
- * <td>
- * {@code IFD}
- * </td>
- * <td>
- * {@link TIFFTag#TIFF_IFD_POINTER}
- * </td>
- * <td>
- * {@code long}
- * </td>
- * <td>
- * {@code "IFDPointer"}
- * </td>
- * </tr>
- *
+ * <thead>
+ *   <tr>
+ *     <th scope="col">TIFF Data Type
+ *     <th scope="col">Java Constant
+ *     <th scope="col">Java Data Type
+ *     <th scope="col">Java Type Name
+ * </thead>
+ * <tbody>
+ *   <tr>
+ *     <th scope="row">{@code BYTE}
+ *     <td>{@link TIFFTag#TIFF_BYTE}
+ *     <td>{@code byte}
+ *     <td>{@code "Byte"}
+ *   <tr>
+ *     <th scope="row">{@code ASCII}
+ *     <td>{@link TIFFTag#TIFF_ASCII}
+ *     <td>{@code String}
+ *     <td>{@code "Ascii"}
+ *   <tr>
+ *     <th scope="row">{@code SHORT}
+ *     <td>{@link TIFFTag#TIFF_SHORT}
+ *     <td>{@code char}
+ *     <td>{@code "Short"}
+ *   <tr>
+ *     <th scope="row">{@code LONG}
+ *     <td>{@link TIFFTag#TIFF_LONG}
+ *     <td>{@code long}
+ *     <td>{@code "Long"}
+ *   <tr>
+ *     <th scope="row">{@code RATIONAL}
+ *     <td>{@link TIFFTag#TIFF_RATIONAL}
+ *     <td>{@code long[2]} {numerator, denominator}
+ *     <td>{@code "Rational"}
+ *   <tr>
+ *     <th scope="row">{@code SBYTE}
+ *     <td>{@link TIFFTag#TIFF_SBYTE}
+ *     <td>{@code byte}
+ *     <td>{@code "SByte"}
+ *   <tr>
+ *     <th scope="row">{@code UNDEFINED}
+ *     <td>{@link TIFFTag#TIFF_UNDEFINED}
+ *     <td>{@code byte}
+ *     <td>{@code "Undefined"}
+ *   <tr>
+ *     <th scope="row">{@code SSHORT}
+ *     <td>{@link TIFFTag#TIFF_SSHORT}
+ *     <td>{@code short}
+ *     <td>{@code "SShort"}
+ *   <tr>
+ *     <th scope="row">{@code SLONG}
+ *     <td>{@link TIFFTag#TIFF_SLONG}
+ *     <td>{@code int}
+ *     <td>{@code "SLong"}
+ *   <tr>
+ *     <th scope="row">{@code SRATIONAL}
+ *     <td>{@link TIFFTag#TIFF_SRATIONAL}
+ *     <td>{@code int[2]} {numerator, denominator}
+ *     <td>{@code "SRational"}
+ *   <tr>
+ *     <th scope="row">{@code FLOAT}
+ *     <td>{@link TIFFTag#TIFF_FLOAT}
+ *     <td>{@code float}
+ *     <td>{@code "Float"}
+ *   <tr>
+ *     <th scope="row">{@code DOUBLE}
+ *     <td>{@link TIFFTag#TIFF_DOUBLE}
+ *     <td>{@code double}
+ *     <td>{@code "Double"}
+ *   <tr>
+ *     <th scope="row">{@code IFD}
+ *     <td>{@link TIFFTag#TIFF_IFD_POINTER}
+ *     <td>{@code long}
+ *     <td>{@code "IFDPointer"}
+ *   </tr>
+ * </tbody>
  * </table>
  *
  * @since 9
--- a/src/java.desktop/share/classes/javax/print/DocFlavor.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/print/DocFlavor.java	Wed Nov 08 16:03:35 2017 -0500
@@ -175,21 +175,21 @@
  *   <caption>MIME-Types and their descriptions</caption>
  *   <thead>
  *     <tr>
- *       <th>MIME-Type
- *       <th>Description
+ *       <th scope="col">MIME-Type
+ *       <th scope="col">Description
  *   </thead>
  *   <tbody>
  *     <tr>
- *       <td>{@code "text/plain"}
+ *       <th scope="row">{@code "text/plain"}
  *       <td>Plain text in the default character set (US-ASCII)
  *     <tr>
- *       <td><code> "text/plain; charset=<i>xxx</i>"</code>
+ *       <th scope="row"><code> "text/plain; charset=<i>xxx</i>"</code>
  *       <td>Plain text in character set <i>xxx</i>
  *     <tr>
- *       <td>{@code "text/html"}
+ *       <th scope="row">{@code "text/html"}
  *       <td>HyperText Markup Language in the default character set (US-ASCII)
  *     <tr>
- *       <td><code> "text/html; charset=<i>xxx</i>"</code>
+ *       <th scope="row"><code> "text/html; charset=<i>xxx</i>"</code>
  *       <td>HyperText Markup Language in character set <i>xxx</i>
  *   </tbody>
  *   </table>
@@ -201,18 +201,18 @@
  *   <caption>MIME-Types and their descriptions</caption>
  *   <thead>
  *     <tr>
- *       <th>MIME-Type
- *       <th>Description
+ *       <th scope="col">MIME-Type
+ *       <th scope="col">Description
  *   </thead>
  *   <tbody>
  *     <tr>
- *       <td>{@code "application/pdf"}
+ *       <th scope="row">{@code "application/pdf"}
  *       <td>Portable Document Format document
  *     <tr>
- *       <td>{@code "application/postscript"}
+ *       <th scope="row">{@code "application/postscript"}
  *       <td>PostScript document
  *     <tr>
- *       <td>{@code "application/vnd.hp-PCL"}
+ *       <th scope="row">{@code "application/vnd.hp-PCL"}
  *       <td>Printer Control Language document
  *   </tbody>
  *   </table>
@@ -223,18 +223,18 @@
  *   <caption>MIME-Types and their descriptions</caption>
  *   <thead>
  *     <tr>
- *       <th>MIME-Type
- *       <th>Description
+ *       <th scope="col">MIME-Type
+ *       <th scope="col">Description
  *   </thead>
  *   <tbody>
  *     <tr>
- *       <td>{@code "image/gif"}
+ *       <th scope="row">{@code "image/gif"}
  *       <td>Graphics Interchange Format image
  *     <tr>
- *       <td>{@code "image/jpeg"}
+ *       <th scope="row">{@code "image/jpeg"}
  *       <td>Joint Photographic Experts Group image
  *     <tr>
- *       <td>{@code "image/png"}
+ *       <th scope="row">{@code "image/png"}
  *       <td>Portable Network Graphics image
  *   </tbody>
  *   </table>
@@ -245,12 +245,12 @@
  *   <caption>MIME-Types and their descriptions</caption>
  *   <thead>
  *     <tr>
- *       <th>MIME-Type
- *       <th>Description
+ *       <th scope="col">MIME-Type
+ *       <th scope="col">Description
  *   </thead>
  *   <tbody>
  *     <tr>
- *       <td>{@code "application/octet-stream"}
+ *       <th scope="row">{@code "application/octet-stream"}
  *       <td>The print data format is unspecified (just an octet stream)
  *   </tbody>
  *   </table>
--- a/src/java.desktop/share/classes/javax/print/attribute/standard/Chromaticity.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/print/attribute/standard/Chromaticity.java	Wed Nov 08 16:03:35 2017 -0500
@@ -42,22 +42,23 @@
  * The table below shows the effects of specifying a Chromaticity attribute of
  * {@link #MONOCHROME MONOCHROME} or {@link #COLOR COLOR} for a monochrome or
  * color document.
+ *
  * <table class="striped">
  * <caption>Shows effects of specifying {@code MONOCHROME} or {@code COLOR}
  * Chromaticity attributes</caption>
  * <thead>
  *   <tr>
- *     <th>Chromaticity<br>Attribute
- *     <th>Effect on<br>Monochrome Document
- *     <th>Effect on<br>Color Document
+ *     <th scope="col">Chromaticity<br>Attribute
+ *     <th scope="col">Effect on<br>Monochrome Document
+ *     <th scope="col">Effect on<br>Color Document
  * </thead>
  * <tbody>
  *   <tr>
- *     <td>{@link #MONOCHROME MONOCHROME}
+ *     <th scope="row">{@link #MONOCHROME MONOCHROME}
  *     <td>Printed as is, in monochrome
  *     <td>Printed in monochrome, with colors converted to shades of gray
  *   <tr>
- *     <td>{@link #COLOR COLOR}
+ *     <th scope="row">{@link #COLOR COLOR}
  *     <td>Printed as is, in monochrome
  *     <td>Printed as is, in color
  * </tbody>
--- a/src/java.desktop/share/classes/javax/print/attribute/standard/JobKOctets.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/print/attribute/standard/JobKOctets.java	Wed Nov 08 16:03:35 2017 -0500
@@ -69,40 +69,41 @@
  * The size of a doc is computed based on the print data representation class as
  * specified by the doc's {@link javax.print.DocFlavor DocFlavor}, as shown in
  * the table below.
+ *
  * <table class="striped">
  * <caption>Table showing computation of doc sizes</caption>
  * <thead>
  *   <tr>
- *     <th>Representation Class
- *     <th>Document Size
+ *     <th scope="col">Representation Class
+ *     <th scope="col">Document Size
  * </thead>
  * <tbody>
  *   <tr>
- *     <td>{@code byte[]}
+ *     <th scope="row">{@code byte[]}
  *     <td>Length of the byte array
  *   <tr>
- *     <td>{@code java.io.InputStream}
+ *     <th scope="row">{@code java.io.InputStream}
  *     <td>Number of bytes read from the stream
  *   <tr>
- *     <td>{@code char[]}
+ *     <th scope="row">{@code char[]}
  *     <td>Length of the character array x 2
  *   <tr>
- *     <td>{@code java.lang.String}
+ *     <th scope="row">{@code java.lang.String}
  *     <td>Length of the string x 2
  *   <tr>
- *     <td>{@code java.io.Reader}
+ *     <th scope="row">{@code java.io.Reader}
  *     <td>Number of characters read from the stream x 2
  *   <tr>
- *     <td>{@code java.net.URL}
+ *     <th scope="row">{@code java.net.URL}
  *     <td>Number of bytes read from the file at the given {@code URL} address
  *   <tr>
- *     <td>{@code java.awt.image.renderable.RenderableImage}
+ *     <th scope="row">{@code java.awt.image.renderable.RenderableImage}
  *     <td>Implementation dependent&#42;
  *   <tr>
- *     <td>{@code java.awt.print.Printable}
+ *     <th scope="row">{@code java.awt.print.Printable}
  *     <td>Implementation dependent&#42;
  *   <tr>
- *     <td>{@code java.awt.print.Pageable}
+ *     <th scope="row">{@code java.awt.print.Pageable}
  *     <td>Implementation dependent&#42;
  * </tbody>
  * </table>
--- a/src/java.desktop/share/classes/javax/print/attribute/standard/PresentationDirection.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/print/attribute/standard/PresentationDirection.java	Wed Nov 08 16:03:35 2017 -0500
@@ -41,10 +41,10 @@
  * <p>
  * <b>IPP Compatibility:</b> This attribute is not an IPP 1.1 attribute; it is
  * an attribute in the Production Printing Extension
- * (<a href="ftp://ftp.pwg.org/pub/pwg/standards/pwg5100.3.pdf">PDF</a>) of IPP
- * 1.1. The category name returned by {@code getName()} is the IPP attribute
- * name. The enumeration's integer value is the IPP enum value. The
- * {@code toString()} method returns the IPP string representation of the
+ * (<a href="ftp://ftp.pwg.org/pub/pwg/standards/temp_archive/pwg5100.3.pdf">
+ * PDF</a>) of IPP 1.1. The category name returned by {@code getName()} is the
+ * IPP attribute name. The enumeration's integer value is the IPP enum value.
+ * The {@code toString()} method returns the IPP string representation of the
  * attribute value.
  *
  * @author Phil Race
--- a/src/java.desktop/share/classes/javax/print/attribute/standard/package-info.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/print/attribute/standard/package-info.java	Wed Nov 08 16:03:35 2017 -0500
@@ -150,412 +150,437 @@
  * attribute, the column marked "SupportedValuesAttribute" lists the
  * supported-values attribute class, if any, with which a print service
  * indicates the supported values for that attribute category.
- * <table border=1 cellpadding=2 cellspacing=1 summary="Lists all printing
- * attributes as described in above text">
- *   <tr style="background-color:#E5E5E5">
- *     <th valign="bottom">Attribute Class
- *     <th valign="bottom">Doc<br>Attribute
- *     <th valign="bottom">Print<br>Request<br>Attribute
- *     <th valign="bottom">Print<br>Job<br>Attribute
- *     <th valign="bottom">Print<br>Service<br>Attribute
- *     <th valign="bottom">SupportedValuesAttribute
+ *
+ * <table class="striped">
+ * <caption>Lists all printing attributes as described above</caption>
+ * <thead>
  *   <tr>
- *     <td><a href="Compression.html">Compression</a>
+ *     <th scope="col">Attribute Class
+ *     <th scope="col">Doc<br>Attribute
+ *     <th scope="col">Print<br>Request<br>Attribute
+ *     <th scope="col">Print<br>Job<br>Attribute
+ *     <th scope="col">Print<br>Service<br>Attribute
+ *     <th scope="col">SupportedValuesAttribute
+ * </thead>
+ * <tbody>
+ *   <tr>
+ *     <th scope="row"><a href="Compression.html">Compression</a>
  *     <td align="center">X
  *     <td>&nbsp;
  *     <td>&nbsp;
  *     <td>&nbsp;
  *     <td>&nbsp;
  *   <tr>
- *     <td><a href="DocumentName.html">DocumentName</a>
+ *     <th scope="row"><a href="DocumentName.html">DocumentName</a>
  *     <td align="center">X
  *     <td>&nbsp;
  *     <td>&nbsp;
  *     <td>&nbsp;
  *     <td>&nbsp;
  *   <tr>
- *     <td><a href="Chromaticity.html">Chromaticity</a>
+ *     <th scope="row"><a href="Chromaticity.html">Chromaticity</a>
  *     <td align="center">X
  *     <td align="center">X
  *     <td align="center">X
  *     <td>&nbsp;
  *     <td>&nbsp;
  *   <tr>
- *     <td><a href="Copies.html">Copies</a>
+ *     <th scope="row"><a href="Copies.html">Copies</a>
  *     <td>&nbsp;
  *     <td align="center">X
  *     <td align="center">X
  *     <td>&nbsp;
  *     <td><a href="CopiesSupported.html">CopiesSupported</a>
  *   <tr>
- *     <td><a href="Finishings.html">Finishings</a>
+ *     <th scope="row"><a href="Finishings.html">Finishings</a>
  *     <td align="center">X
  *     <td align="center">X
  *     <td align="center">X
  *     <td>&nbsp;
  *     <td>&nbsp;
  *   <tr>
- *     <td><a href="JobHoldUntil.html">JobHoldUntil</a>
+ *     <th scope="row"><a href="JobHoldUntil.html">JobHoldUntil</a>
  *     <td>&nbsp;
  *     <td align="center">X
  *     <td align="center">X
  *     <td>&nbsp;
  *     <td>&nbsp;
  *   <tr>
- *     <td><a href="JobImpressions.html">JobImpressions</a>
+ *     <th scope="row"><a href="JobImpressions.html">JobImpressions</a>
  *     <td>&nbsp;
  *     <td align="center">X
  *     <td align="center">X
  *     <td>&nbsp;
  *     <td><a href="JobImpressionsSupported.html">JobImpressionsSupported</a>
  *   <tr>
- *     <td><a href="JobKOctets.html">JobKOctets</a>
+ *     <th scope="row"><a href="JobKOctets.html">JobKOctets</a>
  *     <td>&nbsp;
  *     <td align="center">X
  *     <td align="center">X
  *     <td>&nbsp;
  *     <td><a href="JobKOctetsSupported.html">JobKOctetsSupported</a>
  *   <tr>
- *     <td><a href="JobMediaSheets.html">JobMediaSheets</a>
+ *     <th scope="row"><a href="JobMediaSheets.html">JobMediaSheets</a>
  *     <td>&nbsp;
  *     <td align="center">X
  *     <td align="center">X
  *     <td>&nbsp;
  *     <td><a href="JobMediaSheetsSupported.html">JobMediaSheetsSupported</a>
  *   <tr>
- *     <td><a href="JobName.html">JobName</a>
+ *     <th scope="row"><a href="JobName.html">JobName</a>
  *     <td>&nbsp;
  *     <td align="center">X
  *     <td align="center">X
  *     <td>&nbsp;
  *     <td>&nbsp;
  *   <tr>
- *     <td><a href="JobPriority.html">JobPriority</a>
+ *     <th scope="row"><a href="JobPriority.html">JobPriority</a>
  *     <td>&nbsp;
  *     <td align="center">X
  *     <td align="center">X
  *     <td>&nbsp;
  *     <td><a href="JobPrioritySupported.html">JobPrioritySupported</a>
  *   <tr>
- *     <td><a href="JobSheets.html">JobSheets</a>
+ *     <th scope="row"><a href="JobSheets.html">JobSheets</a>
  *     <td>&nbsp;
  *     <td align="center">X
  *     <td align="center">X
  *     <td>&nbsp;
  *     <td>&nbsp;
  *   <tr>
- *     <td><a href="Media.html">Media</a>
+ *     <th scope="row"><a href="Media.html">Media</a>
  *     <td align="center">X
  *     <td align="center">X
  *     <td align="center">X
  *     <td>&nbsp;
  *     <td>&nbsp;
  *   <tr>
- *     <td><a href="MediaSize.html">MediaSize</a>
+ *     <th scope="row"><a href="MediaSize.html">MediaSize</a>
  *     <td>&nbsp;
  *     <td>&nbsp;
  *     <td>&nbsp;
  *     <td>&nbsp;
  *     <td>&nbsp;
  *   <tr>
- *     <td><a href="MultipleDocumentHandling.html">MultipleDocumentHandling</a>
+ *     <th scope="row"><a href="MultipleDocumentHandling.html">
+ *     MultipleDocumentHandling</a>
  *     <td>&nbsp;
  *     <td align="center">X
  *     <td align="center">X
  *     <td>&nbsp;
  *     <td>&nbsp;
  *   <tr>
- *     <td><a href="NumberUp.html">NumberUp</a>
+ *     <th scope="row"><a href="NumberUp.html">NumberUp</a>
  *     <td align="center">X
  *     <td align="center">X
  *     <td align="center">X
  *     <td>&nbsp;
  *     <td><a href="NumberUpSupported.html">NumberUpSupported</a>
  *   <tr>
- *     <td><a href="OrientationRequested.html">OrientationRequested</a>
+ *     <th scope="row"><a href="OrientationRequested.html">
+ *     OrientationRequested</a>
  *     <td align="center">X
  *     <td align="center">X
  *     <td align="center">X
  *     <td>&nbsp;
  *     <td>&nbsp;
  *   <tr>
- *     <td><a href="PageRanges.html">PageRanges</a>
+ *     <th scope="row"><a href="PageRanges.html">PageRanges</a>
  *     <td align="center">X
  *     <td align="center">X
  *     <td align="center">X
  *     <td>&nbsp;
  *     <td>&nbsp;
  *   <tr>
- *     <td><a href="PresentationDirection.html">PresentationDirection</a>
+ *     <th scope="row"><a href="PresentationDirection.html">
+ *     PresentationDirection</a>
  *     <td align="center">X
  *     <td align="center">X
  *     <td align="center">X
  *     <td>&nbsp;
  *     <td>&nbsp;
  *   <tr>
- *     <td><a href="PrinterResolution.html">PrinterResolution</a>
+ *     <th scope="row"><a href="PrinterResolution.html">PrinterResolution</a>
  *     <td align="center">X
  *     <td align="center">X
  *     <td align="center">X
  *     <td>&nbsp;
  *     <td>&nbsp;
  *   <tr>
- *     <td><a href="PrintQuality.html">PrintQuality</a>
+ *     <th scope="row"><a href="PrintQuality.html">PrintQuality</a>
  *     <td align="center">X
  *     <td align="center">X
  *     <td align="center">X
  *     <td>&nbsp;
  *     <td>&nbsp;
  *   <tr>
- *     <td><a href="RequestingUserName.html">RequestingUserName</a>
+ *     <th scope="row"><a href="RequestingUserName.html">RequestingUserName</a>
  *     <td>&nbsp;
  *     <td align="center">X
  *     <td align="center">X
  *     <td>&nbsp;
  *     <td>&nbsp;
  *   <tr>
- *     <td><a href="SheetCollate.html">SheetCollate</a>
+ *     <th scope="row"><a href="SheetCollate.html">SheetCollate</a>
  *     <td align="center">X
  *     <td align="center">X
  *     <td align="center">X
  *     <td>&nbsp;
  *     <td>&nbsp;
  *   <tr>
- *     <td><a href="Sides.html">Sides</a>
+ *     <th scope="row"><a href="Sides.html">Sides</a>
  *     <td align="center">X
  *     <td align="center">X
  *     <td align="center">X
  *     <td>&nbsp;
  *     <td>&nbsp;
  *   <tr>
- *     <td><a href="DateTimeAtCompleted.html">DateTimeAtCompleted</a>
+ *     <th scope="row"><a href="DateTimeAtCompleted.html">
+ *     DateTimeAtCompleted</a>
  *     <td>&nbsp;
  *     <td>&nbsp;
  *     <td align="center">X
  *     <td>&nbsp;
  *     <td>&nbsp;
  *   <tr>
- *     <td><a href="DateTimeAtCreation.html">DateTimeAtCreation</a>
+ *     <th scope="row"><a href="DateTimeAtCreation.html">DateTimeAtCreation</a>
  *     <td>&nbsp;
  *     <td>&nbsp;
  *     <td align="center">X
  *     <td>&nbsp;
  *     <td>&nbsp;
  *   <tr>
- *     <td><a href="DateTimeAtProcessing.html">DateTimeAtProcessing</a>
+ *     <th scope="row"><a href="DateTimeAtProcessing.html">
+ *     DateTimeAtProcessing</a>
+ *     <td>&nbsp;
+ *     <td>&nbsp;
+ *     <td align="center">X
+ *     <td>&nbsp;
+ *     <td>&nbsp;
+ *   <tr>
+ *     <th scope="row"><a href="JobImpressionsCompleted.html">
+ *     JobImpressionsCompleted</a>
  *     <td>&nbsp;
  *     <td>&nbsp;
  *     <td align="center">X
  *     <td>&nbsp;
  *     <td>&nbsp;
  *   <tr>
- *     <td><a href="JobImpressionsCompleted.html">JobImpressionsCompleted</a>
+ *     <th scope="row"><a href="JobKOctetsProcessed.html">
+ *     JobKOctetsProcessed</a>
  *     <td>&nbsp;
  *     <td>&nbsp;
  *     <td align="center">X
  *     <td>&nbsp;
  *     <td>&nbsp;
  *   <tr>
- *     <td><a href="JobKOctetsProcessed.html">JobKOctetsProcessed</a>
+ *     <th scope="row"><a href="JobMediaSheetsCompleted.html">
+ *     JobMediaSheetsCompleted</a>
  *     <td>&nbsp;
  *     <td>&nbsp;
  *     <td align="center">X
  *     <td>&nbsp;
  *     <td>&nbsp;
  *   <tr>
- *     <td><a href="JobMediaSheetsCompleted.html">JobMediaSheetsCompleted</a>
+ *     <th scope="row"><a href="JobMessageFromOperator.html">
+ *     JobMessageFromOperator</a>
  *     <td>&nbsp;
  *     <td>&nbsp;
  *     <td align="center">X
  *     <td>&nbsp;
  *     <td>&nbsp;
  *   <tr>
- *     <td><a href="JobMessageFromOperator.html">JobMessageFromOperator</a>
+ *     <th scope="row"><a href="JobOriginatingUserName.html">
+ *     JobOriginatingUserName</a>
  *     <td>&nbsp;
  *     <td>&nbsp;
  *     <td align="center">X
  *     <td>&nbsp;
  *     <td>&nbsp;
  *   <tr>
- *     <td><a href="JobOriginatingUserName.html">JobOriginatingUserName</a>
+ *     <th scope="row"><a href="JobState.html">JobState</a>
  *     <td>&nbsp;
  *     <td>&nbsp;
  *     <td align="center">X
  *     <td>&nbsp;
  *     <td>&nbsp;
  *   <tr>
- *     <td><a href="JobState.html">JobState</a>
+ *     <th scope="row"><a href="JobStateReasons.html">JobStateReasons</a>
+ *     <br>
+ *     Contains zero or more --
  *     <td>&nbsp;
  *     <td>&nbsp;
  *     <td align="center">X
  *     <td>&nbsp;
  *     <td>&nbsp;
  *   <tr>
- *     <td><a href="JobStateReasons.html">JobStateReasons</a><br>
- *             Contains zero or more --
+ *     <th scope="row">-- <a href="JobStateReason.html">JobStateReason</a>
+ *     <td>&nbsp;
+ *     <td>&nbsp;
+ *     <td>&nbsp;
+ *     <td>&nbsp;
+ *     <td>&nbsp;
+ *   <tr>
+ *     <th scope="row"><a href="NumberOfDocuments.html">NumberOfDocuments</a>
  *     <td>&nbsp;
  *     <td>&nbsp;
  *     <td align="center">X
  *     <td>&nbsp;
  *     <td>&nbsp;
  *   <tr>
- *     <td>-- <a href="JobStateReason.html">JobStateReason</a>
- *     <td>&nbsp;
- *     <td>&nbsp;
- *     <td>&nbsp;
- *     <td>&nbsp;
- *     <td>&nbsp;
- *   <tr>
- *     <td><a href="NumberOfDocuments.html">NumberOfDocuments</a>
+ *     <th scope="row"><a href="NumberOfInterveningJobs.html">
+ *     NumberOfInterveningJobs</a>
  *     <td>&nbsp;
  *     <td>&nbsp;
  *     <td align="center">X
  *     <td>&nbsp;
  *     <td>&nbsp;
  *   <tr>
- *     <td><a href="NumberOfInterveningJobs.html">NumberOfInterveningJobs</a>
- *     <td>&nbsp;
- *     <td>&nbsp;
- *     <td align="center">X
- *     <td>&nbsp;
- *     <td>&nbsp;
- *   <tr>
- *     <td><a href="OutputDeviceAssigned.html">OutputDeviceAssigned</a>
+ *     <th scope="row"><a href="OutputDeviceAssigned.html">
+ *     OutputDeviceAssigned</a>
  *     <td>&nbsp;
  *     <td>&nbsp;
  *     <td align="center">X
  *     <td>&nbsp;
  *     <td>&nbsp;
  *   <tr>
- *     <td><a href="ColorSupported.html">ColorSupported</a>
+ *     <th scope="row"><a href="ColorSupported.html">ColorSupported</a>
  *     <td>&nbsp;
  *     <td>&nbsp;
  *     <td>&nbsp;
  *     <td align="center">X
  *     <td>&nbsp;
  *   <tr>
- *     <td><a href="PagesPerMinute.html">PagesPerMinute</a>
+ *     <th scope="row"><a href="PagesPerMinute.html">PagesPerMinute</a>
  *     <td>&nbsp;
  *     <td>&nbsp;
  *     <td>&nbsp;
  *     <td align="center">X
  *     <td>&nbsp;
  *   <tr>
- *     <td><a href="PagesPerMinuteColor.html">PagesPerMinuteColor</a>
+ *     <th scope="row"><a href="PagesPerMinuteColor.html">
+ *     PagesPerMinuteColor</a>
+ *     <td>&nbsp;
+ *     <td>&nbsp;
+ *     <td>&nbsp;
+ *     <td align="center">X
+ *     <td>&nbsp;
+ *   <tr>
+ *     <th scope="row"><a href="PDLOverrideSupported.html">
+ *     PDLOverrideSupported</a>
  *     <td>&nbsp;
  *     <td>&nbsp;
  *     <td>&nbsp;
  *     <td align="center">X
  *     <td>&nbsp;
  *   <tr>
- *     <td><a href="PDLOverrideSupported.html">PDLOverrideSupported</a>
+ *     <th scope="row"><a href="PrinterIsAcceptingJobs.html">
+ *     PrinterIsAcceptingJobs</a>
  *     <td>&nbsp;
  *     <td>&nbsp;
  *     <td>&nbsp;
  *     <td align="center">X
  *     <td>&nbsp;
  *   <tr>
- *     <td><a href="PrinterIsAcceptingJobs.html">PrinterIsAcceptingJobs</a>
+ *     <th scope="row"><a href="PrinterInfo.html">PrinterInfo</a>
  *     <td>&nbsp;
  *     <td>&nbsp;
  *     <td>&nbsp;
  *     <td align="center">X
  *     <td>&nbsp;
  *   <tr>
- *     <td><a href="PrinterInfo.html">PrinterInfo</a>
+ *     <th scope="row"><a href="PrinterLocation.html">PrinterLocation</a>
  *     <td>&nbsp;
  *     <td>&nbsp;
  *     <td>&nbsp;
  *     <td align="center">X
  *     <td>&nbsp;
  *   <tr>
- *     <td><a href="PrinterLocation.html">PrinterLocation</a>
+ *     <th scope="row"><a href="PrinterMessageFromOperator.html">
+ *     PrinterMessageFromOperator</a>
  *     <td>&nbsp;
  *     <td>&nbsp;
  *     <td>&nbsp;
  *     <td align="center">X
  *     <td>&nbsp;
  *   <tr>
- *     <td><a href="PrinterMessageFromOperator.html">
- *             PrinterMessageFromOperator</a>
+ *     <th scope="row"><a href="PrinterMakeAndModel.html">
+ *     PrinterMakeAndModel</a>
  *     <td>&nbsp;
  *     <td>&nbsp;
  *     <td>&nbsp;
  *     <td align="center">X
  *     <td>&nbsp;
  *   <tr>
- *     <td><a href="PrinterMakeAndModel.html">PrinterMakeAndModel</a>
+ *     <th scope="row"><a href="PrinterMoreInfo.html">PrinterMoreInfo</a>
  *     <td>&nbsp;
  *     <td>&nbsp;
  *     <td>&nbsp;
  *     <td align="center">X
  *     <td>&nbsp;
  *   <tr>
- *     <td><a href="PrinterMoreInfo.html">PrinterMoreInfo</a>
+ *     <th scope="row"><a href="PrinterMoreInfoManufacturer.html">
+ *     PrinterMoreInfoManufacturer</a>
  *     <td>&nbsp;
  *     <td>&nbsp;
  *     <td>&nbsp;
  *     <td align="center">X
  *     <td>&nbsp;
  *   <tr>
- *     <td><a href="PrinterMoreInfoManufacturer.html">
- *             PrinterMoreInfoManufacturer</a>
+ *     <th scope="row"><a href="PrinterName.html">PrinterName</a>
  *     <td>&nbsp;
  *     <td>&nbsp;
  *     <td>&nbsp;
  *     <td align="center">X
  *     <td>&nbsp;
  *   <tr>
- *     <td><a href="PrinterName.html">PrinterName</a>
+ *     <th scope="row"><a href="PrinterState.html">PrinterState</a>
  *     <td>&nbsp;
  *     <td>&nbsp;
  *     <td>&nbsp;
  *     <td align="center">X
  *     <td>&nbsp;
  *   <tr>
- *     <td><a href="PrinterState.html">PrinterState</a>
+ *     <th scope="row"><a href="PrinterStateReasons.html">
+ *     PrinterStateReasons</a>
+ *     <br>
+ *     Contains zero or more --
  *     <td>&nbsp;
  *     <td>&nbsp;
  *     <td>&nbsp;
  *     <td align="center">X
  *     <td>&nbsp;
  *   <tr>
- *     <td><a href="PrinterStateReasons.html">PrinterStateReasons</a><br>
- *             Contains zero or more --
+ *     <th scope="row">-- <a href="PrinterStateReason.html">
+ *     PrinterStateReason</a>
  *     <td>&nbsp;
  *     <td>&nbsp;
  *     <td>&nbsp;
- *     <td align="center">X
+ *     <td>&nbsp;
  *     <td>&nbsp;
  *   <tr>
- *     <td>-- <a href="PrinterStateReason.html">PrinterStateReason</a>
+ *     <th scope="row">-- <a href="Severity.html">Severity</a>
  *     <td>&nbsp;
  *     <td>&nbsp;
  *     <td>&nbsp;
  *     <td>&nbsp;
  *     <td>&nbsp;
  *   <tr>
- *     <td>-- <a href="Severity.html">Severity</a>
- *     <td>&nbsp;
- *     <td>&nbsp;
- *     <td>&nbsp;
- *     <td>&nbsp;
- *     <td>&nbsp;
- *   <tr>
- *     <td><a href="QueuedJobCount.html">QueuedJobCount</a>
+ *     <th scope="row"><a href="QueuedJobCount.html">QueuedJobCount</a>
  *     <td>&nbsp;
  *     <td>&nbsp;
  *     <td>&nbsp;
  *     <td align="center">X
  *     <td>&nbsp;
  *   <tr>
- *     <td><a href="ReferenceUriSchemesSupported.html">
- *             ReferenceUriSchemesSupported</a>
+ *     <th scope="row"><a href="ReferenceUriSchemesSupported.html">
+ *     ReferenceUriSchemesSupported</a>
  *     <td>&nbsp;
  *     <td>&nbsp;
  *     <td>&nbsp;
  *     <td>&nbsp;
  *     <td>&nbsp;
+ * </tbody>
  * </table>
  * <p>
  * Please note: In the {@code javax.print} APIs, a {@code null} reference
--- a/src/java.desktop/share/classes/javax/sound/midi/MidiFileFormat.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/sound/midi/MidiFileFormat.java	Wed Nov 08 16:03:35 2017 -0500
@@ -43,32 +43,36 @@
  * The following table lists some common properties that should be used in
  * implementations:
  *
- * <table border=1>
+ * <table class="striped">
  * <caption>MIDI File Format Properties</caption>
+ * <thead>
  *   <tr>
- *     <th>Property key
- *     <th>Value type
- *     <th>Description
+ *     <th scope="col">Property key
+ *     <th scope="col">Value type
+ *     <th scope="col">Description
+ * </thead>
+ * <tbody>
  *   <tr>
- *     <td>&quot;author&quot;
+ *     <th scope="row">"author"
  *     <td>{@link String String}
  *     <td>name of the author of this file
  *   <tr>
- *     <td>&quot;title&quot;
+ *     <th scope="row">"title"
  *     <td>{@link String String}
  *     <td>title of this file
  *   <tr>
- *     <td>&quot;copyright&quot;
+ *     <th scope="row">"copyright"
  *     <td>{@link String String}
  *     <td>copyright message
  *   <tr>
- *     <td>&quot;date&quot;
+ *     <th scope="row">"date"
  *     <td>{@link java.util.Date Date}
  *     <td>date of the recording or release
  *   <tr>
- *     <td>&quot;comment&quot;
+ *     <th scope="row">"comment"
  *     <td>{@link String String}
  *     <td>an arbitrary text
+ * </tbody>
  * </table>
  *
  * @author Kara Kytle
--- a/src/java.desktop/share/classes/javax/sound/midi/MidiSystem.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/sound/midi/MidiSystem.java	Wed Nov 08 16:03:35 2017 -0500
@@ -78,32 +78,32 @@
  * <caption>MIDI System Property Keys</caption>
  * <thead>
  *   <tr>
- *     <th>Property Key
- *     <th>Interface
- *     <th>Affected Method
+ *     <th scope="col">Property Key
+ *     <th scope="col">Interface
+ *     <th scope="col">Affected Method
  * </thead>
  * <tbody>
  *   <tr>
- *     <td>{@code javax.sound.midi.Receiver}
+ *     <th scope="row">{@code javax.sound.midi.Receiver}
  *     <td>{@link Receiver}
  *     <td>{@link #getReceiver}
  *   <tr>
- *     <td>{@code javax.sound.midi.Sequencer}
+ *     <th scope="row">{@code javax.sound.midi.Sequencer}
  *     <td>{@link Sequencer}
  *     <td>{@link #getSequencer}
  *   <tr>
- *     <td>{@code javax.sound.midi.Synthesizer}
+ *     <th scope="row">{@code javax.sound.midi.Synthesizer}
  *     <td>{@link Synthesizer}
  *     <td>{@link #getSynthesizer}
  *   <tr>
- *     <td>{@code javax.sound.midi.Transmitter}
+ *     <th scope="row">{@code javax.sound.midi.Transmitter}
  *     <td>{@link Transmitter}
  *     <td>{@link #getTransmitter}
  * </tbody>
  * </table>
  *
  * The property value consists of the provider class name and the device name,
- * separated by the hash mark (&quot;#&quot;). The provider class name is the
+ * separated by the hash mark ("#"). The provider class name is the
  * fully-qualified name of a concrete
  * {@link MidiDeviceProvider MIDI device provider} class. The device name is
  * matched against the {@code String} returned by the {@code getName} method of
--- a/src/java.desktop/share/classes/javax/sound/sampled/AudioFileFormat.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/sound/sampled/AudioFileFormat.java	Wed Nov 08 16:03:35 2017 -0500
@@ -50,36 +50,40 @@
  * The following table lists some common properties that should be used in
  * implementations:
  *
- * <table border=1>
+ * <table class="striped">
  * <caption>Audio File Format Properties</caption>
+ * <thead>
  *   <tr>
- *     <th>Property key
- *     <th>Value type
- *     <th>Description
+ *     <th scope="col">Property key
+ *     <th scope="col">Value type
+ *     <th scope="col">Description
+ * </thead>
+ * <tbody>
  *   <tr>
- *     <td>&quot;duration&quot;
+ *     <th scope="row">"duration"
  *     <td>{@link Long Long}
  *     <td>playback duration of the file in microseconds
  *   <tr>
- *     <td>&quot;author&quot;
+ *     <th scope="row">"author"
  *     <td>{@link String String}
  *     <td>name of the author of this file
  *   <tr>
- *     <td>&quot;title&quot;
+ *     <th scope="row">"title"
  *     <td>{@link String String}
  *     <td>title of this file
  *   <tr>
- *     <td>&quot;copyright&quot;
+ *     <th scope="row">"copyright"
  *     <td>{@link String String}
  *     <td>copyright message
  *   <tr>
- *     <td>&quot;date&quot;
+ *     <th scope="row">"date"
  *     <td>{@link java.util.Date Date}
  *     <td>date of the recording or release
  *   <tr>
- *     <td>&quot;comment&quot;
+ *     <th scope="row">"comment"
  *     <td>{@link String String}
  *     <td>an arbitrary text
+ * </tbody>
  * </table>
  *
  * @author David Rivas
--- a/src/java.desktop/share/classes/javax/sound/sampled/AudioFormat.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/sound/sampled/AudioFormat.java	Wed Nov 08 16:03:35 2017 -0500
@@ -94,21 +94,21 @@
  * <caption>Audio Format Properties</caption>
  * <thead>
  *   <tr>
- *     <th>Property key
- *     <th>Value type
- *     <th>Description
+ *     <th scope="col">Property key
+ *     <th scope="col">Value type
+ *     <th scope="col">Description
  * </thead>
  * <tbody>
  *   <tr>
- *     <td>&quot;bitrate&quot;
+ *     <th scope="row">"bitrate"
  *     <td>{@link java.lang.Integer Integer}
  *     <td>average bit rate in bits per second
  *   <tr>
- *     <td>&quot;vbr&quot;
+ *     <th scope="row">"vbr"
  *     <td>{@link java.lang.Boolean Boolean}
  *     <td>{@code true}, if the file is encoded in variable bit rate (VBR)
  *   <tr>
- *     <td>&quot;quality&quot;
+ *     <th scope="row">"quality"
  *     <td>{@link java.lang.Integer Integer}
  *     <td>encoding/conversion quality, 1..100
  * </tbody>
--- a/src/java.desktop/share/classes/javax/sound/sampled/AudioPermission.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/sound/sampled/AudioPermission.java	Wed Nov 08 16:03:35 2017 -0500
@@ -46,13 +46,13 @@
  * risks</caption>
  * <thead>
  *   <tr>
- *     <th>Permission Target Name
- *     <th>What the Permission Allows
- *     <th>Risks of Allowing this Permission
+ *     <th scope="col">Permission Target Name
+ *     <th scope="col">What the Permission Allows
+ *     <th scope="col">Risks of Allowing this Permission
  * </thead>
  * <tbody>
  *   <tr>
- *     <td>play
+ *     <th scope="row">play
  *     <td>Audio playback through the audio device or devices on the system.
  *     Allows the application to obtain and manipulate lines and mixers for
  *     audio playback (rendering).
@@ -61,7 +61,7 @@
  *     audio being played on the system, or because manipulation of a mixer
  *     affects the audio for all lines using that mixer.
  *   <tr>
- *     <td>record
+ *     <th scope="row">record
  *     <td>Audio recording through the audio device or devices on the system.
  *     Allows the application to obtain and manipulate lines and mixers for
  *     audio recording (capture).
--- a/src/java.desktop/share/classes/javax/sound/sampled/AudioSystem.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/sound/sampled/AudioSystem.java	Wed Nov 08 16:03:35 2017 -0500
@@ -75,32 +75,32 @@
  * <caption>Audio System Property Keys</caption>
  * <thead>
  *   <tr>
- *     <th>Property Key
- *     <th>Interface
- *     <th>Affected Method(s)
+ *     <th scope="col">Property Key
+ *     <th scope="col">Interface
+ *     <th scope="col">Affected Method(s)
  * </thead>
  * <tbody>
  *   <tr>
- *     <td>{@code javax.sound.sampled.Clip}
+ *     <th scope="row">{@code javax.sound.sampled.Clip}
  *     <td>{@link Clip}
  *     <td>{@link #getLine}, {@link #getClip}
  *   <tr>
- *     <td>{@code javax.sound.sampled.Port}
+ *     <th scope="row">{@code javax.sound.sampled.Port}
  *     <td>{@link Port}
  *     <td>{@link #getLine}
  *   <tr>
- *     <td>{@code javax.sound.sampled.SourceDataLine}
+ *     <th scope="row">{@code javax.sound.sampled.SourceDataLine}
  *     <td>{@link SourceDataLine}
  *     <td>{@link #getLine}, {@link #getSourceDataLine}
  *   <tr>
- *     <td>{@code javax.sound.sampled.TargetDataLine}
+ *     <th scope="row">{@code javax.sound.sampled.TargetDataLine}
  *     <td>{@link TargetDataLine}
  *     <td>{@link #getLine}, {@link #getTargetDataLine}
  * </tbody>
  * </table>
  *
  * The property value consists of the provider class name and the mixer name,
- * separated by the hash mark (&quot;#&quot;). The provider class name is the
+ * separated by the hash mark ("#"). The provider class name is the
  * fully-qualified name of a concrete {@link MixerProvider mixer provider}
  * class. The mixer name is matched against the {@code String} returned by the
  * {@code getName} method of {@code Mixer.Info}. Either the class name, or the
--- a/src/java.desktop/share/classes/javax/sound/sampled/ReverbType.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/sound/sampled/ReverbType.java	Wed Nov 08 16:03:35 2017 -0500
@@ -75,44 +75,44 @@
  * early intensity, and early delay</caption>
  * <thead>
  *   <tr>
- *     <th>Type
- *     <th>Decay Time (ms)
- *     <th>Late Intensity (dB)
- *     <th>Late Delay (ms)
- *     <th>Early Intensity (dB)
- *     <th>Early Delay(ms)
+ *     <th scope="col">Type
+ *     <th scope="col">Decay Time (ms)
+ *     <th scope="col">Late Intensity (dB)
+ *     <th scope="col">Late Delay (ms)
+ *     <th scope="col">Early Intensity (dB)
+ *     <th scope="col">Early Delay(ms)
  * </thead>
  * <tbody>
  *   <tr>
- *     <td>Cavern
+ *     <th scope="row">Cavern
  *     <td>2250
  *     <td>-2.0
  *     <td>41.3
  *     <td>-1.4
  *     <td>10.3
  *   <tr>
- *     <td>Dungeon
+ *     <th scope="row">Dungeon
  *     <td>1600
  *     <td>-1.0
  *     <td>10.3
  *     <td>-0.7
  *     <td>2.6
  *   <tr>
- *     <td>Garage
+ *     <th scope="row">Garage
  *     <td>900
  *     <td>-6.0
  *     <td>14.7
  *     <td>-4.0
  *     <td>3.9
  *   <tr>
- *     <td>Acoustic Lab
+ *     <th scope="row">Acoustic Lab
  *     <td>280
  *     <td>-3.0
  *     <td>8.0
  *     <td>-2.0
  *     <td>2.0
  *   <tr>
- *     <td>Closet
+ *     <th scope="row">Closet
  *     <td>150
  *     <td>-10.0
  *     <td>2.5
--- a/src/java.desktop/share/classes/javax/swing/Action.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/swing/Action.java	Wed Nov 08 16:03:35 2017 -0500
@@ -98,102 +98,88 @@
  * <caption>Supported Action properties</caption>
  * <thead>
  *  <tr>
- *    <th>Component Property
- *    <th>Components
- *    <th>Action Key
- *    <th>Notes
+ *    <th scope="col">Component Property
+ *    <th scope="col">Components
+ *    <th scope="col">Action Key
+ *    <th scope="col">Notes
  * </thead>
  * <tbody>
- *  <tr valign="top" style="text-align:left">
- *      <td><b><code>enabled</code></b>
- *      <td>All
- *      <td>The <code>isEnabled</code> method
- *      <td>&nbsp;
- *  <tr valign="top" style="text-align:left">
- *      <td><b><code>toolTipText</code></b>
- *      <td>All
- *      <td><code>SHORT_DESCRIPTION</code>
- *      <td>&nbsp;
- *  <tr valign="top" style="text-align:left">
- *      <td><b><code>actionCommand</code></b>
- *      <td>All
- *      <td><code>ACTION_COMMAND_KEY</code>
- *      <td>&nbsp;
- *  <tr valign="top" style="text-align:left">
- *      <td><b><code>mnemonic</code></b>
- *      <td>All buttons
- *      <td><code>MNEMONIC_KEY</code>
- *      <td>A <code>null</code> value or <code>Action</code> results in the
- *          button's <code>mnemonic</code> property being set to
- *          <code>'\0'</code>.
- *  <tr valign="top" style="text-align:left">
- *      <td><b><code>text</code></b>
- *      <td>All buttons
- *      <td><code>NAME</code>
- *      <td>If you do not want the text of the button to mirror that
- *          of the <code>Action</code>, set the property
- *          <code>hideActionText</code> to <code>true</code>.  If
- *          <code>hideActionText</code> is <code>true</code>, setting the
- *          <code>Action</code> changes the text of the button to
- *          <code>null</code> and any changes to <code>NAME</code>
- *          are ignored.  <code>hideActionText</code> is useful for
- *          tool bar buttons that typically only show an <code>Icon</code>.
- *          <code>JToolBar.add(Action)</code> sets the property to
- *          <code>true</code> if the <code>Action</code> has a
- *          non-<code>null</code> value for <code>LARGE_ICON_KEY</code> or
- *          <code>SMALL_ICON</code>.
- *  <tr valign="top" style="text-align:left">
- *      <td><b><code>displayedMnemonicIndex</code></b>
- *      <td>All buttons
- *      <td><code>DISPLAYED_MNEMONIC_INDEX_KEY</code>
- *      <td>If the value of <code>DISPLAYED_MNEMONIC_INDEX_KEY</code> is
- *          beyond the bounds of the text, it is ignored.  When
- *          <code>setAction</code> is called, if the value from the
- *          <code>Action</code> is <code>null</code>, the displayed
- *          mnemonic index is not updated.  In any subsequent changes to
- *          <code>DISPLAYED_MNEMONIC_INDEX_KEY</code>, <code>null</code>
- *          is treated as -1.
- *  <tr valign="top" style="text-align:left">
- *      <td><b><code>icon</code></b>
- *      <td>All buttons except of <code>JCheckBox</code>,
- *      <code>JToggleButton</code> and <code>JRadioButton</code>.
- *      <td>either <code>LARGE_ICON_KEY</code> or
- *          <code>SMALL_ICON</code>
- *     <td>The <code>JMenuItem</code> subclasses only use
- *         <code>SMALL_ICON</code>.  All other buttons will use
- *         <code>LARGE_ICON_KEY</code>; if the value is <code>null</code> they
- *         use <code>SMALL_ICON</code>.
- *  <tr valign="top" style="text-align:left">
- *      <td><b><code>accelerator</code></b>
- *      <td>All <code>JMenuItem</code> subclasses, with the exception of
- *          <code>JMenu</code>.
- *      <td><code>ACCELERATOR_KEY</code>
- *      <td>&nbsp;
- *  <tr valign="top" style="text-align:left">
- *      <td><b><code>selected</code></b>
- *      <td><code>JToggleButton</code>, <code>JCheckBox</code>,
- *          <code>JRadioButton</code>, <code>JCheckBoxMenuItem</code> and
- *          <code>JRadioButtonMenuItem</code>
- *      <td><code>SELECTED_KEY</code>
- *      <td>Components that honor this property only use
- *          the value if it is {@code non-null}. For example, if
- *          you set an {@code Action} that has a {@code null}
- *          value for {@code SELECTED_KEY} on a {@code JToggleButton}, the
- *          {@code JToggleButton} will not update it's selected state in
- *          any way. Similarly, any time the {@code JToggleButton}'s
- *          selected state changes it will only set the value back on
- *          the {@code Action} if the {@code Action} has a {@code non-null}
- *          value for {@code SELECTED_KEY}.
- *          <br>
- *          Components that honor this property keep their selected state
- *          in sync with this property. When the same {@code Action} is used
- *          with multiple components, all the components keep their selected
- *          state in sync with this property. Mutually exclusive
- *          buttons, such as {@code JToggleButton}s in a {@code ButtonGroup},
- *          force only one of the buttons to be selected. As such, do not
- *          use the same {@code Action} that defines a value for the
- *          {@code SELECTED_KEY} property with multiple mutually
- *          exclusive buttons.
+ *  <tr>
+ *    <th scope="row">{@code enabled}
+ *    <td>All
+ *    <td>The {@code isEnabled} method
+ *    <td>&nbsp;
+ *  <tr>
+ *    <th scope="row">{@code toolTipText}
+ *    <td>All
+ *    <td>{@code SHORT_DESCRIPTION}
+ *    <td>&nbsp;
+ *  <tr>
+ *    <th scope="row">{@code actionCommand}
+ *    <td>All
+ *    <td>{@code ACTION_COMMAND_KEY}
+ *    <td>&nbsp;
+ *  <tr>
+ *    <th scope="row">{@code mnemonic}
+ *    <td>All buttons
+ *    <td>{@code MNEMONIC_KEY}
+ *    <td>A {@code null} value or {@code Action} results in the button's
+ *    {@code mnemonic} property being set to {@code '\0'}.
+ *  <tr>
+ *    <th scope="row">{@code text}
+ *    <td>All buttons
+ *    <td>{@code NAME}
+ *    <td>If you do not want the text of the button to mirror that of the
+ *    {@code Action}, set the property {@code hideActionText} to {@code true}.
+ *    If {@code hideActionText} is {@code true}, setting the {@code Action}
+ *    changes the text of the button to {@code null} and any changes to
+ *    {@code NAME} are ignored. {@code hideActionText} is useful for tool bar
+ *    buttons that typically only show an {@code Icon}.
+ *    {@code JToolBar.add(Action)} sets the property to {@code true} if the
+ *    {@code Action} has a non-{@code null} value for {@code LARGE_ICON_KEY} or
+ *    {@code SMALL_ICON}.
+ *  <tr>
+ *    <th scope="row">{@code displayedMnemonicIndex}
+ *    <td>All buttons
+ *    <td>{@code DISPLAYED_MNEMONIC_INDEX_KEY}
+ *    <td>If the value of {@code DISPLAYED_MNEMONIC_INDEX_KEY} is beyond the
+ *    bounds of the text, it is ignored. When {@code setAction} is called, if
+ *    the value from the {@code Action} is {@code null}, the displayed mnemonic
+ *    index is not updated. In any subsequent changes to
+ *    {@code DISPLAYED_MNEMONIC_INDEX_KEY}, {@code null} is treated as -1.
+ *  <tr>
+ *    <th scope="row">{@code icon}
+ *    <td>All buttons except of {@code JCheckBox}, {@code JToggleButton} and
+ *    {@code JRadioButton}.
+ *    <td>either {@code LARGE_ICON_KEY} or {@code SMALL_ICON}
+ *    <td>The {@code JMenuItem} subclasses only use {@code SMALL_ICON}. All
+ *    other buttons will use {@code LARGE_ICON_KEY}; if the value is
+ *    {@code null} they use {@code SMALL_ICON}.
+ *  <tr>
+ *    <th scope="row">{@code accelerator}
+ *    <td>All {@code JMenuItem} subclasses, with the exception of {@code JMenu}.
+ *    <td>{@code ACCELERATOR_KEY}
+ *    <td>&nbsp;
+ *  <tr>
+ *    <th scope="row">{@code selected}
+ *    <td>{@code JToggleButton}, {@code JCheckBox}, {@code JRadioButton},
+ *    {@code JCheckBoxMenuItem} and {@code JRadioButtonMenuItem}
+ *    <td>{@code SELECTED_KEY}
+ *    <td>Components that honor this property only use the value if it is
+ *    {@code non-null}. For example, if you set an {@code Action} that has a
+ *    {@code null} value for {@code SELECTED_KEY} on a {@code JToggleButton},
+ *    the {@code JToggleButton} will not update it's selected state in any way.
+ *    Similarly, any time the {@code JToggleButton}'s selected state changes it
+ *    will only set the value back on the {@code Action} if the {@code Action}
+ *    has a {@code non-null} value for {@code SELECTED_KEY}.
+ *    <br>
+ *    Components that honor this property keep their selected state in sync with
+ *    this property. When the same {@code Action} is used with multiple
+ *    components, all the components keep their selected state in sync with this
+ *    property. Mutually exclusive buttons, such as {@code JToggleButton}s in a
+ *    {@code ButtonGroup}, force only one of the buttons to be selected. As
+ *    such, do not use the same {@code Action} that defines a value for the
+ *    {@code SELECTED_KEY} property with multiple mutually exclusive buttons.
  * </tbody>
  * </table>
  * <p>
--- a/src/java.desktop/share/classes/javax/swing/DefaultDesktopManager.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/swing/DefaultDesktopManager.java	Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,16 +23,22 @@
  * questions.
  */
 
-
 package javax.swing;
 
-import com.sun.awt.AWTUtilities;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.Toolkit;
+import java.awt.Window;
+import java.beans.PropertyVetoException;
+
 import sun.awt.AWTAccessor;
 import sun.awt.SunToolkit;
 
-import java.awt.*;
-import java.beans.PropertyVetoException;
-
 /** This is an implementation of the <code>DesktopManager</code>.
   * It currently implements the basic behaviors for managing
   * <code>JInternalFrame</code>s in an arbitrary parent.
@@ -315,7 +321,7 @@
         if (p != null) {
             String mode = (String)p.getClientProperty("JDesktopPane.dragMode");
             Window window = SwingUtilities.getWindowAncestor(f);
-            if (window != null && !AWTUtilities.isWindowOpaque(window)) {
+            if (window != null && !window.isOpaque()) {
                 dragMode = DEFAULT_DRAG_MODE;
             } else if (mode != null && mode.equals("outline")) {
                 dragMode = OUTLINE_DRAG_MODE;
--- a/src/java.desktop/share/classes/javax/swing/JComponent.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/swing/JComponent.java	Wed Nov 08 16:03:35 2017 -0500
@@ -121,7 +121,7 @@
  *     both of which are sections in <em>The Java Tutorial</em>.
  * </ul>
  * For more information on these subjects, see the
- * <a href="package-summary.html#package_description">Swing package description</a>
+ * {@link javax.swing Swing package description}
  * and <em>The Java Tutorial</em> section
  * <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/jcomponent.html">The JComponent Class</a>.
  * <p>
--- a/src/java.desktop/share/classes/javax/swing/JEditorPane.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/swing/JEditorPane.java	Wed Nov 08 16:03:35 2017 -0500
@@ -1914,11 +1914,13 @@
 
             /**
              * Return an object that represents the link anchor,
-             * as appropriate for that link.  E.g. from HTML:
-             *   <a href="http://www.sun.com/access">Accessibility</a>
+             * as appropriate for that link.
+             * <p>
+             * E.g. from HTML:
+             *   &lt;a href="http://openjdk.java.net"&gt;OpenJDK&lt;/a&gt;
              * this method would return a String containing the text:
-             * 'Accessibility'.
-             *
+             * 'OpenJDK'.
+             * <p>
              * Similarly, from this HTML:
              *   &lt;a HREF="#top"&gt;&lt;img src="top-hat.gif" alt="top hat"&gt;&lt;/a&gt;
              * this might return the object ImageIcon("top-hat.gif", "top hat");
--- a/src/java.desktop/share/classes/javax/swing/JFormattedTextField.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/swing/JFormattedTextField.java	Wed Nov 08 16:03:35 2017 -0500
@@ -59,27 +59,32 @@
  * <caption>Possible JFormattedTextField configurations and their descriptions
  * </caption>
  * <thead>
- * <tr><th>Value</th>
- * <th>Description</th></tr>
+ *   <tr>
+ *     <th scope="col">Value
+ *     <th scope="col">Description
  * </thead>
  * <tbody>
- * <tr><td>JFormattedTextField.REVERT
- *            <td>Revert the display to match that of <code>getValue</code>,
- *                possibly losing the current edit.
- *        <tr><td>JFormattedTextField.COMMIT
- *            <td>Commits the current value. If the value being edited
- *                isn't considered a legal value by the
- *                <code>AbstractFormatter</code> that is, a
- *                <code>ParseException</code> is thrown, then the value
- *                will not change, and then edited value will persist.
- *        <tr><td>JFormattedTextField.COMMIT_OR_REVERT
- *            <td>Similar to <code>COMMIT</code>, but if the value isn't
- *                legal, behave like <code>REVERT</code>.
- *        <tr><td>JFormattedTextField.PERSIST
- *            <td>Do nothing, don't obtain a new
- *                <code>AbstractFormatter</code>, and don't update the value.
+ *   <tr>
+ *     <th scope="row">JFormattedTextField.REVERT
+ *     <td>Revert the display to match that of {@code getValue}, possibly losing
+ *     the current edit.
+ *   <tr>
+ *     <th scope="row">JFormattedTextField.COMMIT
+ *     <td>Commits the current value. If the value being edited isn't considered
+ *     a legal value by the {@code AbstractFormatter} that is, a
+ *     {@code ParseException} is thrown, then the value will not change, and
+ *     then edited value will persist.
+ *   <tr>
+ *     <th scope="row">JFormattedTextField.COMMIT_OR_REVERT
+ *     <td>Similar to {@code COMMIT}, but if the value isn't legal, behave like
+ *     {@code REVERT}.
+ *   <tr>
+ *     <th scope="row">JFormattedTextField.PERSIST
+ *     <td>Do nothing, don't obtain a new {@code AbstractFormatter}, and don't
+ *     update the value.
  * </tbody>
  * </table>
+ *
  * The default is <code>JFormattedTextField.COMMIT_OR_REVERT</code>,
  * refer to {@link #setFocusLostBehavior} for more information on this.
  * <p>
--- a/src/java.desktop/share/classes/javax/swing/JList.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/swing/JList.java	Wed Nov 08 16:03:35 2017 -0500
@@ -968,25 +968,30 @@
      * <caption>Describes layouts VERTICAL,HORIZONTAL_WRAP, and VERTICAL_WRAP
      * </caption>
      * <thead>
-     *   <tr><th>Value</th><th>Description</th></tr>
+     *   <tr>
+     *     <th scope="col">Value
+     *     <th scope="col">Description
      * </thead>
      * <tbody>
-     *   <tr><td><code>VERTICAL</code>
-     *       <td>Cells are layed out vertically in a single column.
-     *   <tr><td><code>HORIZONTAL_WRAP</code>
-     *       <td>Cells are layed out horizontally, wrapping to a new row as
-     *           necessary. If the {@code visibleRowCount} property is less than
-     *           or equal to zero, wrapping is determined by the width of the
-     *           list; otherwise wrapping is done in such a way as to ensure
-     *           {@code visibleRowCount} rows in the list.
-     *   <tr><td><code>VERTICAL_WRAP</code>
-     *       <td>Cells are layed out vertically, wrapping to a new column as
-     *           necessary. If the {@code visibleRowCount} property is less than
-     *           or equal to zero, wrapping is determined by the height of the
-     *           list; otherwise wrapping is done at {@code visibleRowCount} rows.
+     *   <tr>
+     *     <th scope="row">{@code VERTICAL}
+     *     <td>Cells are layed out vertically in a single column.
+     *   <tr>
+     *     <th scope="row">{@code HORIZONTAL_WRAP}
+     *     <td>Cells are layed out horizontally, wrapping to a new row as
+     *     necessary. If the {@code visibleRowCount} property is less than or
+     *     equal to zero, wrapping is determined by the width of the list;
+     *     otherwise wrapping is done in such a way as to ensure
+     *     {@code visibleRowCount} rows in the list.
+     *   <tr>
+     *     <th scope="row">{@code VERTICAL_WRAP}
+     *     <td>Cells are layed out vertically, wrapping to a new column as
+     *     necessary. If the {@code visibleRowCount} property is less than or
+     *     equal to zero, wrapping is determined by the height of the list;
+     *     otherwise wrapping is done at {@code visibleRowCount} rows.
      * </tbody>
      * </table>
-     * <p>
+     *
      * The default value of this property is <code>VERTICAL</code>.
      *
      * @param layoutOrientation the new layout orientation, one of:
--- a/src/java.desktop/share/classes/javax/swing/JOptionPane.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/swing/JOptionPane.java	Wed Nov 08 16:03:35 2017 -0500
@@ -71,37 +71,30 @@
  * class may appear complex because of the large number of methods, almost
  * all uses of this class are one-line calls to one of the static
  * <code>showXxxDialog</code> methods shown below:
- * <blockquote>
  *
  * <table class="striped">
  * <caption>Common JOptionPane method names and their descriptions</caption>
  * <thead>
- * <tr>
- *    <th>Method Name</th>
- *    <th>Description</th>
- * </tr>
+ *   <tr>
+ *     <th scope="col">Method Name
+ *     <th scope="col">Description
  * </thead>
  * <tbody>
- * <tr>
- *    <td>showConfirmDialog</td>
- *    <td>Asks a confirming question, like yes/no/cancel.</td>
- * </tr>
- * <tr>
- *    <td>showInputDialog</td>
- *    <td>Prompt for some input.</td>
- * </tr>
- * <tr>
- *   <td>showMessageDialog</td>
- *   <td>Tell the user about something that has happened.</td>
- * </tr>
- * <tr>
- *   <td>showOptionDialog</td>
- *   <td>The Grand Unification of the above three.</td>
- * </tr>
+ *   <tr>
+ *     <th scope="row">showConfirmDialog
+ *     <td>Asks a confirming question, like yes/no/cancel.</td>
+ *   <tr>
+ *     <th scope="row">showInputDialog
+ *     <td>Prompt for some input.
+ *   <tr>
+ *     <th scope="row">showMessageDialog
+ *     <td>Tell the user about something that has happened.
+ *   <tr>
+ *     <th scope="row">showOptionDialog
+ *     <td>The Grand Unification of the above three.
  * </tbody>
  * </table>
  *
- * </blockquote>
  * Each of these methods also comes in a <code>showInternalXXX</code>
  * flavor, which uses an internal frame to hold the dialog box (see
  * {@link JInternalFrame}).
@@ -148,7 +141,7 @@
  * in which case a default <code>Frame</code> is used as the parent,
  * and the dialog will be
  * centered on the screen (depending on the {@literal L&F}).
- * <dt><a id=message>message</a><dd>
+ * <dt>message<dd>
  * A descriptive message to be placed in the dialog box.
  * In the most common usage, message is just a <code>String</code> or
  * <code>String</code> constant.
--- a/src/java.desktop/share/classes/javax/swing/SpinnerNumberModel.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/swing/SpinnerNumberModel.java	Wed Nov 08 16:03:35 2017 -0500
@@ -260,8 +260,7 @@
      * as the <code>value</code> however it's possible to use any
      * <code>Comparable</code> with a <code>compareTo</code>
      * method for a <code>Number</code> with the same type as the value.
-     * See <a href="#setMinimum(java.lang.Comparable)">
-     * <code>setMinimum</code></a> for an example.
+     * See {@link #setMinimum(Comparable)} for an example.
      * <p>
      * This method fires a <code>ChangeEvent</code> if the
      * <code>maximum</code> has changed.
--- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicListUI.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicListUI.java	Wed Nov 08 16:03:35 2017 -0500
@@ -588,52 +588,53 @@
      * <caption>Describes the preferred size for each layout orientation
      * </caption>
      * <thead>
-     * <tr><th>Layout Orientation</th><th>Preferred Size</th></tr>
+     *   <tr>
+     *     <th scope="col">Layout Orientation
+     *     <th scope="col">Preferred Size
      * </thead>
      * <tbody>
-     * <tr>
-     *   <td>JList.VERTICAL
-     *   <td>The preferredSize of the list is total height of the rows
-     *       and the maximum width of the cells.  If JList.fixedCellHeight
-     *       is specified then the total height of the rows is just
-     *       (cellVerticalMargins + fixedCellHeight) * model.getSize() where
-     *       rowVerticalMargins is the space we allocate for drawing
-     *       the yellow focus outline.  Similarly if fixedCellWidth is
-     *       specified then we just use that.
-     *   </td>
-     * <tr>
-     *   <td>JList.VERTICAL_WRAP
-     *   <td>If the visible row count is greater than zero, the preferredHeight
-     *       is the maximum cell height * visibleRowCount. If the visible row
-     *       count is &lt;= 0, the preferred height is either the current height
-     *       of the list, or the maximum cell height, whichever is
-     *       bigger. The preferred width is than the maximum cell width *
-     *       number of columns needed. Where the number of columns needs is
-     *       list.height / max cell height. Max cell height is either the fixed
-     *       cell height, or is determined by iterating through all the cells
-     *       to find the maximum height from the ListCellRenderer.
-     * <tr>
-     *   <td>JList.HORIZONTAL_WRAP
-     *   <td>If the visible row count is greater than zero, the preferredHeight
-     *       is the maximum cell height * adjustedRowCount.  Where
-     *       visibleRowCount is used to determine the number of columns.
-     *       Because this lays out horizontally the number of rows is
-     *       then determined from the column count.  For example, lets say
-     *       you have a model with 10 items and the visible row count is 8.
-     *       The number of columns needed to display this is 2, but you no
-     *       longer need 8 rows to display this, you only need 5, thus
-     *       the adjustedRowCount is 5.
-     *       <p>If the visible row
-     *       count is &lt;= 0, the preferred height is dictated by the
-     *       number of columns, which will be as many as can fit in the width
-     *       of the <code>JList</code> (width / max cell width), with at
-     *       least one column.  The preferred height then becomes the
-     *       model size / number of columns * maximum cell height.
-     *       Max cell height is either the fixed
-     *       cell height, or is determined by iterating through all the cells
-     *       to find the maximum height from the ListCellRenderer.
+     *   <tr>
+     *     <th scope="row">JList.VERTICAL
+     *     <td>The preferredSize of the list is total height of the rows
+     *     and the maximum width of the cells. If JList.fixedCellHeight
+     *     is specified then the total height of the rows is just
+     *     (cellVerticalMargins + fixedCellHeight) * model.getSize() where
+     *     rowVerticalMargins is the space we allocate for drawing
+     *     the yellow focus outline. Similarly if fixedCellWidth is
+     *     specified then we just use that.
+     *   <tr>
+     *     <th scope="row">JList.VERTICAL_WRAP
+     *     <td>If the visible row count is greater than zero, the preferredHeight
+     *     is the maximum cell height * visibleRowCount. If the visible row
+     *     count is &lt;= 0, the preferred height is either the current height
+     *     of the list, or the maximum cell height, whichever is
+     *     bigger. The preferred width is than the maximum cell width *
+     *     number of columns needed. Where the number of columns needs is
+     *     list.height / max cell height. Max cell height is either the fixed
+     *     cell height, or is determined by iterating through all the cells
+     *     to find the maximum height from the ListCellRenderer.
+     *   <tr>
+     *     <th scope="row">JList.HORIZONTAL_WRAP
+     *     <td>If the visible row count is greater than zero, the preferredHeight
+     *     is the maximum cell height * adjustedRowCount. Where
+     *     visibleRowCount is used to determine the number of columns.
+     *     Because this lays out horizontally the number of rows is
+     *     then determined from the column count. For example, lets say
+     *     you have a model with 10 items and the visible row count is 8.
+     *     The number of columns needed to display this is 2, but you no
+     *     longer need 8 rows to display this, you only need 5, thus
+     *     the adjustedRowCount is 5.
+     *     <p>
+     *     If the visible row count is &lt;= 0, the preferred height is dictated
+     *     by the number of columns, which will be as many as can fit in the
+     *     width of the {@code JList} (width / max cell width), with at least
+     *     one column. The preferred height then becomes the model size / number
+     *     of columns * maximum cell height. Max cell height is either the fixed
+     *     cell height, or is determined by iterating through all the cells to
+     *     find the maximum height from the ListCellRenderer.
      * </tbody>
      * </table>
+     *
      * The above specifies the raw preferred width and height. The resulting
      * preferred width is the above width + insets.left + insets.right and
      * the resulting preferred height is the above height + insets.top +
--- a/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalLookAndFeel.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalLookAndFeel.java	Wed Nov 08 16:03:35 2017 -0500
@@ -295,87 +295,87 @@
      * <caption>Metal's system color mapping</caption>
      * <thead>
      *  <tr>
-     *    <th>Key
-     *    <th>Value
+     *    <th scope="col">Key
+     *    <th scope="col">Value
      * </thead>
      * <tbody>
-     *  <tr valign="top" style="text-align:left">
-     *    <td>"desktop"
+     *  <tr>
+     *    <th scope="row">"desktop"
      *    <td>{@code theme.getDesktopColor()}
-     *  <tr valign="top" style="text-align:left">
-     *    <td>"activeCaption"
+     *  <tr>
+     *    <th scope="row">"activeCaption"
      *    <td>{@code theme.getWindowTitleBackground()}
-     *  <tr valign="top" style="text-align:left">
-     *    <td>"activeCaptionText"
+     *  <tr>
+     *    <th scope="row">"activeCaptionText"
      *    <td>{@code theme.getWindowTitleForeground()}
-     *  <tr valign="top" style="text-align:left">
-     *    <td>"activeCaptionBorder"
+     *  <tr>
+     *    <th scope="row">"activeCaptionBorder"
      *    <td>{@code theme.getPrimaryControlShadow()}
-     *  <tr valign="top" style="text-align:left">
-     *    <td>"inactiveCaption"
+     *  <tr>
+     *    <th scope="row">"inactiveCaption"
      *    <td>{@code theme.getWindowTitleInactiveBackground()}
-     *  <tr valign="top" style="text-align:left">
-     *    <td>"inactiveCaptionText"
+     *  <tr>
+     *    <th scope="row">"inactiveCaptionText"
      *    <td>{@code theme.getWindowTitleInactiveForeground()}
-     *  <tr valign="top" style="text-align:left">
-     *    <td>"inactiveCaptionBorder"
+     *  <tr>
+     *    <th scope="row">"inactiveCaptionBorder"
      *    <td>{@code theme.getControlShadow()}
-     *  <tr valign="top" style="text-align:left">
-     *    <td>"window"
+     *  <tr>
+     *    <th scope="row">"window"
      *    <td>{@code theme.getWindowBackground()}
-     *  <tr valign="top" style="text-align:left">
-     *    <td>"windowBorder"
+     *  <tr>
+     *    <th scope="row">"windowBorder"
      *    <td>{@code theme.getControl()}
-     *  <tr valign="top" style="text-align:left">
-     *    <td>"windowText"
+     *  <tr>
+     *    <th scope="row">"windowText"
      *    <td>{@code theme.getUserTextColor()}
-     *  <tr valign="top" style="text-align:left">
-     *    <td>"menu"
+     *  <tr>
+     *    <th scope="row">"menu"
      *    <td>{@code theme.getMenuBackground()}
-     *  <tr valign="top" style="text-align:left">
-     *    <td>"menuText"
+     *  <tr>
+     *    <th scope="row">"menuText"
      *    <td>{@code theme.getMenuForeground()}
-     *  <tr valign="top" style="text-align:left">
-     *    <td>"text"
+     *  <tr>
+     *    <th scope="row">"text"
      *    <td>{@code theme.getWindowBackground()}
-     *  <tr valign="top" style="text-align:left">
-     *    <td>"textText"
+     *  <tr>
+     *    <th scope="row">"textText"
      *    <td>{@code theme.getUserTextColor()}
-     *  <tr valign="top" style="text-align:left">
-     *    <td>"textHighlight"
+     *  <tr>
+     *    <th scope="row">"textHighlight"
      *    <td>{@code theme.getTextHighlightColor()}
-     *  <tr valign="top" style="text-align:left">
-     *    <td>"textHighlightText"
+     *  <tr>
+     *    <th scope="row">"textHighlightText"
      *    <td>{@code theme.getHighlightedTextColor()}
-     *  <tr valign="top" style="text-align:left">
-     *    <td>"textInactiveText"
+     *  <tr>
+     *    <th scope="row">"textInactiveText"
      *    <td>{@code theme.getInactiveSystemTextColor()}
-     *  <tr valign="top" style="text-align:left">
-     *    <td>"control"
+     *  <tr>
+     *    <th scope="row">"control"
      *    <td>{@code theme.getControl()}
-     *  <tr valign="top" style="text-align:left">
-     *    <td>"controlText"
+     *  <tr>
+     *    <th scope="row">"controlText"
      *    <td>{@code theme.getControlTextColor()}
-     *  <tr valign="top" style="text-align:left">
-     *    <td>"controlHighlight"
+     *  <tr>
+     *    <th scope="row">"controlHighlight"
      *    <td>{@code theme.getControlHighlight()}
-     *  <tr valign="top" style="text-align:left">
-     *    <td>"controlLtHighlight"
+     *  <tr>
+     *    <th scope="row">"controlLtHighlight"
      *    <td>{@code theme.getControlHighlight()}
-     *  <tr valign="top" style="text-align:left">
-     *    <td>"controlShadow"
+     *  <tr>
+     *    <th scope="row">"controlShadow"
      *    <td>{@code theme.getControlShadow()}
-     *  <tr valign="top" style="text-align:left">
-     *    <td>"controlDkShadow"
+     *  <tr>
+     *    <th scope="row">"controlDkShadow"
      *    <td>{@code theme.getControlDarkShadow()}
-     *  <tr valign="top" style="text-align:left">
-     *    <td>"scrollbar"
+     *  <tr>
+     *    <th scope="row">"scrollbar"
      *    <td>{@code theme.getControl()}
-     *  <tr valign="top" style="text-align:left">
-     *    <td>"info"
+     *  <tr>
+     *    <th scope="row">"info"
      *    <td>{@code theme.getPrimaryControl()}
-     *  <tr valign="top" style="text-align:left">
-     *    <td>"infoText"
+     *  <tr>
+     *    <th scope="row">"infoText"
      *    <td>{@code theme.getPrimaryControlInfo()}
      * </tbody>
      * </table>
--- a/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalTreeUI.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalTreeUI.java	Wed Nov 08 16:03:35 2017 -0500
@@ -47,24 +47,25 @@
  * <table class="striped">
  * <caption>Descriptions of supported hints: Angled, Horizontal, and None
  * </caption>
- *  <tr>
- *    <th>Angled</th>
- *    <td>A line is drawn connecting the child to the parent. For handling
- *          of the root node refer to
- *          {@link javax.swing.JTree#setRootVisible} and
- *          {@link javax.swing.JTree#setShowsRootHandles}.
- *    </td>
- *  </tr>
- *  <tr>
- *     <th>Horizontal</th>
- *     <td>A horizontal line is drawn dividing the children of the root node.</td>
- *  </tr>
- *  <tr>
- *      <th>None</th>
- *      <td>Do not draw any visual indication between nodes.</td>
- *  </tr>
+ * <thead>
+ *   <tr>
+ *     <th scope="col">Hint
+ *     <th scope="col">Description
+ * </thead>
+ * <tbody>
+ *   <tr>
+ *     <th scope="row">Angled
+ *     <td>A line is drawn connecting the child to the parent. For handling of
+ *     the root node refer to {@link JTree#setRootVisible} and
+ *     {@link JTree#setShowsRootHandles}.
+ *   <tr>
+ *     <th scope="row">Horizontal
+ *     <td>A horizontal line is drawn dividing the children of the root node.
+ *   <tr>
+ *     <th scope="row">None
+ *     <td>Do not draw any visual indication between nodes.
+ * </tbody>
  * </table>
- *
  * <p>
  * As it is typically impractical to obtain the <code>TreeUI</code> from
  * the <code>JTree</code> and cast to an instance of <code>MetalTreeUI</code>
--- a/src/java.desktop/share/classes/javax/swing/text/DefaultCaret.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/swing/text/DefaultCaret.java	Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -352,6 +352,7 @@
                 setVisible(true);
             }
             setSelectionVisible(true);
+            updateSystemSelection();
         }
     }
 
@@ -365,7 +366,9 @@
      */
     public void focusLost(FocusEvent e) {
         setVisible(false);
-        setSelectionVisible(ownsSelection || e.isTemporary());
+        setSelectionVisible((e.getCause() == FocusEvent.Cause.ACTIVATION ||
+                e.getOppositeComponent() instanceof JRootPane) &&
+                (ownsSelection || e.isTemporary()));
     }
 
 
@@ -866,7 +869,6 @@
                     Highlighter.HighlightPainter p = getSelectionPainter();
                     try {
                         selectionTag = h.addHighlight(p0, p1, p);
-                        updateOwnsSelection();
                     } catch (BadLocationException bl) {
                         selectionTag = null;
                     }
@@ -877,7 +879,6 @@
                     Highlighter h = component.getHighlighter();
                     h.removeHighlight(selectionTag);
                     selectionTag = null;
-                    updateOwnsSelection();
                 }
             }
         }
@@ -1119,7 +1120,6 @@
                     if (selectionTag != null) {
                         h.removeHighlight(selectionTag);
                         selectionTag = null;
-                        updateOwnsSelection();
                     }
                 // otherwise, change or add the highlight
                 } else {
@@ -1130,7 +1130,6 @@
                             Highlighter.HighlightPainter p = getSelectionPainter();
                             selectionTag = h.addHighlight(p0, p1, p);
                         }
-                        updateOwnsSelection();
                     } catch (BadLocationException e) {
                         throw new StateInvariantError("Bad caret position");
                     }
@@ -1181,7 +1180,6 @@
         if (this.dot != dot || this.dotBias != dotBias ||
             selectionTag != null || forceCaretPositionChange) {
             changeCaretPosition(dot, dotBias);
-            updateOwnsSelection();
         }
         this.markBias = this.dotBias;
         this.markLTR = dotLTR;
@@ -1189,7 +1187,6 @@
         if ((h != null) && (selectionTag != null)) {
             h.removeHighlight(selectionTag);
             selectionTag = null;
-            updateOwnsSelection();
         }
     }
 
@@ -1940,13 +1937,6 @@
         }
     }
 
-    /**
-     * Updates ownsSelection based on text selection in the caret.
-     */
-    private void updateOwnsSelection() {
-        ownsSelection = (selectionTag != null)
-                && SwingUtilities2.canAccessSystemClipboard();
-    }
 
     private class DefaultFilterBypass extends NavigationFilter.FilterBypass {
         public Caret getCaret() {
--- a/src/java.desktop/share/classes/javax/swing/text/Document.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/swing/text/Document.java	Wed Nov 08 16:03:35 2017 -0500
@@ -146,10 +146,10 @@
  * <p>
  * The methods related to observing mutations to the document are:
  * <ul>
- * <li><a href="#addDocumentListener(javax.swing.event.DocumentListener)">addDocumentListener(DocumentListener)</a>
- * <li><a href="#removeDocumentListener(javax.swing.event.DocumentListener)">removeDocumentListener(DocumentListener)</a>
- * <li><a href="#addUndoableEditListener(javax.swing.event.UndoableEditListener)">addUndoableEditListener(UndoableEditListener)</a>
- * <li><a href="#removeUndoableEditListener(javax.swing.event.UndoableEditListener)">removeUndoableEditListener(UndoableEditListener)</a>
+ *   <li>{@link #addDocumentListener(DocumentListener)}
+ *   <li>{@link #removeDocumentListener(DocumentListener)}
+ *   <li>{@link #addUndoableEditListener(UndoableEditListener)}
+ *   <li>{@link #removeUndoableEditListener(UndoableEditListener)}
  * </ul>
  *
  * <p><b>Properties</b>
--- a/src/java.desktop/share/classes/javax/swing/text/JTextComponent.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/swing/text/JTextComponent.java	Wed Nov 08 16:03:35 2017 -0500
@@ -160,34 +160,39 @@
  * <table class="striped">
  * <caption>Stages of keyboard and input method event handling</caption>
  * <thead>
- * <tr>
- * <th id="stage">Stage</th>
- * <th id="ke">KeyEvent</th>
- * <th id="ime">InputMethodEvent</th></tr>
+ *   <tr>
+ *     <th scope="col">Stage
+ *     <th scope="col">KeyEvent
+ *     <th scope="col">InputMethodEvent
  * </thead>
  * <tbody>
- * <tr><td headers="stage">1.   </td>
- *     <td headers="ke">input methods </td>
- *     <td headers="ime">(generated here)</td></tr>
- * <tr><td headers="stage">2.   </td>
- *     <td headers="ke">focus manager </td>
- *     <td headers="ime"></td>
- * </tr>
- * <tr>
- *     <td headers="stage">3.   </td>
- *     <td headers="ke">registered key listeners</td>
- *     <td headers="ime">registered input method listeners</tr>
- * <tr>
- *     <td headers="stage">4.   </td>
- *     <td headers="ke"></td>
- *     <td headers="ime">input method handling in JTextComponent</tr>
- * <tr>
- *     <td headers="stage">5.   </td><td headers="ke ime" colspan=2>keymap handling using the current keymap</td></tr>
- * <tr><td headers="stage">6.   </td><td headers="ke">keyboard handling in JComponent (e.g. accelerators, component navigation, etc.)</td>
- *     <td headers="ime"></td></tr>
+ *   <tr>
+ *     <th scope="row">1.
+ *     <td>input methods
+ *     <td>(generated here)
+ *   <tr>
+ *     <th scope="row" headers="stage">2.
+ *     <td>focus manager
+ *     <td>
+ *   </tr>
+ *   <tr>
+ *     <th scope="row">3.
+ *     <td>registered key listeners
+ *     <td>registered input method listeners
+ *   <tr>
+ *     <th scope="row">4.
+ *     <td>
+ *     <td>input method handling in JTextComponent
+ *   <tr>
+ *     <th scope="row">5.
+ *     <td colspan=2>keymap handling using the current keymap
+ *   <tr>
+ *     <th scope="row">6.
+ *     <td>keyboard handling in JComponent (e.g. accelerators, component
+ *     navigation, etc.)
+ *     <td>
  * </tbody>
  * </table>
- *
  * <p>
  * To maintain compatibility with applications that listen to key
  * events but are not aware of input method events, the input
--- a/src/java.desktop/share/classes/javax/swing/text/MaskFormatter.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/swing/text/MaskFormatter.java	Wed Nov 08 16:03:35 2017 -0500
@@ -40,36 +40,39 @@
  * <table class="striped">
  * <caption>Valid characters and their descriptions</caption>
  * <thead>
- * <tr>
- *    <th>Character&nbsp;</th>
- *    <th>Description</th>
- * </tr>
+ *   <tr>
+ *     <th scope="col">Character
+ *     <th scope="col">Description
  * </thead>
  * <tbody>
- * <tr>
- *    <td>#</td>
- *    <td>Any valid number, uses <code>Character.isDigit</code>.</td>
- * </tr>
- * <tr>
- *    <td>'</td>
- *    <td>Escape character, used to escape any of the
- *       special formatting characters.</td>
- * </tr>
- * <tr>
- *    <td>U</td><td>Any character (<code>Character.isLetter</code>). All
- *        lowercase letters are mapped to upper case.</td>
- * </tr>
- * <tr><td>L</td><td>Any character (<code>Character.isLetter</code>). All
- *        upper case letters are mapped to lower case.</td>
- * </tr>
- * <tr><td>A</td><td>Any character or number (<code>Character.isLetter</code>
- *       or <code>Character.isDigit</code>)</td>
- * </tr>
- * <tr><td>?</td><td>Any character
- *        (<code>Character.isLetter</code>).</td>
- * </tr>
- * <tr><td>*</td><td>Anything.</td></tr>
- * <tr><td>H</td><td>Any hex character (0-9, a-f or A-F).</td></tr>
+ *   <tr>
+ *     <th scope="row">#
+ *     <td>Any valid number, uses {@code Character.isDigit}.
+ *   <tr>
+ *     <th scope="row">'
+ *     <td>Escape character, used to escape any of the special formatting
+ *     characters.
+ *   <tr>
+ *     <th scope="row">U
+ *     <td>Any character ({@code Character.isLetter}). All lowercase letters are
+ *     mapped to upper case.
+ *   <tr>
+ *     <th scope="row">L
+ *     <td>Any character ({@code Character.isLetter}). All upper case letters
+ *     are mapped to lower case.
+ *   <tr>
+ *     <th scope="row">A
+ *     <td>Any character or number ({@code Character.isLetter} or
+ *     {@code Character.isDigit}).
+ *   <tr>
+ *     <th scope="row">?
+ *     <td>Any character ({@code Character.isLetter}).
+ *   <tr>
+ *     <th scope="row">*
+ *     <td>Anything.
+ *   <tr>
+ *     <th scope="row">H
+ *     <td>Any hex character (0-9, a-f or A-F).
  * </tbody>
  * </table>
  *
--- a/src/java.desktop/share/classes/javax/swing/text/html/FormView.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/swing/text/html/FormView.java	Wed Nov 08 16:03:35 2017 -0500
@@ -50,60 +50,47 @@
  * <table class="striped">
  * <caption>Shows what components get built by this view</caption>
  * <thead>
- * <tr>
- *   <th>Element Type</th>
- *   <th>Component built</th>
- * </tr>
+ *   <tr>
+ *     <th scope="col">Element Type
+ *     <th scope="col">Component built
  * </thead>
  * <tbody>
- * <tr>
- *   <td>input, type button</td>
- *   <td>JButton</td>
- * </tr>
- * <tr>
- *   <td>input, type checkbox</td>
- *   <td>JCheckBox</td>
- * </tr>
- * <tr>
- *   <td>input, type image</td>
- *   <td>JButton</td>
- * </tr>
- * <tr>
- *   <td>input, type password</td>
- *   <td>JPasswordField</td>
- * </tr>
- * <tr>
- *   <td>input, type radio</td>
- *   <td>JRadioButton</td>
- * </tr>
- * <tr>
- *   <td>input, type reset</td>
- *   <td>JButton</td>
- * </tr>
- * <tr>
- *   <td>input, type submit</td>
- *   <td>JButton</td>
- * </tr>
- * <tr>
- *   <td>input, type text</td>
- *   <td>JTextField</td>
- * </tr>
- * <tr>
- *   <td>select, size &gt; 1 or multiple attribute defined</td>
- *   <td>JList in a JScrollPane</td>
- * </tr>
- * <tr>
- *   <td>select, size unspecified or 1</td>
- *   <td>JComboBox</td>
- * </tr>
- * <tr>
- *   <td>textarea</td>
- *   <td>JTextArea in a JScrollPane</td>
- * </tr>
- * <tr>
- *   <td>input, type file</td>
- *   <td>JTextField</td>
- * </tr>
+ *   <tr>
+ *     <th scope="row">input, type button
+ *     <td>JButton
+ *   <tr>
+ *     <th scope="row">input, type checkbox
+ *     <td>JCheckBox
+ *   <tr>
+ *     <th scope="row">input, type image
+ *     <td>JButton
+ *   <tr>
+ *     <th scope="row">input, type password
+ *     <td>JPasswordField
+ *   <tr>
+ *     <th scope="row">input, type radio
+ *     <td>JRadioButton
+ *   <tr>
+ *     <th scope="row">input, type reset
+ *     <td>JButton
+ *   <tr>
+ *     <th scope="row">input, type submit
+ *     <td>JButton
+ *   <tr>
+ *     <th scope="row">input, type text
+ *     <td>JTextField
+ *   <tr>
+ *     <th scope="row">select, size &gt; 1 or multiple attribute defined
+ *     <td>JList in a JScrollPane
+ *   <tr>
+ *     <th scope="row">select, size unspecified or 1
+ *     <td>JComboBox
+ *   <tr>
+ *     <th scope="row">textarea
+ *     <td>JTextArea in a JScrollPane
+ *   <tr>
+ *     <th scope="row">input, type file
+ *     <td>JTextField
  * </tbody>
  * </table>
  *
--- a/src/java.desktop/share/classes/javax/swing/text/html/HTMLDocument.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/swing/text/html/HTMLDocument.java	Wed Nov 08 16:03:35 2017 -0500
@@ -2134,81 +2134,227 @@
      * <table class="striped">
      * <caption>HTML tags and assigned actions</caption>
      * <thead>
-     * <tr><th>Tag</th><th>Action</th></tr>
+     *   <tr>
+     *     <th scope="col">Tag
+     *     <th scope="col">Action
      * </thead>
      * <tbody>
-     * <tr><td><code>HTML.Tag.A</code>         <td>CharacterAction
-     * <tr><td><code>HTML.Tag.ADDRESS</code>   <td>CharacterAction
-     * <tr><td><code>HTML.Tag.APPLET</code>    <td>HiddenAction
-     * <tr><td><code>HTML.Tag.AREA</code>      <td>AreaAction
-     * <tr><td><code>HTML.Tag.B</code>         <td>CharacterAction
-     * <tr><td><code>HTML.Tag.BASE</code>      <td>BaseAction
-     * <tr><td><code>HTML.Tag.BASEFONT</code>  <td>CharacterAction
-     * <tr><td><code>HTML.Tag.BIG</code>       <td>CharacterAction
-     * <tr><td><code>HTML.Tag.BLOCKQUOTE</code><td>BlockAction
-     * <tr><td><code>HTML.Tag.BODY</code>      <td>BlockAction
-     * <tr><td><code>HTML.Tag.BR</code>        <td>SpecialAction
-     * <tr><td><code>HTML.Tag.CAPTION</code>   <td>BlockAction
-     * <tr><td><code>HTML.Tag.CENTER</code>    <td>BlockAction
-     * <tr><td><code>HTML.Tag.CITE</code>      <td>CharacterAction
-     * <tr><td><code>HTML.Tag.CODE</code>      <td>CharacterAction
-     * <tr><td><code>HTML.Tag.DD</code>        <td>BlockAction
-     * <tr><td><code>HTML.Tag.DFN</code>       <td>CharacterAction
-     * <tr><td><code>HTML.Tag.DIR</code>       <td>BlockAction
-     * <tr><td><code>HTML.Tag.DIV</code>       <td>BlockAction
-     * <tr><td><code>HTML.Tag.DL</code>        <td>BlockAction
-     * <tr><td><code>HTML.Tag.DT</code>        <td>ParagraphAction
-     * <tr><td><code>HTML.Tag.EM</code>        <td>CharacterAction
-     * <tr><td><code>HTML.Tag.FONT</code>      <td>CharacterAction
-     * <tr><td><code>HTML.Tag.FORM</code>      <td>As of 1.4 a BlockAction
-     * <tr><td><code>HTML.Tag.FRAME</code>     <td>SpecialAction
-     * <tr><td><code>HTML.Tag.FRAMESET</code>  <td>BlockAction
-     * <tr><td><code>HTML.Tag.H1</code>        <td>ParagraphAction
-     * <tr><td><code>HTML.Tag.H2</code>        <td>ParagraphAction
-     * <tr><td><code>HTML.Tag.H3</code>        <td>ParagraphAction
-     * <tr><td><code>HTML.Tag.H4</code>        <td>ParagraphAction
-     * <tr><td><code>HTML.Tag.H5</code>        <td>ParagraphAction
-     * <tr><td><code>HTML.Tag.H6</code>        <td>ParagraphAction
-     * <tr><td><code>HTML.Tag.HEAD</code>      <td>HeadAction
-     * <tr><td><code>HTML.Tag.HR</code>        <td>SpecialAction
-     * <tr><td><code>HTML.Tag.HTML</code>      <td>BlockAction
-     * <tr><td><code>HTML.Tag.I</code>         <td>CharacterAction
-     * <tr><td><code>HTML.Tag.IMG</code>       <td>SpecialAction
-     * <tr><td><code>HTML.Tag.INPUT</code>     <td>FormAction
-     * <tr><td><code>HTML.Tag.ISINDEX</code>   <td>IsndexAction
-     * <tr><td><code>HTML.Tag.KBD</code>       <td>CharacterAction
-     * <tr><td><code>HTML.Tag.LI</code>        <td>BlockAction
-     * <tr><td><code>HTML.Tag.LINK</code>      <td>LinkAction
-     * <tr><td><code>HTML.Tag.MAP</code>       <td>MapAction
-     * <tr><td><code>HTML.Tag.MENU</code>      <td>BlockAction
-     * <tr><td><code>HTML.Tag.META</code>      <td>MetaAction
-     * <tr><td><code>HTML.Tag.NOFRAMES</code>  <td>BlockAction
-     * <tr><td><code>HTML.Tag.OBJECT</code>    <td>SpecialAction
-     * <tr><td><code>HTML.Tag.OL</code>        <td>BlockAction
-     * <tr><td><code>HTML.Tag.OPTION</code>    <td>FormAction
-     * <tr><td><code>HTML.Tag.P</code>         <td>ParagraphAction
-     * <tr><td><code>HTML.Tag.PARAM</code>     <td>HiddenAction
-     * <tr><td><code>HTML.Tag.PRE</code>       <td>PreAction
-     * <tr><td><code>HTML.Tag.SAMP</code>      <td>CharacterAction
-     * <tr><td><code>HTML.Tag.SCRIPT</code>    <td>HiddenAction
-     * <tr><td><code>HTML.Tag.SELECT</code>    <td>FormAction
-     * <tr><td><code>HTML.Tag.SMALL</code>     <td>CharacterAction
-     * <tr><td><code>HTML.Tag.STRIKE</code>    <td>CharacterAction
-     * <tr><td><code>HTML.Tag.S</code>         <td>CharacterAction
-     * <tr><td><code>HTML.Tag.STRONG</code>    <td>CharacterAction
-     * <tr><td><code>HTML.Tag.STYLE</code>     <td>StyleAction
-     * <tr><td><code>HTML.Tag.SUB</code>       <td>CharacterAction
-     * <tr><td><code>HTML.Tag.SUP</code>       <td>CharacterAction
-     * <tr><td><code>HTML.Tag.TABLE</code>     <td>BlockAction
-     * <tr><td><code>HTML.Tag.TD</code>        <td>BlockAction
-     * <tr><td><code>HTML.Tag.TEXTAREA</code>  <td>FormAction
-     * <tr><td><code>HTML.Tag.TH</code>        <td>BlockAction
-     * <tr><td><code>HTML.Tag.TITLE</code>     <td>TitleAction
-     * <tr><td><code>HTML.Tag.TR</code>        <td>BlockAction
-     * <tr><td><code>HTML.Tag.TT</code>        <td>CharacterAction
-     * <tr><td><code>HTML.Tag.U</code>         <td>CharacterAction
-     * <tr><td><code>HTML.Tag.UL</code>        <td>BlockAction
-     * <tr><td><code>HTML.Tag.VAR</code>       <td>CharacterAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.A}
+     *     <td>CharacterAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.ADDRESS}
+     *     <td>CharacterAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.APPLET}
+     *     <td>HiddenAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.AREA}
+     *     <td>AreaAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.B}
+     *     <td>CharacterAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.BASE}
+     *     <td>BaseAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.BASEFONT}
+     *     <td>CharacterAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.BIG}
+     *     <td>CharacterAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.BLOCKQUOTE}
+     *     <td>BlockAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.BODY}
+     *     <td>BlockAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.BR}
+     *     <td>SpecialAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.CAPTION}
+     *     <td>BlockAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.CENTER}
+     *     <td>BlockAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.CITE}
+     *     <td>CharacterAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.CODE}
+     *     <td>CharacterAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.DD}
+     *     <td>BlockAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.DFN}
+     *     <td>CharacterAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.DIR}
+     *     <td>BlockAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.DIV}
+     *     <td>BlockAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.DL}
+     *     <td>BlockAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.DT}
+     *     <td>ParagraphAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.EM}
+     *     <td>CharacterAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.FONT}
+     *     <td>CharacterAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.FORM}
+     *     <td>As of 1.4 a BlockAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.FRAME}
+     *     <td>SpecialAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.FRAMESET}
+     *     <td>BlockAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.H1}
+     *     <td>ParagraphAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.H2}
+     *     <td>ParagraphAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.H3}
+     *     <td>ParagraphAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.H4}
+     *     <td>ParagraphAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.H5}
+     *     <td>ParagraphAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.H6}
+     *     <td>ParagraphAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.HEAD}
+     *     <td>HeadAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.HR}
+     *     <td>SpecialAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.HTML}
+     *     <td>BlockAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.I}
+     *     <td>CharacterAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.IMG}
+     *     <td>SpecialAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.INPUT}
+     *     <td>FormAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.ISINDEX}
+     *     <td>IsndexAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.KBD}
+     *     <td>CharacterAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.LI}
+     *     <td>BlockAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.LINK}
+     *     <td>LinkAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.MAP}
+     *     <td>MapAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.MENU}
+     *     <td>BlockAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.META}
+     *     <td>MetaAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.NOFRAMES}
+     *     <td>BlockAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.OBJECT}
+     *     <td>SpecialAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.OL}
+     *     <td>BlockAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.OPTION}
+     *     <td>FormAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.P}
+     *     <td>ParagraphAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.PARAM}
+     *     <td>HiddenAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.PRE}
+     *     <td>PreAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.SAMP}
+     *     <td>CharacterAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.SCRIPT}
+     *     <td>HiddenAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.SELECT}
+     *     <td>FormAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.SMALL}
+     *     <td>CharacterAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.STRIKE}
+     *     <td>CharacterAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.S}
+     *     <td>CharacterAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.STRONG}
+     *     <td>CharacterAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.STYLE}
+     *     <td>StyleAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.SUB}
+     *     <td>CharacterAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.SUP}
+     *     <td>CharacterAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.TABLE}
+     *     <td>BlockAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.TD}
+     *     <td>BlockAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.TEXTAREA}
+     *     <td>FormAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.TH}
+     *     <td>BlockAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.TITLE}
+     *     <td>TitleAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.TR}
+     *     <td>BlockAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.TT}
+     *     <td>CharacterAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.U}
+     *     <td>CharacterAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.UL}
+     *     <td>BlockAction
+     *   <tr>
+     *     <th scope="row">{@code HTML.Tag.VAR}
+     *     <td>CharacterAction
      * </tbody>
      * </table>
      * <p>
@@ -3397,45 +3543,44 @@
          * <caption>Model assignments for the various types of form elements
          * </caption>
          * <thead>
-         * <tr>
-         *   <th>Element Type
-         *   <th>Model Type
-         * </tr>
+         *   <tr>
+         *     <th scope="col">Element Type
+         *     <th scope="col">Model Type
          * </thead>
          * <tbody>
-         * <tr>
-         *   <td>input, type button
-         *   <td>{@link DefaultButtonModel}
-         * <tr>
-         *   <td>input, type checkbox
-         *   <td>{@link javax.swing.JToggleButton.ToggleButtonModel}
-         * <tr>
-         *   <td>input, type image
-         *   <td>{@link DefaultButtonModel}
-         * <tr>
-         *   <td>input, type password
-         *   <td>{@link PlainDocument}
-         * <tr>
-         *   <td>input, type radio
-         *   <td>{@link javax.swing.JToggleButton.ToggleButtonModel}
-         * <tr>
-         *   <td>input, type reset
-         *   <td>{@link DefaultButtonModel}
-         * <tr>
-         *   <td>input, type submit
-         *   <td>{@link DefaultButtonModel}
-         * <tr>
-         *   <td>input, type text or type is null.
-         *   <td>{@link PlainDocument}
-         * <tr>
-         *   <td>select
-         *   <td>{@link DefaultComboBoxModel} or an {@link DefaultListModel}, with an item type of Option
-         * <tr>
-         *   <td>textarea
-         *   <td>{@link PlainDocument}
+         *   <tr>
+         *     <th scope="row">input, type button
+         *     <td>{@link DefaultButtonModel}
+         *   <tr>
+         *     <th scope="row">input, type checkbox
+         *     <td>{@link JToggleButton.ToggleButtonModel}
+         *   <tr>
+         *     <th scope="row">input, type image
+         *     <td>{@link DefaultButtonModel}
+         *   <tr>
+         *     <th scope="row">input, type password
+         *     <td>{@link PlainDocument}
+         *   <tr>
+         *     <th scope="row">input, type radio
+         *     <td>{@link JToggleButton.ToggleButtonModel}
+         *   <tr>
+         *     <th scope="row">input, type reset
+         *     <td>{@link DefaultButtonModel}
+         *   <tr>
+         *     <th scope="row">input, type submit
+         *     <td>{@link DefaultButtonModel}
+         *   <tr>
+         *     <th scope="row">input, type text or type is null.
+         *     <td>{@link PlainDocument}
+         *   <tr>
+         *     <th scope="row">select
+         *     <td>{@link DefaultComboBoxModel} or an {@link DefaultListModel},
+         *     with an item type of Option
+         *   <tr>
+         *     <td>textarea
+         *     <td>{@link PlainDocument}
          * </tbody>
          * </table>
-         *
          */
         public class FormAction extends SpecialAction {
 
--- a/src/java.desktop/share/classes/javax/swing/text/html/HTMLEditorKit.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/swing/text/html/HTMLEditorKit.java	Wed Nov 08 16:03:35 2017 -0500
@@ -1122,83 +1122,116 @@
      * <caption>Describes the tag and view created by this factory by default
      * </caption>
      * <thead>
-     * <tr>
-     * <th>Tag
-     * <th>View created
-     * </tr>
+     *   <tr>
+     *     <th scope="col">Tag
+     *     <th scope="col">View created
      * </thead>
      * <tbody>
-     * <tr>
-     * <td>HTML.Tag.CONTENT<td>InlineView
-     * </tr><tr>
-     * <td>HTML.Tag.IMPLIED<td>javax.swing.text.html.ParagraphView
-     * </tr><tr>
-     * <td>HTML.Tag.P<td>javax.swing.text.html.ParagraphView
-     * </tr><tr>
-     * <td>HTML.Tag.H1<td>javax.swing.text.html.ParagraphView
-     * </tr><tr>
-     * <td>HTML.Tag.H2<td>javax.swing.text.html.ParagraphView
-     * </tr><tr>
-     * <td>HTML.Tag.H3<td>javax.swing.text.html.ParagraphView
-     * </tr><tr>
-     * <td>HTML.Tag.H4<td>javax.swing.text.html.ParagraphView
-     * </tr><tr>
-     * <td>HTML.Tag.H5<td>javax.swing.text.html.ParagraphView
-     * </tr><tr>
-     * <td>HTML.Tag.H6<td>javax.swing.text.html.ParagraphView
-     * </tr><tr>
-     * <td>HTML.Tag.DT<td>javax.swing.text.html.ParagraphView
-     * </tr><tr>
-     * <td>HTML.Tag.MENU<td>ListView
-     * </tr><tr>
-     * <td>HTML.Tag.DIR<td>ListView
-     * </tr><tr>
-     * <td>HTML.Tag.UL<td>ListView
-     * </tr><tr>
-     * <td>HTML.Tag.OL<td>ListView
-     * </tr><tr>
-     * <td>HTML.Tag.LI<td>BlockView
-     * </tr><tr>
-     * <td>HTML.Tag.DL<td>BlockView
-     * </tr><tr>
-     * <td>HTML.Tag.DD<td>BlockView
-     * </tr><tr>
-     * <td>HTML.Tag.BODY<td>BlockView
-     * </tr><tr>
-     * <td>HTML.Tag.HTML<td>BlockView
-     * </tr><tr>
-     * <td>HTML.Tag.CENTER<td>BlockView
-     * </tr><tr>
-     * <td>HTML.Tag.DIV<td>BlockView
-     * </tr><tr>
-     * <td>HTML.Tag.BLOCKQUOTE<td>BlockView
-     * </tr><tr>
-     * <td>HTML.Tag.PRE<td>BlockView
-     * </tr><tr>
-     * <td>HTML.Tag.BLOCKQUOTE<td>BlockView
-     * </tr><tr>
-     * <td>HTML.Tag.PRE<td>BlockView
-     * </tr><tr>
-     * <td>HTML.Tag.IMG<td>ImageView
-     * </tr><tr>
-     * <td>HTML.Tag.HR<td>HRuleView
-     * </tr><tr>
-     * <td>HTML.Tag.BR<td>BRView
-     * </tr><tr>
-     * <td>HTML.Tag.TABLE<td>javax.swing.text.html.TableView
-     * </tr><tr>
-     * <td>HTML.Tag.INPUT<td>FormView
-     * </tr><tr>
-     * <td>HTML.Tag.SELECT<td>FormView
-     * </tr><tr>
-     * <td>HTML.Tag.TEXTAREA<td>FormView
-     * </tr><tr>
-     * <td>HTML.Tag.OBJECT<td>ObjectView
-     * </tr><tr>
-     * <td>HTML.Tag.FRAMESET<td>FrameSetView
-     * </tr><tr>
-     * <td>HTML.Tag.FRAME<td>FrameView
-     * </tr>
+     *   <tr>
+     *     <th scope="row">HTML.Tag.CONTENT
+     *     <td>InlineView
+     *   <tr>
+     *     <th scope="row">HTML.Tag.IMPLIED
+     *     <td>javax.swing.text.html.ParagraphView
+     *   <tr>
+     *     <th scope="row">HTML.Tag.P
+     *     <td>javax.swing.text.html.ParagraphView
+     *   <tr>
+     *     <th scope="row">HTML.Tag.H1
+     *     <td>javax.swing.text.html.ParagraphView
+     *   <tr>
+     *     <th scope="row">HTML.Tag.H2
+     *     <td>javax.swing.text.html.ParagraphView
+     *   <tr>
+     *     <th scope="row">HTML.Tag.H3
+     *     <td>javax.swing.text.html.ParagraphView
+     *   <tr>
+     *     <th scope="row">HTML.Tag.H4
+     *     <td>javax.swing.text.html.ParagraphView
+     *   <tr>
+     *     <th scope="row">HTML.Tag.H5
+     *     <td>javax.swing.text.html.ParagraphView
+     *   <tr>
+     *     <th scope="row">HTML.Tag.H6
+     *     <td>javax.swing.text.html.ParagraphView
+     *   <tr>
+     *     <th scope="row">HTML.Tag.DT
+     *     <td>javax.swing.text.html.ParagraphView
+     *   <tr>
+     *     <th scope="row">HTML.Tag.MENU
+     *     <td>ListView
+     *   <tr>
+     *     <th scope="row">HTML.Tag.DIR
+     *     <td>ListView
+     *   <tr>
+     *     <th scope="row">HTML.Tag.UL
+     *     <td>ListView
+     *   <tr>
+     *     <th scope="row">HTML.Tag.OL
+     *     <td>ListView
+     *   <tr>
+     *     <th scope="row">HTML.Tag.LI
+     *     <td>BlockView
+     *   <tr>
+     *     <th scope="row">HTML.Tag.DL
+     *     <td>BlockView
+     *   <tr>
+     *     <th scope="row">HTML.Tag.DD
+     *     <td>BlockView
+     *   <tr>
+     *     <th scope="row">HTML.Tag.BODY
+     *     <td>BlockView
+     *   <tr>
+     *     <th scope="row">HTML.Tag.HTML
+     *     <td>BlockView
+     *   <tr>
+     *     <th scope="row">HTML.Tag.CENTER
+     *     <td>BlockView
+     *   <tr>
+     *     <th scope="row">HTML.Tag.DIV
+     *     <td>BlockView
+     *   <tr>
+     *     <th scope="row">HTML.Tag.BLOCKQUOTE
+     *     <td>BlockView
+     *   <tr>
+     *     <th scope="row">HTML.Tag.PRE
+     *     <td>BlockView
+     *   <tr>
+     *     <th scope="row">HTML.Tag.BLOCKQUOTE
+     *     <td>BlockView
+     *   <tr>
+     *     <th scope="row">HTML.Tag.PRE
+     *     <td>BlockView
+     *   <tr>
+     *     <th scope="row">HTML.Tag.IMG
+     *     <td>ImageView
+     *   <tr>
+     *     <th scope="row">HTML.Tag.HR
+     *     <td>HRuleView
+     *   <tr>
+     *     <th scope="row">HTML.Tag.BR
+     *     <td>BRView
+     *   <tr>
+     *     <th scope="row">HTML.Tag.TABLE
+     *     <td>javax.swing.text.html.TableView
+     *   <tr>
+     *     <th scope="row">HTML.Tag.INPUT
+     *     <td>FormView
+     *   <tr>
+     *     <th scope="row">HTML.Tag.SELECT
+     *     <td>FormView
+     *   <tr>
+     *     <th scope="row">HTML.Tag.TEXTAREA
+     *     <td>FormView
+     *   <tr>
+     *     <th scope="row">HTML.Tag.OBJECT
+     *     <td>ObjectView
+     *   <tr>
+     *     <th scope="row">HTML.Tag.FRAMESET
+     *     <td>FrameSetView
+     *   <tr>
+     *     <th scope="row">HTML.Tag.FRAME
+     *     <td>FrameView
      * </tbody>
      * </table>
      */
--- a/src/java.desktop/share/classes/javax/swing/tree/DefaultTreeCellRenderer.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/javax/swing/tree/DefaultTreeCellRenderer.java	Wed Nov 08 16:03:35 2017 -0500
@@ -65,19 +65,35 @@
  * <caption>Properties</caption>
  * <thead>
  *   <tr>
- *     <th>Property:
- *     <th>Key:
+ *     <th scope="col">Property
+ *     <th scope="col">Key
  *   </tr>
  * </thead>
  * <tbody>
- *   <tr><td>"leafIcon"<td>"Tree.leafIcon"
- *   <tr><td>"closedIcon"<td>"Tree.closedIcon"
- *   <tr><td>"openIcon"<td>"Tree.openIcon"
- *   <tr><td>"textSelectionColor"<td>"Tree.selectionForeground"
- *   <tr><td>"textNonSelectionColor"<td>"Tree.textForeground"
- *   <tr><td>"backgroundSelectionColor"<td>"Tree.selectionBackground"
- *   <tr><td>"backgroundNonSelectionColor"<td>"Tree.textBackground"
- *   <tr><td>"borderSelectionColor"<td>"Tree.selectionBorderColor"
+ *   <tr>
+ *     <th scope="row">"leafIcon"
+ *     <td>"Tree.leafIcon"
+ *   <tr>
+ *     <th scope="row">"closedIcon"
+ *     <td>"Tree.closedIcon"
+ *   <tr>
+ *     <th scope="row">"openIcon"
+ *     <td>"Tree.openIcon"
+ *   <tr>
+ *     <th scope="row">"textSelectionColor"
+ *     <td>"Tree.selectionForeground"
+ *   <tr>
+ *     <th scope="row">"textNonSelectionColor"
+ *     <td>"Tree.textForeground"
+ *   <tr>
+ *     <th scope="row">"backgroundSelectionColor"
+ *     <td>"Tree.selectionBackground"
+ *   <tr>
+ *     <th scope="row">"backgroundNonSelectionColor"
+ *     <td>"Tree.textBackground"
+ *   <tr>
+ *     <th scope="row">"borderSelectionColor"
+ *     <td>"Tree.selectionBorderColor"
  * </tbody>
  * </table>
  * <p>
--- a/src/java.desktop/share/classes/sun/awt/AWTAccessor.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/share/classes/sun/awt/AWTAccessor.java	Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -291,26 +291,6 @@
      */
     public interface WindowAccessor {
         /*
-         * Get opacity level of the given window.
-         */
-        float getOpacity(Window window);
-        /*
-         * Set opacity level to the given window.
-         */
-        void setOpacity(Window window, float opacity);
-        /*
-         * Get a shape assigned to the given window.
-         */
-        Shape getShape(Window window);
-        /*
-         * Set a shape to the given window.
-         */
-        void setShape(Window window, Shape shape);
-        /*
-         * Set the opaque preoperty to the given window.
-         */
-        void setOpaque(Window window, boolean isOpaque);
-        /*
          * Update the image of a non-opaque (translucent) window.
          */
         void updateWindow(Window window);
--- a/src/java.desktop/unix/classes/sun/awt/X11/XDragSourceContextPeer.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/unix/classes/sun/awt/X11/XDragSourceContextPeer.java	Wed Nov 08 16:03:35 2017 -0500
@@ -38,6 +38,7 @@
 
 import java.util.*;
 
+import sun.java2d.pipe.Region;
 import sun.util.logging.PlatformLogger;
 
 import sun.awt.dnd.SunDragSourceContextPeer;
@@ -811,10 +812,10 @@
     }
 
     public int scaleUp(int x) {
-        return x * windowScale;
+        return Region.clipRound(x * (double)windowScale);
     }
 
     public int scaleDown(int x) {
-        return x / windowScale;
+        return Region.clipRound(x / (double)windowScale);
     }
 }
--- a/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java	Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -22,41 +22,135 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
+
 package sun.awt.X11;
 
-import java.awt.peer.TaskbarPeer;
-import java.awt.*;
-import java.awt.event.InputEvent;
-import java.awt.event.MouseEvent;
-import java.awt.event.KeyEvent;
+import java.awt.AWTError;
+import java.awt.AWTException;
+import java.awt.Button;
+import java.awt.Canvas;
+import java.awt.Checkbox;
+import java.awt.CheckboxMenuItem;
+import java.awt.Choice;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Cursor;
+import java.awt.Desktop;
+import java.awt.Dialog;
+import java.awt.Dimension;
+import java.awt.EventQueue;
+import java.awt.FileDialog;
+import java.awt.Frame;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsDevice;
+import java.awt.GraphicsEnvironment;
+import java.awt.HeadlessException;
+import java.awt.Image;
+import java.awt.Insets;
+import java.awt.JobAttributes;
+import java.awt.Label;
+import java.awt.Menu;
+import java.awt.MenuBar;
+import java.awt.MenuItem;
+import java.awt.PageAttributes;
+import java.awt.Panel;
+import java.awt.Point;
+import java.awt.PopupMenu;
+import java.awt.PrintJob;
+import java.awt.Rectangle;
+import java.awt.Robot;
+import java.awt.ScrollPane;
+import java.awt.Scrollbar;
+import java.awt.SystemColor;
+import java.awt.SystemTray;
+import java.awt.Taskbar;
+import java.awt.TextArea;
+import java.awt.TextField;
+import java.awt.Toolkit;
+import java.awt.TrayIcon;
+import java.awt.Window;
 import java.awt.datatransfer.Clipboard;
+import java.awt.dnd.DragGestureEvent;
+import java.awt.dnd.DragGestureListener;
+import java.awt.dnd.DragGestureRecognizer;
 import java.awt.dnd.DragSource;
-import java.awt.dnd.DragGestureListener;
-import java.awt.dnd.DragGestureEvent;
-import java.awt.dnd.DragGestureRecognizer;
+import java.awt.dnd.InvalidDnDOperationException;
 import java.awt.dnd.MouseDragGestureRecognizer;
-import java.awt.dnd.InvalidDnDOperationException;
 import java.awt.dnd.peer.DragSourceContextPeer;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseEvent;
 import java.awt.font.TextAttribute;
 import java.awt.im.InputMethodHighlight;
 import java.awt.im.spi.InputMethodDescriptor;
-import java.awt.peer.*;
+import java.awt.peer.ButtonPeer;
+import java.awt.peer.CanvasPeer;
+import java.awt.peer.CheckboxMenuItemPeer;
+import java.awt.peer.CheckboxPeer;
+import java.awt.peer.ChoicePeer;
+import java.awt.peer.DesktopPeer;
+import java.awt.peer.DialogPeer;
+import java.awt.peer.FileDialogPeer;
+import java.awt.peer.FontPeer;
+import java.awt.peer.FramePeer;
+import java.awt.peer.KeyboardFocusManagerPeer;
+import java.awt.peer.LabelPeer;
+import java.awt.peer.ListPeer;
+import java.awt.peer.MenuBarPeer;
+import java.awt.peer.MenuItemPeer;
+import java.awt.peer.MenuPeer;
+import java.awt.peer.MouseInfoPeer;
+import java.awt.peer.PanelPeer;
+import java.awt.peer.PopupMenuPeer;
+import java.awt.peer.RobotPeer;
+import java.awt.peer.ScrollPanePeer;
+import java.awt.peer.ScrollbarPeer;
+import java.awt.peer.SystemTrayPeer;
+import java.awt.peer.TaskbarPeer;
+import java.awt.peer.TextAreaPeer;
+import java.awt.peer.TextFieldPeer;
+import java.awt.peer.TrayIconPeer;
+import java.awt.peer.WindowPeer;
 import java.beans.PropertyChangeListener;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Properties;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.TreeMap;
+import java.util.Vector;
+
 import javax.swing.LookAndFeel;
 import javax.swing.UIDefaults;
-import sun.awt.*;
+
+import sun.awt.AWTAccessor;
+import sun.awt.AWTPermissions;
+import sun.awt.AppContext;
+import sun.awt.DisplayChangedListener;
+import sun.awt.LightweightFrame;
+import sun.awt.SunToolkit;
+import sun.awt.UNIXToolkit;
+import sun.awt.X11GraphicsConfig;
+import sun.awt.X11GraphicsDevice;
+import sun.awt.X11GraphicsEnvironment;
+import sun.awt.XSettings;
 import sun.awt.datatransfer.DataTransferer;
+import sun.awt.util.PerformanceLogger;
+import sun.awt.util.ThreadGroupUtils;
 import sun.font.FontConfigManager;
 import sun.java2d.SunGraphicsEnvironment;
-import sun.awt.util.PerformanceLogger;
-import sun.awt.util.ThreadGroupUtils;
 import sun.print.PrintJob2D;
+import sun.security.action.GetBooleanAction;
 import sun.security.action.GetPropertyAction;
-import sun.security.action.GetBooleanAction;
 import sun.util.logging.PlatformLogger;
+
 import static sun.awt.X11.XlibUtil.scaleDown;
 
 public final class XToolkit extends UNIXToolkit implements Runnable {
@@ -2587,7 +2681,7 @@
     @Override
     public boolean isWindowTranslucencySupported() {
         //NOTE: it may not be supported. The actual check is being performed
-        //      at com.sun.awt.AWTUtilities(). In X11 we need to check
+        //      at java.awt.GraphicsDevice. In X11 we need to check
         //      whether there's any translucency-capable GC available.
         return true;
     }
--- a/src/java.desktop/unix/classes/sun/awt/X11/XWindowPeer.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/unix/classes/sun/awt/X11/XWindowPeer.java	Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -22,42 +22,50 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
+
 package sun.awt.X11;
 
-import java.awt.*;
-
+import java.awt.AWTEvent;
+import java.awt.Component;
+import java.awt.Dialog;
+import java.awt.Dimension;
+import java.awt.EventQueue;
+import java.awt.Frame;
+import java.awt.Graphics;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsDevice;
+import java.awt.GraphicsEnvironment;
+import java.awt.Image;
+import java.awt.Insets;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.awt.SystemColor;
+import java.awt.Window;
 import java.awt.event.ComponentEvent;
 import java.awt.event.FocusEvent;
 import java.awt.event.WindowEvent;
-import java.awt.geom.AffineTransform;
-
 import java.awt.peer.ComponentPeer;
 import java.awt.peer.WindowPeer;
-
 import java.io.UnsupportedEncodingException;
-
 import java.security.AccessController;
 import java.security.PrivilegedAction;
-
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Set;
 import java.util.Vector;
-
 import java.util.concurrent.atomic.AtomicBoolean;
 
+import sun.awt.AWTAccessor;
 import sun.awt.AWTAccessor.ComponentAccessor;
-import sun.util.logging.PlatformLogger;
-
-import sun.awt.AWTAccessor;
 import sun.awt.DisplayChangedListener;
+import sun.awt.IconInfo;
 import sun.awt.SunToolkit;
 import sun.awt.X11GraphicsDevice;
 import sun.awt.X11GraphicsEnvironment;
-import sun.awt.IconInfo;
-
 import sun.java2d.pipe.Region;
+import sun.util.logging.PlatformLogger;
 
 class XWindowPeer extends XPanelPeer implements WindowPeer,
                                                 DisplayChangedListener {
@@ -446,16 +454,14 @@
     }
 
     private void updateShape() {
-        // Shape shape = ((Window)target).getShape();
-        Shape shape = AWTAccessor.getWindowAccessor().getShape((Window)target);
+        Shape shape = ((Window)target).getShape();
         if (shape != null) {
             applyShape(Region.getInstance(shape, null));
         }
     }
 
     private void updateOpacity() {
-        // float opacity = ((Window)target).getOpacity();
-        float opacity = AWTAccessor.getWindowAccessor().getOpacity((Window)target);
+        float opacity = ((Window)target).getOpacity();
         if (opacity < 1.0f) {
             setOpacity(opacity);
         }
@@ -2375,7 +2381,7 @@
     public void print(Graphics g) {
         // We assume we print the whole frame,
         // so we expect no clip was set previously
-        Shape shape = AWTAccessor.getWindowAccessor().getShape((Window)target);
+        Shape shape = ((Window)target).getShape();
         if (shape != null) {
             g.setClip(shape);
         }
--- a/src/java.desktop/unix/classes/sun/awt/X11/XlibUtil.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/unix/classes/sun/awt/X11/XlibUtil.java	Wed Nov 08 16:03:35 2017 -0500
@@ -38,6 +38,8 @@
 import sun.awt.X11GraphicsDevice;
 import sun.awt.X11GraphicsEnvironment;
 
+import sun.java2d.pipe.Region;
+
 /*
  * This class is a collection of utility methods that operate
  * with native windows.
@@ -414,6 +416,6 @@
     }
 
     static int scaleDown(int x, int scale) {
-        return x / scale;
+        return Region.clipRound(x / (double)scale);
     }
 }
--- a/src/java.desktop/unix/classes/sun/awt/X11GraphicsConfig.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/unix/classes/sun/awt/X11GraphicsConfig.java	Wed Nov 08 16:03:35 2017 -0500
@@ -49,6 +49,7 @@
 import sun.java2d.loops.RenderLoops;
 import sun.java2d.loops.SurfaceType;
 import sun.java2d.loops.CompositeType;
+import sun.java2d.pipe.Region;
 import sun.java2d.x11.X11SurfaceData;
 import sun.awt.image.OffScreenImage;
 import sun.awt.image.SunVolatileImage;
@@ -265,11 +266,11 @@
     }
 
     public int scaleUp(int x) {
-        return x * getScale();
+        return Region.clipRound(x * (double)getScale());
     }
 
     public int scaleDown(int x) {
-        return x / getScale();
+        return Region.clipRound(x / (double)getScale());
     }
 
     /**
--- a/src/java.desktop/unix/legal/fontconfig.md	Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,24 +0,0 @@
-## Fontconfig v2.5
-
-### Fontconfig License
-<pre>
-
-Copyright 2001,2003 Keith Packard
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that the
-above copyright notice appear in all copies and that both that copyright
-notice and this permission notice appear in supporting documentation, and that
-the name of Keith Packard not be used in advertising or publicity pertaining
-to distribution of the software without specific, written prior permission.
-Keith Packard makes no representations about the suitability of this software
-for any purpose.  It is provided "as is" without express or implied warranty.
-
-KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL KEITH
-PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
-DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
-CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-</pre>
--- a/src/java.desktop/unix/native/common/awt/fontconfig.h	Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,941 +0,0 @@
-/*
- * $RCSId: xc/lib/fontconfig/fontconfig/fontconfig.h,v 1.30 2002/09/26 00:17:27 keithp Exp $
- *
- * Copyright © 2001 Keith Packard
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Keith Packard not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission.  Keith Packard makes no
- * representations about the suitability of this software for any purpose.  It
- * is provided "as is" without express or implied warranty.
- *
- * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef _FONTCONFIG_H_
-#define _FONTCONFIG_H_
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <stdarg.h>
-
-#if defined(__GNUC__) && (__GNUC__ >= 4)
-#define FC_ATTRIBUTE_SENTINEL(x) __attribute__((__sentinel__(0)))
-#else
-#define FC_ATTRIBUTE_SENTINEL(x)
-#endif
-
-#ifndef FcPublic
-#define FcPublic
-#endif
-
-typedef unsigned char   FcChar8;
-typedef unsigned short  FcChar16;
-typedef unsigned int    FcChar32;
-typedef int             FcBool;
-
-/*
- * Current Fontconfig version number.  This same number
- * must appear in the fontconfig configure.in file. Yes,
- * it'a a pain to synchronize version numbers like this.
- */
-
-#define FC_MAJOR        2
-#define FC_MINOR        5
-#define FC_REVISION     0
-
-#define FC_VERSION      ((FC_MAJOR * 10000) + (FC_MINOR * 100) + (FC_REVISION))
-
-/*
- * Current font cache file format version
- * This is appended to the cache files so that multiple
- * versions of the library will peacefully coexist
- *
- * Change this value whenever the disk format for the cache file
- * changes in any non-compatible way.  Try to avoid such changes as
- * it means multiple copies of the font information.
- */
-
-#define FC_CACHE_VERSION    "2"
-
-#define FcTrue          1
-#define FcFalse         0
-
-#define FC_FAMILY           "family"            /* String */
-#define FC_STYLE            "style"             /* String */
-#define FC_SLANT            "slant"             /* Int */
-#define FC_WEIGHT           "weight"            /* Int */
-#define FC_SIZE             "size"              /* Double */
-#define FC_ASPECT           "aspect"            /* Double */
-#define FC_PIXEL_SIZE       "pixelsize"         /* Double */
-#define FC_SPACING          "spacing"           /* Int */
-#define FC_FOUNDRY          "foundry"           /* String */
-#define FC_ANTIALIAS        "antialias"         /* Bool (depends) */
-#define FC_HINTING          "hinting"           /* Bool (true) */
-#define FC_HINT_STYLE       "hintstyle"         /* Int */
-#define FC_VERTICAL_LAYOUT  "verticallayout"    /* Bool (false) */
-#define FC_AUTOHINT         "autohint"          /* Bool (false) */
-#define FC_GLOBAL_ADVANCE   "globaladvance"     /* Bool (true) */
-#define FC_WIDTH            "width"             /* Int */
-#define FC_FILE             "file"              /* String */
-#define FC_INDEX            "index"             /* Int */
-#define FC_FT_FACE          "ftface"            /* FT_Face */
-#define FC_RASTERIZER       "rasterizer"        /* String */
-#define FC_OUTLINE          "outline"           /* Bool */
-#define FC_SCALABLE         "scalable"          /* Bool */
-#define FC_SCALE            "scale"             /* double */
-#define FC_DPI              "dpi"               /* double */
-#define FC_RGBA             "rgba"              /* Int */
-#define FC_MINSPACE         "minspace"          /* Bool use minimum line spacing */
-#define FC_SOURCE           "source"            /* String (deprecated) */
-#define FC_CHARSET          "charset"           /* CharSet */
-#define FC_LANG             "lang"              /* String RFC 3066 langs */
-#define FC_FONTVERSION      "fontversion"       /* Int from 'head' table */
-#define FC_FULLNAME         "fullname"          /* String */
-#define FC_FAMILYLANG       "familylang"        /* String RFC 3066 langs */
-#define FC_STYLELANG        "stylelang"         /* String RFC 3066 langs */
-#define FC_FULLNAMELANG     "fullnamelang"      /* String RFC 3066 langs */
-#define FC_CAPABILITY       "capability"        /* String */
-#define FC_FONTFORMAT       "fontformat"        /* String */
-#define FC_EMBOLDEN         "embolden"          /* Bool - true if emboldening needed*/
-#define FC_EMBEDDED_BITMAP  "embeddedbitmap"    /* Bool - true to enable embedded bitmaps */
-#define FC_DECORATIVE       "decorative"        /* Bool - true if style is a decorative variant */
-
-#define FC_CACHE_SUFFIX             ".cache-"FC_CACHE_VERSION
-#define FC_DIR_CACHE_FILE           "fonts.cache-"FC_CACHE_VERSION
-#define FC_USER_CACHE_FILE          ".fonts.cache-"FC_CACHE_VERSION
-
-/* Adjust outline rasterizer */
-#define FC_CHAR_WIDTH       "charwidth" /* Int */
-#define FC_CHAR_HEIGHT      "charheight"/* Int */
-#define FC_MATRIX           "matrix"    /* FcMatrix */
-
-#define FC_WEIGHT_THIN              0
-#define FC_WEIGHT_EXTRALIGHT        40
-#define FC_WEIGHT_ULTRALIGHT        FC_WEIGHT_EXTRALIGHT
-#define FC_WEIGHT_LIGHT             50
-#define FC_WEIGHT_BOOK              75
-#define FC_WEIGHT_REGULAR           80
-#define FC_WEIGHT_NORMAL            FC_WEIGHT_REGULAR
-#define FC_WEIGHT_MEDIUM            100
-#define FC_WEIGHT_DEMIBOLD          180
-#define FC_WEIGHT_SEMIBOLD          FC_WEIGHT_DEMIBOLD
-#define FC_WEIGHT_BOLD              200
-#define FC_WEIGHT_EXTRABOLD         205
-#define FC_WEIGHT_ULTRABOLD         FC_WEIGHT_EXTRABOLD
-#define FC_WEIGHT_BLACK             210
-#define FC_WEIGHT_HEAVY             FC_WEIGHT_BLACK
-#define FC_WEIGHT_EXTRABLACK        215
-#define FC_WEIGHT_ULTRABLACK        FC_WEIGHT_EXTRABLACK
-
-#define FC_SLANT_ROMAN              0
-#define FC_SLANT_ITALIC             100
-#define FC_SLANT_OBLIQUE            110
-
-#define FC_WIDTH_ULTRACONDENSED     50
-#define FC_WIDTH_EXTRACONDENSED     63
-#define FC_WIDTH_CONDENSED          75
-#define FC_WIDTH_SEMICONDENSED      87
-#define FC_WIDTH_NORMAL             100
-#define FC_WIDTH_SEMIEXPANDED       113
-#define FC_WIDTH_EXPANDED           125
-#define FC_WIDTH_EXTRAEXPANDED      150
-#define FC_WIDTH_ULTRAEXPANDED      200
-
-#define FC_PROPORTIONAL             0
-#define FC_DUAL                     90
-#define FC_MONO                     100
-#define FC_CHARCELL                 110
-
-/* sub-pixel order */
-#define FC_RGBA_UNKNOWN     0
-#define FC_RGBA_RGB         1
-#define FC_RGBA_BGR         2
-#define FC_RGBA_VRGB        3
-#define FC_RGBA_VBGR        4
-#define FC_RGBA_NONE        5
-
-/* hinting style */
-#define FC_HINT_NONE        0
-#define FC_HINT_SLIGHT      1
-#define FC_HINT_MEDIUM      2
-#define FC_HINT_FULL        3
-
-typedef enum _FcType {
-    FcTypeVoid,
-    FcTypeInteger,
-    FcTypeDouble,
-    FcTypeString,
-    FcTypeBool,
-    FcTypeMatrix,
-    FcTypeCharSet,
-    FcTypeFTFace,
-    FcTypeLangSet
-} FcType;
-
-typedef struct _FcMatrix {
-    double xx, xy, yx, yy;
-} FcMatrix;
-
-#define FcMatrixInit(m) ((m)->xx = (m)->yy = 1, \
-                         (m)->xy = (m)->yx = 0)
-
-/*
- * A data structure to represent the available glyphs in a font.
- * This is represented as a sparse boolean btree.
- */
-
-typedef struct _FcCharSet FcCharSet;
-
-typedef struct _FcObjectType {
-    const char  *object;
-    FcType      type;
-} FcObjectType;
-
-typedef struct _FcConstant {
-    const FcChar8  *name;
-    const char  *object;
-    int         value;
-} FcConstant;
-
-typedef enum _FcResult {
-    FcResultMatch, FcResultNoMatch, FcResultTypeMismatch, FcResultNoId,
-    FcResultOutOfMemory
-} FcResult;
-
-typedef struct _FcPattern   FcPattern;
-
-typedef struct _FcLangSet   FcLangSet;
-
-typedef struct _FcValue {
-    FcType      type;
-    union {
-        const FcChar8   *s;
-        int             i;
-        FcBool          b;
-        double          d;
-        const FcMatrix  *m;
-        const FcCharSet *c;
-        void            *f;
-        const FcLangSet *l;
-    } u;
-} FcValue;
-
-typedef struct _FcFontSet {
-    int         nfont;
-    int         sfont;
-    FcPattern   **fonts;
-} FcFontSet;
-
-typedef struct _FcObjectSet {
-    int         nobject;
-    int         sobject;
-    const char  **objects;
-} FcObjectSet;
-
-typedef enum _FcMatchKind {
-    FcMatchPattern, FcMatchFont, FcMatchScan
-} FcMatchKind;
-
-typedef enum _FcLangResult {
-    FcLangEqual = 0,
-    FcLangDifferentCountry = 1,
-    FcLangDifferentTerritory = 1,
-    FcLangDifferentLang = 2
-} FcLangResult;
-
-typedef enum _FcSetName {
-    FcSetSystem = 0,
-    FcSetApplication = 1
-} FcSetName;
-
-typedef struct _FcAtomic FcAtomic;
-
-#if defined(__cplusplus) || defined(c_plusplus) /* for C++ V2.0 */
-#define _FCFUNCPROTOBEGIN extern "C" {  /* do not leave open across includes */
-#define _FCFUNCPROTOEND }
-#else
-#define _FCFUNCPROTOBEGIN
-#define _FCFUNCPROTOEND
-#endif
-
-typedef enum { FcEndianBig, FcEndianLittle } FcEndian;
-
-typedef struct _FcConfig    FcConfig;
-
-typedef struct _FcGlobalCache   FcFileCache;
-
-typedef struct _FcBlanks    FcBlanks;
-
-typedef struct _FcStrList   FcStrList;
-
-typedef struct _FcStrSet    FcStrSet;
-
-typedef struct _FcCache     FcCache;
-
-_FCFUNCPROTOBEGIN
-
-/* fcblanks.c */
-FcPublic FcBlanks *
-FcBlanksCreate (void);
-
-FcPublic void
-FcBlanksDestroy (FcBlanks *b);
-
-FcPublic FcBool
-FcBlanksAdd (FcBlanks *b, FcChar32 ucs4);
-
-FcPublic FcBool
-FcBlanksIsMember (FcBlanks *b, FcChar32 ucs4);
-
-/* fccache.c */
-
-FcPublic const FcChar8 *
-FcCacheDir(const FcCache *c);
-
-FcPublic FcFontSet *
-FcCacheCopySet(const FcCache *c);
-
-FcPublic const FcChar8 *
-FcCacheSubdir (const FcCache *c, int i);
-
-FcPublic int
-FcCacheNumSubdir (const FcCache *c);
-
-FcPublic int
-FcCacheNumFont (const FcCache *c);
-
-FcPublic FcBool
-FcDirCacheUnlink (const FcChar8 *dir, FcConfig *config);
-
-FcPublic FcBool
-FcDirCacheValid (const FcChar8 *cache_file);
-
-/* fccfg.c */
-FcPublic FcChar8 *
-FcConfigHome (void);
-
-FcPublic FcBool
-FcConfigEnableHome (FcBool enable);
-
-FcPublic FcChar8 *
-FcConfigFilename (const FcChar8 *url);
-
-FcPublic FcConfig *
-FcConfigCreate (void);
-
-FcPublic void
-FcConfigDestroy (FcConfig *config);
-
-FcPublic FcBool
-FcConfigSetCurrent (FcConfig *config);
-
-FcPublic FcConfig *
-FcConfigGetCurrent (void);
-
-FcPublic FcBool
-FcConfigUptoDate (FcConfig *config);
-
-FcPublic FcBool
-FcConfigBuildFonts (FcConfig *config);
-
-FcPublic FcStrList *
-FcConfigGetFontDirs (FcConfig   *config);
-
-FcPublic FcStrList *
-FcConfigGetConfigDirs (FcConfig   *config);
-
-FcPublic FcStrList *
-FcConfigGetConfigFiles (FcConfig    *config);
-
-FcPublic FcChar8 *
-FcConfigGetCache (FcConfig  *config);
-
-FcPublic FcBlanks *
-FcConfigGetBlanks (FcConfig *config);
-
-FcPublic FcStrList *
-FcConfigGetCacheDirs (FcConfig  *config);
-
-FcPublic int
-FcConfigGetRescanInterval (FcConfig *config);
-
-FcPublic FcBool
-FcConfigSetRescanInterval (FcConfig *config, int rescanInterval);
-
-FcPublic FcFontSet *
-FcConfigGetFonts (FcConfig      *config,
-                  FcSetName     set);
-
-FcPublic FcBool
-FcConfigAppFontAddFile (FcConfig    *config,
-                        const FcChar8  *file);
-
-FcPublic FcBool
-FcConfigAppFontAddDir (FcConfig     *config,
-                       const FcChar8   *dir);
-
-FcPublic void
-FcConfigAppFontClear (FcConfig      *config);
-
-FcPublic FcBool
-FcConfigSubstituteWithPat (FcConfig     *config,
-                           FcPattern    *p,
-                           FcPattern    *p_pat,
-                           FcMatchKind  kind);
-
-FcPublic FcBool
-FcConfigSubstitute (FcConfig    *config,
-                    FcPattern   *p,
-                    FcMatchKind kind);
-
-/* fccharset.c */
-FcPublic FcCharSet*
-FcCharSetCreate (void);
-
-/* deprecated alias for FcCharSetCreate */
-FcPublic FcCharSet *
-FcCharSetNew (void);
-
-FcPublic void
-FcCharSetDestroy (FcCharSet *fcs);
-
-FcPublic FcBool
-FcCharSetAddChar (FcCharSet *fcs, FcChar32 ucs4);
-
-FcPublic FcCharSet*
-FcCharSetCopy (FcCharSet *src);
-
-FcPublic FcBool
-FcCharSetEqual (const FcCharSet *a, const FcCharSet *b);
-
-FcPublic FcCharSet*
-FcCharSetIntersect (const FcCharSet *a, const FcCharSet *b);
-
-FcPublic FcCharSet*
-FcCharSetUnion (const FcCharSet *a, const FcCharSet *b);
-
-FcPublic FcCharSet*
-FcCharSetSubtract (const FcCharSet *a, const FcCharSet *b);
-
-FcPublic FcBool
-FcCharSetHasChar (const FcCharSet *fcs, FcChar32 ucs4);
-
-FcPublic FcChar32
-FcCharSetCount (const FcCharSet *a);
-
-FcPublic FcChar32
-FcCharSetIntersectCount (const FcCharSet *a, const FcCharSet *b);
-
-FcPublic FcChar32
-FcCharSetSubtractCount (const FcCharSet *a, const FcCharSet *b);
-
-FcPublic FcBool
-FcCharSetIsSubset (const FcCharSet *a, const FcCharSet *b);
-
-#define FC_CHARSET_MAP_SIZE (256/32)
-#define FC_CHARSET_DONE ((FcChar32) -1)
-
-FcPublic FcChar32
-FcCharSetFirstPage (const FcCharSet *a,
-                    FcChar32        map[FC_CHARSET_MAP_SIZE],
-                    FcChar32        *next);
-
-FcPublic FcChar32
-FcCharSetNextPage (const FcCharSet  *a,
-                   FcChar32         map[FC_CHARSET_MAP_SIZE],
-                   FcChar32         *next);
-
-/*
- * old coverage API, rather hard to use correctly
- */
-
-FcPublic FcChar32
-FcCharSetCoverage (const FcCharSet *a, FcChar32 page, FcChar32 *result);
-
-/* fcdbg.c */
-FcPublic void
-FcValuePrint (const FcValue v);
-
-FcPublic void
-FcPatternPrint (const FcPattern *p);
-
-FcPublic void
-FcFontSetPrint (const FcFontSet *s);
-
-/* fcdefault.c */
-FcPublic void
-FcDefaultSubstitute (FcPattern *pattern);
-
-/* fcdir.c */
-FcPublic FcBool
-FcFileIsDir (const FcChar8 *file);
-
-FcPublic FcBool
-FcFileScan (FcFontSet       *set,
-            FcStrSet        *dirs,
-            FcFileCache     *cache,
-            FcBlanks        *blanks,
-            const FcChar8   *file,
-            FcBool          force);
-
-FcPublic FcBool
-FcDirScan (FcFontSet        *set,
-           FcStrSet         *dirs,
-           FcFileCache      *cache,
-           FcBlanks         *blanks,
-           const FcChar8    *dir,
-           FcBool           force);
-
-FcPublic FcBool
-FcDirSave (FcFontSet *set, FcStrSet *dirs, const FcChar8 *dir);
-
-FcPublic FcCache *
-FcDirCacheLoad (const FcChar8 *dir, FcConfig *config, FcChar8 **cache_file);
-
-FcPublic FcCache *
-FcDirCacheRead (const FcChar8 *dir, FcBool force, FcConfig *config);
-
-FcPublic FcCache *
-FcDirCacheLoadFile (const FcChar8 *cache_file, struct stat *file_stat);
-
-FcPublic void
-FcDirCacheUnload (FcCache *cache);
-
-/* fcfreetype.c */
-FcPublic FcPattern *
-FcFreeTypeQuery (const FcChar8 *file, int id, FcBlanks *blanks, int *count);
-
-/* fcfs.c */
-
-FcPublic FcFontSet *
-FcFontSetCreate (void);
-
-FcPublic void
-FcFontSetDestroy (FcFontSet *s);
-
-FcPublic FcBool
-FcFontSetAdd (FcFontSet *s, FcPattern *font);
-
-/* fcinit.c */
-FcPublic FcConfig *
-FcInitLoadConfig (void);
-
-FcPublic FcConfig *
-FcInitLoadConfigAndFonts (void);
-
-FcPublic FcBool
-FcInit (void);
-
-FcPublic void
-FcFini (void);
-
-FcPublic int
-FcGetVersion (void);
-
-FcPublic FcBool
-FcInitReinitialize (void);
-
-FcPublic FcBool
-FcInitBringUptoDate (void);
-
-/* fclang.c */
-FcPublic FcStrSet *
-FcGetLangs (void);
-
-FcPublic const FcCharSet *
-FcLangGetCharSet (const FcChar8 *lang);
-
-FcPublic FcLangSet*
-FcLangSetCreate (void);
-
-FcPublic void
-FcLangSetDestroy (FcLangSet *ls);
-
-FcPublic FcLangSet*
-FcLangSetCopy (const FcLangSet *ls);
-
-FcPublic FcBool
-FcLangSetAdd (FcLangSet *ls, const FcChar8 *lang);
-
-FcPublic FcLangResult
-FcLangSetHasLang (const FcLangSet *ls, const FcChar8 *lang);
-
-FcPublic FcLangResult
-FcLangSetCompare (const FcLangSet *lsa, const FcLangSet *lsb);
-
-FcPublic FcBool
-FcLangSetContains (const FcLangSet *lsa, const FcLangSet *lsb);
-
-FcPublic FcBool
-FcLangSetEqual (const FcLangSet *lsa, const FcLangSet *lsb);
-
-FcPublic FcChar32
-FcLangSetHash (const FcLangSet *ls);
-
-/* fclist.c */
-FcPublic FcObjectSet *
-FcObjectSetCreate (void);
-
-FcPublic FcBool
-FcObjectSetAdd (FcObjectSet *os, const char *object);
-
-FcPublic void
-FcObjectSetDestroy (FcObjectSet *os);
-
-FcPublic FcObjectSet *
-FcObjectSetVaBuild (const char *first, va_list va);
-
-FcPublic FcObjectSet *
-FcObjectSetBuild (const char *first, ...) FC_ATTRIBUTE_SENTINEL(0);
-
-FcPublic FcFontSet *
-FcFontSetList (FcConfig     *config,
-               FcFontSet    **sets,
-               int          nsets,
-               FcPattern    *p,
-               FcObjectSet  *os);
-
-FcPublic FcFontSet *
-FcFontList (FcConfig    *config,
-            FcPattern   *p,
-            FcObjectSet *os);
-
-/* fcatomic.c */
-
-FcPublic FcAtomic *
-FcAtomicCreate (const FcChar8   *file);
-
-FcPublic FcBool
-FcAtomicLock (FcAtomic *atomic);
-
-FcPublic FcChar8 *
-FcAtomicNewFile (FcAtomic *atomic);
-
-FcPublic FcChar8 *
-FcAtomicOrigFile (FcAtomic *atomic);
-
-FcPublic FcBool
-FcAtomicReplaceOrig (FcAtomic *atomic);
-
-FcPublic void
-FcAtomicDeleteNew (FcAtomic *atomic);
-
-FcPublic void
-FcAtomicUnlock (FcAtomic *atomic);
-
-FcPublic void
-FcAtomicDestroy (FcAtomic *atomic);
-
-/* fcmatch.c */
-FcPublic FcPattern *
-FcFontSetMatch (FcConfig    *config,
-                FcFontSet   **sets,
-                int         nsets,
-                FcPattern   *p,
-                FcResult    *result);
-
-FcPublic FcPattern *
-FcFontMatch (FcConfig   *config,
-             FcPattern  *p,
-             FcResult   *result);
-
-FcPublic FcPattern *
-FcFontRenderPrepare (FcConfig       *config,
-                     FcPattern      *pat,
-                     FcPattern      *font);
-
-FcPublic FcFontSet *
-FcFontSetSort (FcConfig     *config,
-               FcFontSet    **sets,
-               int          nsets,
-               FcPattern    *p,
-               FcBool       trim,
-               FcCharSet    **csp,
-               FcResult     *result);
-
-FcPublic FcFontSet *
-FcFontSort (FcConfig     *config,
-            FcPattern    *p,
-            FcBool       trim,
-            FcCharSet    **csp,
-            FcResult     *result);
-
-FcPublic void
-FcFontSetSortDestroy (FcFontSet *fs);
-
-/* fcmatrix.c */
-FcPublic FcMatrix *
-FcMatrixCopy (const FcMatrix *mat);
-
-FcPublic FcBool
-FcMatrixEqual (const FcMatrix *mat1, const FcMatrix *mat2);
-
-FcPublic void
-FcMatrixMultiply (FcMatrix *result, const FcMatrix *a, const FcMatrix *b);
-
-FcPublic void
-FcMatrixRotate (FcMatrix *m, double c, double s);
-
-FcPublic void
-FcMatrixScale (FcMatrix *m, double sx, double sy);
-
-FcPublic void
-FcMatrixShear (FcMatrix *m, double sh, double sv);
-
-/* fcname.c */
-
-FcPublic FcBool
-FcNameRegisterObjectTypes (const FcObjectType *types, int ntype);
-
-FcPublic FcBool
-FcNameUnregisterObjectTypes (const FcObjectType *types, int ntype);
-
-FcPublic const FcObjectType *
-FcNameGetObjectType (const char *object);
-
-FcPublic FcBool
-FcNameRegisterConstants (const FcConstant *consts, int nconsts);
-
-FcPublic FcBool
-FcNameUnregisterConstants (const FcConstant *consts, int nconsts);
-
-FcPublic const FcConstant *
-FcNameGetConstant (FcChar8 *string);
-
-FcPublic FcBool
-FcNameConstant (FcChar8 *string, int *result);
-
-FcPublic FcPattern *
-FcNameParse (const FcChar8 *name);
-
-FcPublic FcChar8 *
-FcNameUnparse (FcPattern *pat);
-
-/* fcpat.c */
-FcPublic FcPattern *
-FcPatternCreate (void);
-
-FcPublic FcPattern *
-FcPatternDuplicate (const FcPattern *p);
-
-FcPublic void
-FcPatternReference (FcPattern *p);
-
-FcPublic void
-FcValueDestroy (FcValue v);
-
-FcPublic FcBool
-FcValueEqual (FcValue va, FcValue vb);
-
-FcPublic FcValue
-FcValueSave (FcValue v);
-
-FcPublic void
-FcPatternDestroy (FcPattern *p);
-
-FcPublic FcBool
-FcPatternEqual (const FcPattern *pa, const FcPattern *pb);
-
-FcPublic FcBool
-FcPatternEqualSubset (const FcPattern *pa, const FcPattern *pb, const FcObjectSet *os);
-
-FcPublic FcChar32
-FcPatternHash (const FcPattern *p);
-
-FcPublic FcBool
-FcPatternAdd (FcPattern *p, const char *object, FcValue value, FcBool append);
-
-FcPublic FcBool
-FcPatternAddWeak (FcPattern *p, const char *object, FcValue value, FcBool append);
-
-FcPublic FcResult
-FcPatternGet (const FcPattern *p, const char *object, int id, FcValue *v);
-
-FcPublic FcBool
-FcPatternDel (FcPattern *p, const char *object);
-
-FcPublic FcBool
-FcPatternRemove (FcPattern *p, const char *object, int id);
-
-FcPublic FcBool
-FcPatternAddInteger (FcPattern *p, const char *object, int i);
-
-FcPublic FcBool
-FcPatternAddDouble (FcPattern *p, const char *object, double d);
-
-FcPublic FcBool
-FcPatternAddString (FcPattern *p, const char *object, const FcChar8 *s);
-
-FcPublic FcBool
-FcPatternAddMatrix (FcPattern *p, const char *object, const FcMatrix *s);
-
-FcPublic FcBool
-FcPatternAddCharSet (FcPattern *p, const char *object, const FcCharSet *c);
-
-FcPublic FcBool
-FcPatternAddBool (FcPattern *p, const char *object, FcBool b);
-
-FcPublic FcBool
-FcPatternAddLangSet (FcPattern *p, const char *object, const FcLangSet *ls);
-
-FcPublic FcResult
-FcPatternGetInteger (const FcPattern *p, const char *object, int n, int *i);
-
-FcPublic FcResult
-FcPatternGetDouble (const FcPattern *p, const char *object, int n, double *d);
-
-FcPublic FcResult
-FcPatternGetString (const FcPattern *p, const char *object, int n, FcChar8 ** s);
-
-FcPublic FcResult
-FcPatternGetMatrix (const FcPattern *p, const char *object, int n, FcMatrix **s);
-
-FcPublic FcResult
-FcPatternGetCharSet (const FcPattern *p, const char *object, int n, FcCharSet **c);
-
-FcPublic FcResult
-FcPatternGetBool (const FcPattern *p, const char *object, int n, FcBool *b);
-
-FcPublic FcResult
-FcPatternGetLangSet (const FcPattern *p, const char *object, int n, FcLangSet **ls);
-
-FcPublic FcPattern *
-FcPatternVaBuild (FcPattern *orig, va_list va);
-
-FcPublic FcPattern *
-FcPatternBuild (FcPattern *orig, ...) FC_ATTRIBUTE_SENTINEL(0);
-
-/* fcstr.c */
-
-FcPublic FcChar8 *
-FcStrCopy (const FcChar8 *s);
-
-FcPublic FcChar8 *
-FcStrCopyFilename (const FcChar8 *s);
-
-FcPublic FcChar8 *
-FcStrPlus (const FcChar8 *s1, const FcChar8 *s2);
-
-FcPublic void
-FcStrFree (FcChar8 *s);
-
-/* These are ASCII only, suitable only for pattern element names */
-#define FcIsUpper(c)    ((0101 <= (c) && (c) <= 0132))
-#define FcIsLower(c)    ((0141 <= (c) && (c) <= 0172))
-#define FcToLower(c)    (FcIsUpper(c) ? (c) - 0101 + 0141 : (c))
-
-FcPublic FcChar8 *
-FcStrDowncase (const FcChar8 *s);
-
-FcPublic int
-FcStrCmpIgnoreCase (const FcChar8 *s1, const FcChar8 *s2);
-
-FcPublic int
-FcStrCmp (const FcChar8 *s1, const FcChar8 *s2);
-
-FcPublic const FcChar8 *
-FcStrStrIgnoreCase (const FcChar8 *s1, const FcChar8 *s2);
-
-FcPublic const FcChar8 *
-FcStrStr (const FcChar8 *s1, const FcChar8 *s2);
-
-FcPublic int
-FcUtf8ToUcs4 (const FcChar8 *src_orig,
-              FcChar32      *dst,
-              int           len);
-
-FcPublic FcBool
-FcUtf8Len (const FcChar8    *string,
-           int              len,
-           int              *nchar,
-           int              *wchar);
-
-#define FC_UTF8_MAX_LEN 6
-
-FcPublic int
-FcUcs4ToUtf8 (FcChar32  ucs4,
-              FcChar8   dest[FC_UTF8_MAX_LEN]);
-
-FcPublic int
-FcUtf16ToUcs4 (const FcChar8    *src_orig,
-               FcEndian         endian,
-               FcChar32         *dst,
-               int              len);       /* in bytes */
-
-FcPublic FcBool
-FcUtf16Len (const FcChar8   *string,
-            FcEndian        endian,
-            int             len,            /* in bytes */
-            int             *nchar,
-            int             *wchar);
-
-FcPublic FcChar8 *
-FcStrDirname (const FcChar8 *file);
-
-FcPublic FcChar8 *
-FcStrBasename (const FcChar8 *file);
-
-FcPublic FcStrSet *
-FcStrSetCreate (void);
-
-FcPublic FcBool
-FcStrSetMember (FcStrSet *set, const FcChar8 *s);
-
-FcPublic FcBool
-FcStrSetEqual (FcStrSet *sa, FcStrSet *sb);
-
-FcPublic FcBool
-FcStrSetAdd (FcStrSet *set, const FcChar8 *s);
-
-FcPublic FcBool
-FcStrSetAddFilename (FcStrSet *set, const FcChar8 *s);
-
-FcPublic FcBool
-FcStrSetDel (FcStrSet *set, const FcChar8 *s);
-
-FcPublic void
-FcStrSetDestroy (FcStrSet *set);
-
-FcPublic FcStrList *
-FcStrListCreate (FcStrSet *set);
-
-FcPublic FcChar8 *
-FcStrListNext (FcStrList *list);
-
-FcPublic void
-FcStrListDone (FcStrList *list);
-
-/* fcxml.c */
-FcPublic FcBool
-FcConfigParseAndLoad (FcConfig *config, const FcChar8 *file, FcBool complain);
-
-_FCFUNCPROTOEND
-
-#undef FC_ATTRIBUTE_SENTINEL
-
-
-#ifndef _FCINT_H_
-
-/*
- * Deprecated functions are placed here to help users fix their code without
- * digging through documentation
- */
-
-#define FcConfigGetRescanInverval   FcConfigGetRescanInverval_REPLACE_BY_FcConfigGetRescanInterval
-#define FcConfigSetRescanInverval   FcConfigSetRescanInverval_REPLACE_BY_FcConfigSetRescanInterval
-
-#endif
-
-#endif /* _FONTCONFIG_H_ */
--- a/src/java.desktop/unix/native/common/awt/fontpath.c	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/unix/native/common/awt/fontpath.c	Wed Nov 08 16:03:35 2017 -0500
@@ -578,7 +578,7 @@
 
 #include <dlfcn.h>
 
-#include "fontconfig.h"
+#include <fontconfig/fontconfig.h>
 
 
 static void* openFontConfig() {
@@ -1254,6 +1254,7 @@
                 && (strcmp((char*)fontformat, "TrueType") != 0)
 #if defined(__linux__) || defined(_AIX)
                 && (strcmp((char*)fontformat, "Type 1") != 0)
+                && (strcmp((char*)fontformat, "CFF") != 0)
 #endif
              ) {
                 continue;
--- a/src/java.desktop/windows/classes/sun/awt/windows/WWindowPeer.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/windows/classes/sun/awt/windows/WWindowPeer.java	Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -22,23 +22,48 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
+
 package sun.awt.windows;
 
-import java.awt.*;
-import java.awt.event.*;
-import java.awt.image.*;
-import java.awt.peer.*;
-
-import java.beans.*;
+import java.awt.AWTEvent;
+import java.awt.AWTEventMulticaster;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.Dialog;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsDevice;
+import java.awt.GraphicsEnvironment;
+import java.awt.Image;
+import java.awt.Insets;
+import java.awt.KeyboardFocusManager;
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.awt.SystemColor;
+import java.awt.Window;
+import java.awt.event.FocusEvent;
+import java.awt.event.WindowEvent;
+import java.awt.event.WindowListener;
+import java.awt.geom.AffineTransform;
+import java.awt.image.DataBufferInt;
+import java.awt.peer.WindowPeer;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.util.LinkedList;
+import java.util.List;
 
-import java.util.*;
-import java.util.List;
-import sun.util.logging.PlatformLogger;
-import java.awt.geom.AffineTransform;
-import sun.awt.*;
-
+import sun.awt.AWTAccessor;
+import sun.awt.AppContext;
+import sun.awt.DisplayChangedListener;
+import sun.awt.SunToolkit;
+import sun.awt.Win32GraphicsConfig;
+import sun.awt.Win32GraphicsDevice;
+import sun.awt.Win32GraphicsEnvironment;
 import sun.java2d.pipe.Region;
 import sun.swing.SwingUtilities2;
+import sun.util.logging.PlatformLogger;
 
 public class WWindowPeer extends WPanelPeer implements WindowPeer,
        DisplayChangedListener
@@ -671,7 +696,7 @@
     public void print(Graphics g) {
         // We assume we print the whole frame,
         // so we expect no clip was set previously
-        Shape shape = AWTAccessor.getWindowAccessor().getShape((Window)target);
+        Shape shape = ((Window)target).getShape();
         if (shape != null) {
             g.setClip(shape);
         }
--- a/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsDevice.cpp	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsDevice.cpp	Wed Nov 08 16:03:35 2017 -0500
@@ -632,22 +632,38 @@
 
 int AwtWin32GraphicsDevice::ScaleUpX(int x)
 {
-    return (int)ceil(x * scaleX);
+    return ClipRound(x * scaleX);
 }
 
 int AwtWin32GraphicsDevice::ScaleUpY(int y)
 {
-    return (int)ceil(y * scaleY);
+    return ClipRound(y * scaleY);
 }
 
 int AwtWin32GraphicsDevice::ScaleDownX(int x)
 {
-    return (int)ceil(x / scaleX);
+    return ClipRound(x / scaleX);
 }
 
 int AwtWin32GraphicsDevice::ScaleDownY(int y)
 {
-    return (int)ceil(y / scaleY);
+    return ClipRound(y / scaleY);
+}
+
+int AwtWin32GraphicsDevice::ClipRound(double value)
+{
+    value -= 0.5;
+    if (value < INT_MIN)
+    {
+        return INT_MIN;
+    }
+
+    if (value > INT_MAX)
+    {
+        return INT_MAX;
+    }
+
+    return (int)ceil(value);
 }
 
 void AwtWin32GraphicsDevice::InitDesktopScales()
--- a/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsDevice.h	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsDevice.h	Wed Nov 08 16:03:35 2017 -0500
@@ -119,6 +119,7 @@
     float                   scaleY;
 
     static HDC              MakeDCFromMonitor(HMONITOR);
+    static int              ClipRound(double value);
 };
 
 #endif AWT_WIN32GRAPHICSDEVICE_H
--- a/src/java.management/share/classes/java/lang/management/RuntimeMXBean.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.management/share/classes/java/lang/management/RuntimeMXBean.java	Wed Nov 08 16:03:35 2017 -0500
@@ -25,6 +25,9 @@
 
 package java.lang.management;
 
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
 /**
  * The management interface for the runtime system of
  * the Java virtual machine.
@@ -61,6 +64,22 @@
  */
 public interface RuntimeMXBean extends PlatformManagedObject {
     /**
+     * Returns the {@linkplain ProcessHandle#pid process ID} representing
+     * the running Java virtual machine.
+     *
+     * @implSpec The default implementation returns {@link ProcessHandle#pid process ID}
+     * of the {@linkplain ProcessHandle#current current process}.
+     *
+     * @return the process ID representing the running Java virtual machine.
+     *
+     * @since 10
+     */
+    public default long getPid() {
+        return AccessController.doPrivileged((PrivilegedAction<Long>)
+                () -> ProcessHandle.current().pid());
+    }
+
+    /**
      * Returns the name representing the running Java virtual machine.
      * The returned name string can be any arbitrary string and
      * a Java virtual machine implementation can choose
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Utility.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Utility.java	Wed Nov 08 16:03:35 2017 -0500
@@ -1,6 +1,6 @@
 /*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * @LastModified: Oct 2017
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -181,6 +181,7 @@
      * @throws IOException if a failure from reading from the bytes argument
      * occurs
      */
+    @SuppressWarnings("fallthrough") // by design for case Const.INSTANCEOF
     public static String codeToString(final ByteSequence bytes, final ConstantPool constant_pool,
             final boolean verbose) throws IOException {
         final short opcode = (short) bytes.readUnsignedByte();
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/BCELFactory.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/BCELFactory.java	Wed Nov 08 16:03:35 2017 -0500
@@ -1,6 +1,6 @@
 /*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * @LastModified: Oct 2017
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -175,6 +175,7 @@
 
 
     @Override
+    @SuppressWarnings("fallthrough") // by design for case Const.ANEWARRAY
     public void visitAllocationInstruction( final AllocationInstruction i ) {
         Type type;
         if (i instanceof CPInstruction) {
--- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/Message.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/Message.java	Wed Nov 08 16:03:35 2017 -0500
@@ -1,6 +1,6 @@
 /*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * @LastModified: Oct 2017
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -54,6 +54,7 @@
         return Type.Void;
     }
 
+    @SuppressWarnings("fallthrough") // at default
     public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
         final ConstantPoolGen cpg = classGen.getConstantPool();
         final InstructionList il = methodGen.getInstructionList();
--- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/Step.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/Step.java	Wed Nov 08 16:03:35 2017 -0500
@@ -232,6 +232,7 @@
         translateStep(classGen, methodGen, hasPredicates() ? _predicates.size() - 1 : -1);
     }
 
+    @SuppressWarnings("fallthrough") // at case NodeTest.ANODE and NodeTest.ELEMENT
     private void translateStep(ClassGenerator classGen,
                                MethodGenerator methodGen,
                                int predicateIndex) {
--- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/Whitespace.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/Whitespace.java	Wed Nov 08 16:03:35 2017 -0500
@@ -191,6 +191,7 @@
      * Scans through the rules vector and looks for a rule of higher
      * priority that contradicts the current rule.
      */
+    @SuppressWarnings("fallthrough") // case RULE_NAMESPACE
     private static WhitespaceRule findContradictingRule(List<WhitespaceRule> rules,
                                                         WhitespaceRule rule) {
         for (WhitespaceRule currentRule : rules) {
--- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/XPathLexer.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/XPathLexer.java	Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * @LastModified: Oct 2017
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -73,6 +74,7 @@
          * name instead of a keyword (Jira-1912). Look two tokens behind
          * to desambiguate expressions like "* and *" or "and * and".
          */
+        @SuppressWarnings("fallthrough")
         Symbol disambiguateOperator(int ss) throws Exception {
             switch (last) {
             case sym.STAR:
@@ -745,6 +747,7 @@
 ":13,-1:2,184:10,-1:3,76,184,76:3,-1:4,184:6,64,-1:2,76,-1:6,184:5,-1:3,184:" +
 "4,232,184:8,-1:2,184:10,-1:3,76,184,76:3");
 
+        @SuppressWarnings("fallthrough") // at case 18 and -1
         public com.sun.java_cup.internal.runtime.Symbol next_token ()
                 throws java.io.IOException,
 Exception
--- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/XPathParser.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/XPathParser.java	Wed Nov 08 16:03:35 2017 -0500
@@ -1591,13 +1591,13 @@
             RESULT = new CurrentCall(fname);
           }
           else if (fname == parser.getQNameIgnoreDefaultNs("number")) {
-            RESULT = new NumberCall(fname, parser.EmptyArgs);
+            RESULT = new NumberCall(fname, XPathParser.EmptyArgs);
           }
           else if (fname == parser.getQNameIgnoreDefaultNs("string")) {
-            RESULT = new StringCall(fname, parser.EmptyArgs);
+            RESULT = new StringCall(fname, XPathParser.EmptyArgs);
           }
           else if (fname == parser.getQNameIgnoreDefaultNs("concat")) {
-            RESULT = new ConcatCall(fname, parser.EmptyArgs);
+            RESULT = new ConcatCall(fname, XPathParser.EmptyArgs);
           }
           else if (fname == parser.getQNameIgnoreDefaultNs("true")) {
             RESULT = new BooleanExpr(true);
@@ -1609,10 +1609,10 @@
             RESULT = new NameCall(fname);
           }
           else if (fname == parser.getQNameIgnoreDefaultNs("generate-id")) {
-            RESULT = new GenerateIdCall(fname, parser.EmptyArgs);
+            RESULT = new GenerateIdCall(fname, XPathParser.EmptyArgs);
           }
           else if (fname == parser.getQNameIgnoreDefaultNs("string-length")) {
-            RESULT = new StringLengthCall(fname, parser.EmptyArgs);
+            RESULT = new StringLengthCall(fname, XPathParser.EmptyArgs);
           }
           else if (fname == parser.getQNameIgnoreDefaultNs("position")) {
             RESULT = new PositionCall(fname);
@@ -1627,7 +1627,7 @@
             RESULT = new NamespaceUriCall(fname);
           }
           else {
-            RESULT = new FunctionCall(fname, parser.EmptyArgs);
+            RESULT = new FunctionCall(fname, XPathParser.EmptyArgs);
           }
 
               parser_result = new Symbol(16/*FunctionCall*/, (parser_stack.get(parser_top-2)).left, (parser_stack.get(parser_top-0)).right, RESULT);
--- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/dom/SAXImpl.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/dom/SAXImpl.java	Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * @LastModified: Oct 2017
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -1278,11 +1279,13 @@
                     // For "attribute::p:*", the principal node kind is
                     // attribute
                     m_baseIterator = getAxisIterator(axis);
+                    break;
                 }
                 case Axis.NAMESPACE: {
                     // This covers "namespace::p:*".  It is syntactically
                     // correct, though it doesn't make much sense.
                     m_baseIterator = getAxisIterator(axis);
+                    break;
                 }
                 default: {
                     // In all other cases, the principal node kind is
--- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/runtime/output/TransletOutputHandlerFactory.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/runtime/output/TransletOutputHandlerFactory.java	Wed Nov 08 16:03:35 2017 -0500
@@ -1,6 +1,6 @@
 /*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * @LastModified: Oct 2017
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -145,6 +145,7 @@
         _indentNumber = value;
     }
 
+    @SuppressWarnings("fallthrough")  // intentional at case STAX, SAX
     public SerializationHandler getSerializationHandler()
         throws IOException, ParserConfigurationException
     {
--- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/DeferredDocumentTypeImpl.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/DeferredDocumentTypeImpl.java	Wed Nov 08 16:03:35 2017 -0500
@@ -1,6 +1,6 @@
 /*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * @LastModified: Oct 2017
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -161,8 +161,8 @@
                     if (((DocumentImpl)getOwnerDocument()).allowGrammarAccess){
                         insertBefore(node, last);
                         last = node;
-                        break;
                     }
+                    break;
                 }
 
                 // NOTE: Should never get here! -Ac
--- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/traversers/XSDElementTraverser.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/traversers/XSDElementTraverser.java	Wed Nov 08 16:03:35 2017 -0500
@@ -1,6 +1,6 @@
 /*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * @LastModified: Oct 2017
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -439,7 +439,7 @@
                         fSchemaHandler.checkForDuplicateNames(
                                 (schemaDoc.fTargetNamespace == null) ? ","+DOMUtil.getAttrValue(child, SchemaSymbols.ATT_NAME)
                                         : schemaDoc.fTargetNamespace+","+ DOMUtil.getAttrValue(child, SchemaSymbols.ATT_NAME),
-                                        fSchemaHandler.ATTRIBUTE_TYPE, fSchemaHandler.getIDRegistry(), fSchemaHandler.getIDRegistry_sub(),
+                                        XSDHandler.ATTRIBUTE_TYPE, fSchemaHandler.getIDRegistry(), fSchemaHandler.getIDRegistry_sub(),
                                         child, schemaDoc);
                     }
                 } else if (childName.equals(SchemaSymbols.ELT_KEYREF)) {
--- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/traversers/XSDHandler.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/traversers/XSDHandler.java	Wed Nov 08 16:03:35 2017 -0500
@@ -3025,6 +3025,7 @@
         return newComponents;
     }
 
+    @SuppressWarnings("fallthrough")
     private void expandRelatedComponents(XSObject component,List<XSObject>componentList, Map<String, List<String>> dependencies) {
         short componentType = component.getType();
         switch (componentType) {
--- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/parsers/AbstractDOMParser.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/parsers/AbstractDOMParser.java	Wed Nov 08 16:03:35 2017 -0500
@@ -600,6 +600,7 @@
      *
      * @throws XNIException Thrown by application to signal an error.
      */
+    @SuppressWarnings("fallthrough") // by design at case LSParserFilter.FILTER_SKIP
     public void comment (XMLString text, Augmentations augs) throws XNIException {
         if (fInDTD) {
             if (fInternalSubset != null && !fInDTDExternalSubset) {
@@ -673,6 +674,7 @@
      *
      * @throws XNIException Thrown by handler to signal an error.
      */
+    @SuppressWarnings("fallthrough") // by design at case LSParserFilter.FILTER_REJECT
     public void processingInstruction (String target, XMLString data, Augmentations augs)
     throws XNIException {
 
@@ -1416,6 +1418,7 @@
      *
      * @throws XNIException Thrown by handler to signal an error.
      */
+    @SuppressWarnings("fallthrough") // by design at case LSParserFilter.FILTER_REJECT
     public void endCDATA (Augmentations augs) throws XNIException {
 
         fInCDATASection = false;
@@ -2596,6 +2599,7 @@
      * or removed fFistChunk must be set to true, otherwise some data can be lost.
      *
      */
+    @SuppressWarnings("fallthrough") // by design at case LSParserFilter.FILTER_REJECT
     protected void  setCharacterData (boolean sawChars){
 
         // handle character data
--- a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/dtm/ref/DTMDocumentImpl.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/dtm/ref/DTMDocumentImpl.java	Wed Nov 08 16:03:35 2017 -0500
@@ -1,6 +1,6 @@
 /*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * @LastModified: Oct 2017
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -1697,6 +1697,7 @@
          * @return String Value of this node, or null if not
          * meaningful for this node type.
          */
+        @SuppressWarnings("fallthrough")
         public String getNodeValue(int nodeHandle)
         {
                 nodes.readSlot(nodeHandle, gotslot);
--- a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/dtm/ref/dom2dtm/DOM2DTM.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/dtm/ref/dom2dtm/DOM2DTM.java	Wed Nov 08 16:03:35 2017 -0500
@@ -1651,6 +1651,7 @@
    * @param node Node whose subtree is to be walked, gathering the
    * contents of all Text or CDATASection nodes.
    */
+  @SuppressWarnings("fallthrough")
   protected static void dispatchNodeData(Node node,
                                          org.xml.sax.ContentHandler ch,
                                          int depth)
--- a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serialize/BaseMarkupSerializer.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serialize/BaseMarkupSerializer.java	Wed Nov 08 16:03:35 2017 -0500
@@ -1020,6 +1020,7 @@
      * @throws IOException An I/O exception occured while
      *   serializing
      */
+    @SuppressWarnings("fallthrough") // by design at case Node.DOCUMENT_FRAGMENT_NODE
     protected void serializeNode( Node node )
         throws IOException
     {
--- a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/axes/FilterExprWalker.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/axes/FilterExprWalker.java	Wed Nov 08 16:03:35 2017 -0500
@@ -62,6 +62,7 @@
    *
    * @throws javax.xml.transform.TransformerException
    */
+  @SuppressWarnings("fallthrough")
   public void init(Compiler compiler, int opPos, int stepType)
           throws javax.xml.transform.TransformerException
   {
--- a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/axes/MatchPatternIterator.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/axes/MatchPatternIterator.java	Wed Nov 08 16:03:35 2017 -0500
@@ -1,6 +1,6 @@
 /*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * @LastModified: Oct 2017
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -299,7 +299,7 @@
         System.out.println(", "+m_cdtm.getNodeName(n));
         // if(m_cdtm.getNodeName(n).equals("near-east"))
         System.out.println("pattern: "+m_pattern.toString());
-        m_pattern.debugWhatToShow(m_pattern.getWhatToShow());
+        NodeTest.debugWhatToShow(m_pattern.getWhatToShow());
       }
 
       XObject score = m_pattern.execute(xctxt);
--- a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/axes/WalkerFactory.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/axes/WalkerFactory.java	Wed Nov 08 16:03:35 2017 -0500
@@ -1,6 +1,6 @@
 /*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * @LastModified: Oct 2017
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -554,6 +554,7 @@
    *
    * @throws javax.xml.transform.TransformerException
    */
+  @SuppressWarnings("fallthrough") // by design at case OpCodes.FROM_DESCENDANTS
   private static boolean isOptimizableForDescendantIterator(
           Compiler compiler, int stepOpCodePos, int stepIndex)
             throws javax.xml.transform.TransformerException
@@ -1102,7 +1103,7 @@
       System.out.print(", predAxis: " + Axis.getNames(ai.getAxis()));
       System.out.print(", what: ");
       System.out.print("    ");
-      ai.debugWhatToShow(ai.getWhatToShow());
+      NodeTest.debugWhatToShow(ai.getWhatToShow());
     }
 
     int argLen = compiler.getFirstPredicateOpPos(opPos);
@@ -1621,6 +1622,7 @@
    *
    * @throws javax.xml.transform.TransformerException
    */
+  @SuppressWarnings("fallthrough") // by design at case OpCodes.FROM_ROOT
   private static boolean isNaturalDocOrder(
           Compiler compiler, int stepOpCodePos, int stepIndex, int analysis)
             throws javax.xml.transform.TransformerException
--- a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/compiler/Lexer.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/compiler/Lexer.java	Wed Nov 08 16:03:35 2017 -0500
@@ -106,6 +106,7 @@
    *
    * @throws javax.xml.transform.TransformerException
    */
+  @SuppressWarnings("fallthrough") // on purpose at case '-', '(' and default
   void tokenize(String pat, List<String> targetStrings)
           throws javax.xml.transform.TransformerException
   {
--- a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/patterns/ContextMatchStepPattern.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/patterns/ContextMatchStepPattern.java	Wed Nov 08 16:03:35 2017 -0500
@@ -1,6 +1,6 @@
 /*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * @LastModified: Oct 2017
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -65,7 +65,7 @@
     if (xctxt.getIteratorRoot() == xctxt.getCurrentNode())
       return getStaticScore();
     else
-      return this.SCORE_NONE;
+      return NodeTest.SCORE_NONE;
   }
 
   /**
--- a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/patterns/StepPattern.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/patterns/StepPattern.java	Wed Nov 08 16:03:35 2017 -0500
@@ -116,7 +116,7 @@
       m_targetString = PsuedoNames.PSEUDONAME_ROOT;
       break;
     case DTMFilter.SHOW_ELEMENT :
-      if (this.WILD == m_name)
+      if (WILD.equals(m_name))
         m_targetString = PsuedoNames.PSEUDONAME_ANY;
       else
         m_targetString = m_name;
--- a/src/java.xml/share/classes/org/xml/sax/helpers/ParserAdapter.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/java.xml/share/classes/org/xml/sax/helpers/ParserAdapter.java	Wed Nov 08 16:03:35 2017 -0500
@@ -586,7 +586,7 @@
                             // note funky case:  localname can be null
                             // when declaring the default prefix, and
                             // yet the uri isn't null.
-                            atts.addAttribute (nsSupport.XMLNS, prefix,
+                            atts.addAttribute (NamespaceSupport.XMLNS, prefix,
                                     attQName.intern(), type, value);
                         else
                             atts.addAttribute ("", "",
--- a/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/BinaryContainer.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/BinaryContainer.java	Wed Nov 08 16:03:35 2017 -0500
@@ -192,6 +192,8 @@
 
         {"StubRoutines::_checkcast_arraycopy", "_aot_stub_routines_checkcast_arraycopy"},
 
+        {"StubRoutines::_generic_arraycopy", "_aot_stub_routines_generic_arraycopy"},
+
         {"StubRoutines::_aescrypt_encryptBlock", "_aot_stub_routines_aescrypt_encryptBlock"},
         {"StubRoutines::_aescrypt_decryptBlock", "_aot_stub_routines_aescrypt_decryptBlock"},
         {"StubRoutines::_cipherBlockChaining_encryptAESCrypt", "_aot_stub_routines_cipherBlockChaining_encryptAESCrypt"},
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java	Wed Nov 08 16:03:35 2017 -0500
@@ -1473,11 +1473,6 @@
                 d.packge.modle = msym;
             }
         }
-
-        if (!allowAccessIntoSystem && (msym.flags() & Flags.SYSTEM_MODULE) != 0 &&
-            msym.patchLocation != null) {
-            log.error(Errors.PatchModuleWithRelease(msym));
-        }
     }
 
     private Set<ModuleSymbol> retrieveRequiresTransitive(ModuleSymbol msym) {
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties	Wed Nov 08 16:03:35 2017 -0500
@@ -3126,10 +3126,6 @@
 compiler.err.add.reads.with.release=\
     adding read edges for system module {0} is not allowed with --release
 
-# 0: symbol
-compiler.err.patch.module.with.release=\
-    patching system module {0} is not allowed in combination with --release
-
 compiler.warn.addopens.ignored=\
     --add-opens has no effect at compile time
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.api.directives.test/src/org/graalvm/compiler/api/directives/test/BlackholeDirectiveTest.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.api.directives.test/src/org/graalvm/compiler/api/directives/test/BlackholeDirectiveTest.java	Wed Nov 08 16:03:35 2017 -0500
@@ -34,6 +34,9 @@
 import org.graalvm.compiler.core.test.GraalCompilerTest;
 import org.graalvm.compiler.nodes.ParameterNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.phases.OptimisticOptimizations;
+import org.graalvm.compiler.phases.OptimisticOptimizations.Optimization;
+import org.graalvm.compiler.phases.tiers.HighTierContext;
 
 /**
  * Tests for {@link GraalDirectives#blackhole}.
@@ -129,6 +132,11 @@
     }
 
     @Override
+    protected HighTierContext getDefaultHighTierContext() {
+        return new HighTierContext(getProviders(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL.remove(Optimization.RemoveNeverExecutedCode));
+    }
+
+    @Override
     protected boolean checkLowTierGraph(StructuredGraph graph) {
         BlackholeSnippet snippet = graph.method().getAnnotation(BlackholeSnippet.class);
         ParameterNode arg = graph.getParameter(0);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.api.directives.test/src/org/graalvm/compiler/api/directives/test/ControlFlowAnchorDirectiveTest.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.api.directives.test/src/org/graalvm/compiler/api/directives/test/ControlFlowAnchorDirectiveTest.java	Wed Nov 08 16:03:35 2017 -0500
@@ -46,6 +46,9 @@
 import org.graalvm.compiler.nodes.debug.ControlFlowAnchorNode;
 
 import jdk.vm.ci.meta.ResolvedJavaMethod;
+import org.graalvm.compiler.phases.OptimisticOptimizations;
+import org.graalvm.compiler.phases.OptimisticOptimizations.Optimization;
+import org.graalvm.compiler.phases.tiers.HighTierContext;
 
 public class ControlFlowAnchorDirectiveTest extends GraalCompilerTest {
 
@@ -239,6 +242,11 @@
     }
 
     @Override
+    protected HighTierContext getDefaultHighTierContext() {
+        return new HighTierContext(getProviders(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL.remove(Optimization.RemoveNeverExecutedCode));
+    }
+
+    @Override
     protected boolean checkLowTierGraph(StructuredGraph graph) {
         List<ControlFlowAnchorNode> anchors = graph.getNodes().filter(ControlFlowAnchorNode.class).snapshot();
         for (int i = 0; i < anchors.size(); i++) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.api.directives.test/src/org/graalvm/compiler/api/directives/test/OpaqueDirectiveTest.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.api.directives.test/src/org/graalvm/compiler/api/directives/test/OpaqueDirectiveTest.java	Wed Nov 08 16:03:35 2017 -0500
@@ -37,6 +37,9 @@
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.calc.AddNode;
 import org.graalvm.compiler.nodes.calc.ConditionalNode;
+import org.graalvm.compiler.phases.OptimisticOptimizations;
+import org.graalvm.compiler.phases.OptimisticOptimizations.Optimization;
+import org.graalvm.compiler.phases.tiers.HighTierContext;
 
 /**
  * Tests for {@link GraalDirectives#opaque}.
@@ -128,6 +131,11 @@
     }
 
     @Override
+    protected HighTierContext getDefaultHighTierContext() {
+        return new HighTierContext(getProviders(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL.remove(Optimization.RemoveNeverExecutedCode));
+    }
+
+    @Override
     protected boolean checkLowTierGraph(StructuredGraph graph) {
         OpaqueSnippet snippet = graph.method().getAnnotation(OpaqueSnippet.class);
         for (ReturnNode returnNode : graph.getNodes(ReturnNode.TYPE)) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.api.replacements/src/org/graalvm/compiler/api/replacements/Snippet.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.api.replacements/src/org/graalvm/compiler/api/replacements/Snippet.java	Wed Nov 08 16:03:35 2017 -0500
@@ -36,6 +36,13 @@
 public @interface Snippet {
 
     /**
+     * A partial intrinsic exits by (effectively) calling the intrinsified method. Normally, this
+     * call must use exactly the same arguments as the call that is being intrinsified. For well
+     * known snippets that are used after frame state assignment, we want to relax this restriction.
+     */
+    boolean allowPartialIntrinsicArgumentMismatch() default false;
+
+    /**
      * Denotes a snippet parameter representing 0 or more arguments that will be bound during
      * snippet template instantiation. During snippet template creation, its value must be an array
      * whose length specifies the number of arguments (the contents of the array are ignored) bound
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64Assembler.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64Assembler.java	Wed Nov 08 16:03:35 2017 -0500
@@ -22,10 +22,14 @@
  */
 package org.graalvm.compiler.asm.amd64;
 
-import static org.graalvm.compiler.core.common.NumUtil.isByte;
-import static org.graalvm.compiler.core.common.NumUtil.isInt;
-import static org.graalvm.compiler.core.common.NumUtil.isShiftCount;
-import static org.graalvm.compiler.core.common.NumUtil.isUByte;
+import static jdk.vm.ci.amd64.AMD64.CPU;
+import static jdk.vm.ci.amd64.AMD64.XMM;
+import static jdk.vm.ci.amd64.AMD64.r12;
+import static jdk.vm.ci.amd64.AMD64.r13;
+import static jdk.vm.ci.amd64.AMD64.rbp;
+import static jdk.vm.ci.amd64.AMD64.rip;
+import static jdk.vm.ci.amd64.AMD64.rsp;
+import static jdk.vm.ci.code.MemoryBarriers.STORE_LOAD;
 import static org.graalvm.compiler.asm.amd64.AMD64AsmOptions.UseAddressNop;
 import static org.graalvm.compiler.asm.amd64.AMD64AsmOptions.UseNormalNop;
 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.ADD;
@@ -47,25 +51,24 @@
 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.SD;
 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.SS;
 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.WORD;
-import static jdk.vm.ci.amd64.AMD64.CPU;
-import static jdk.vm.ci.amd64.AMD64.XMM;
-import static jdk.vm.ci.amd64.AMD64.r12;
-import static jdk.vm.ci.amd64.AMD64.r13;
-import static jdk.vm.ci.amd64.AMD64.rbp;
-import static jdk.vm.ci.amd64.AMD64.rip;
-import static jdk.vm.ci.amd64.AMD64.rsp;
-import static jdk.vm.ci.code.MemoryBarriers.STORE_LOAD;
+import static org.graalvm.compiler.core.common.NumUtil.isByte;
+import static org.graalvm.compiler.core.common.NumUtil.isInt;
+import static org.graalvm.compiler.core.common.NumUtil.isShiftCount;
+import static org.graalvm.compiler.core.common.NumUtil.isUByte;
 
 import org.graalvm.compiler.asm.Assembler;
 import org.graalvm.compiler.asm.Label;
+import org.graalvm.compiler.asm.amd64.AMD64Address.Scale;
 import org.graalvm.compiler.core.common.NumUtil;
-import org.graalvm.compiler.asm.amd64.AMD64Address.Scale;
+import org.graalvm.compiler.debug.GraalError;
 
 import jdk.vm.ci.amd64.AMD64;
 import jdk.vm.ci.amd64.AMD64.CPUFeature;
+import jdk.vm.ci.amd64.AMD64Kind;
 import jdk.vm.ci.code.Register;
 import jdk.vm.ci.code.Register.RegisterCategory;
 import jdk.vm.ci.code.TargetDescription;
+import jdk.vm.ci.meta.PlatformKind;
 
 /**
  * This class implements an assembler that can encode most X86 instructions.
@@ -225,7 +228,7 @@
      * The x86 operand sizes.
      */
     public enum OperandSize {
-        BYTE(1) {
+        BYTE(1, AMD64Kind.BYTE) {
             @Override
             protected void emitImmediate(AMD64Assembler asm, int imm) {
                 assert imm == (byte) imm;
@@ -238,7 +241,7 @@
             }
         },
 
-        WORD(2, 0x66) {
+        WORD(2, AMD64Kind.WORD, 0x66) {
             @Override
             protected void emitImmediate(AMD64Assembler asm, int imm) {
                 assert imm == (short) imm;
@@ -251,7 +254,7 @@
             }
         },
 
-        DWORD(4) {
+        DWORD(4, AMD64Kind.DWORD) {
             @Override
             protected void emitImmediate(AMD64Assembler asm, int imm) {
                 asm.emitInt(imm);
@@ -263,7 +266,7 @@
             }
         },
 
-        QWORD(8) {
+        QWORD(8, AMD64Kind.QWORD) {
             @Override
             protected void emitImmediate(AMD64Assembler asm, int imm) {
                 asm.emitInt(imm);
@@ -275,34 +278,35 @@
             }
         },
 
-        SS(4, 0xF3, true),
-
-        SD(8, 0xF2, true),
-
-        PS(16, true),
-
-        PD(16, 0x66, true);
+        SS(4, AMD64Kind.SINGLE, 0xF3, true),
+
+        SD(8, AMD64Kind.DOUBLE, 0xF2, true),
+
+        PS(16, AMD64Kind.V128_SINGLE, true),
+
+        PD(16, AMD64Kind.V128_DOUBLE, 0x66, true);
 
         private final int sizePrefix;
-
         private final int bytes;
         private final boolean xmm;
-
-        OperandSize(int bytes) {
-            this(bytes, 0);
+        private final AMD64Kind kind;
+
+        OperandSize(int bytes, AMD64Kind kind) {
+            this(bytes, kind, 0);
         }
 
-        OperandSize(int bytes, int sizePrefix) {
-            this(bytes, sizePrefix, false);
+        OperandSize(int bytes, AMD64Kind kind, int sizePrefix) {
+            this(bytes, kind, sizePrefix, false);
         }
 
-        OperandSize(int bytes, boolean xmm) {
-            this(bytes, 0, xmm);
+        OperandSize(int bytes, AMD64Kind kind, boolean xmm) {
+            this(bytes, kind, 0, xmm);
         }
 
-        OperandSize(int bytes, int sizePrefix, boolean xmm) {
+        OperandSize(int bytes, AMD64Kind kind, int sizePrefix, boolean xmm) {
             this.sizePrefix = sizePrefix;
             this.bytes = bytes;
+            this.kind = kind;
             this.xmm = xmm;
         }
 
@@ -314,6 +318,19 @@
             return xmm;
         }
 
+        public AMD64Kind getKind() {
+            return kind;
+        }
+
+        public static OperandSize get(PlatformKind kind) {
+            for (OperandSize operandSize : OperandSize.values()) {
+                if (operandSize.kind.equals(kind)) {
+                    return operandSize;
+                }
+            }
+            throw GraalError.shouldNotReachHere("Unexpected kind: " + kind.toString());
+        }
+
         /**
          * Emit an immediate of this size. Note that immediate {@link #QWORD} operands are encoded
          * as sign-extended 32-bit values.
@@ -2230,6 +2247,14 @@
         emitOperandHelper(dst, src, 0);
     }
 
+    public final void movzbl(Register dst, Register src) {
+        AMD64RMOp.MOVZXB.emit(this, OperandSize.DWORD, dst, src);
+    }
+
+    public final void movzbq(Register dst, Register src) {
+        AMD64RMOp.MOVZXB.emit(this, OperandSize.QWORD, dst, src);
+    }
+
     public final void movzwl(Register dst, AMD64Address src) {
         prefix(src, dst);
         emitByte(0x0F);
@@ -3198,6 +3223,13 @@
         emitByte(0xC0 | encode);
     }
 
+    public final void setb(ConditionFlag cc, Register dst) {
+        int encode = prefixAndEncode(dst.encoding, true);
+        emitByte(0x0F);
+        emitByte(0x90 | cc.getValue());
+        emitByte(0xC0 | encode);
+    }
+
     public final void cmovq(ConditionFlag cc, Register dst, AMD64Address src) {
         prefixq(src, dst);
         emitByte(0x0F);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64MacroAssembler.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64MacroAssembler.java	Wed Nov 08 16:03:35 2017 -0500
@@ -31,8 +31,8 @@
 import static org.graalvm.compiler.asm.amd64.AMD64AsmOptions.UseXmmRegToRegMoveAll;
 
 import org.graalvm.compiler.asm.Label;
+import org.graalvm.compiler.asm.amd64.AMD64Address.Scale;
 import org.graalvm.compiler.core.common.NumUtil;
-import org.graalvm.compiler.asm.amd64.AMD64Address.Scale;
 
 import jdk.vm.ci.amd64.AMD64;
 import jdk.vm.ci.amd64.AMD64Kind;
@@ -281,6 +281,16 @@
 
     }
 
+    public final void setl(ConditionFlag cc, Register dst) {
+        setb(cc, dst);
+        movzbl(dst, dst);
+    }
+
+    public final void setq(ConditionFlag cc, Register dst) {
+        setb(cc, dst);
+        movzbq(dst, dst);
+    }
+
     public final void flog(Register dest, Register value, boolean base10) {
         if (base10) {
             fldlg2();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64.test/src/org/graalvm/compiler/core/amd64/test/AMD64AddressLoweringTest.java	Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 org.graalvm.compiler.core.amd64.test;
+
+import static org.junit.Assume.assumeTrue;
+
+import org.graalvm.compiler.asm.amd64.AMD64Address.Scale;
+import org.graalvm.compiler.core.amd64.AMD64AddressLowering;
+import org.graalvm.compiler.core.amd64.AMD64AddressNode;
+import org.graalvm.compiler.core.test.GraalCompilerTest;
+import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.ValueNode;
+import org.graalvm.compiler.nodes.calc.AddNode;
+import org.graalvm.compiler.nodes.calc.LeftShiftNode;
+import org.graalvm.compiler.nodes.calc.NegateNode;
+import org.graalvm.compiler.nodes.memory.address.AddressNode;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import jdk.vm.ci.amd64.AMD64;
+
+public class AMD64AddressLoweringTest extends GraalCompilerTest {
+
+    private StructuredGraph graph;
+    private AMD64AddressLowering lowering;
+
+    @Before
+    public void checkAMD64() {
+        assumeTrue("skipping AMD64 specific test", getTarget().arch instanceof AMD64);
+        graph = new StructuredGraph.Builder(getInitialOptions(), getDebugContext()).build();
+        lowering = new AMD64AddressLowering();
+    }
+
+    @Test
+    public void convertBaseAndIndexToDisplacement() {
+        ValueNode base = graph.unique(const64(1000));
+        ValueNode index = graph.unique(const64(10));
+        AddressNode result = lowering.lower(base, index);
+        assertAddress(result, null, null, Scale.Times1, 1010);
+    }
+
+    @Test
+    public void convertBaseToDisplacement() {
+        ValueNode constantAddress = graph.addOrUniqueWithInputs(const64(1000));
+        AddressNode result = lowering.lower(constantAddress, null);
+        assertAddress(result, null, null, Scale.Times1, 1000);
+    }
+
+    @Test
+    public void convertBaseAndShiftedIndexToDisplacement() {
+        ValueNode base = graph.addOrUniqueWithInputs(const64(1000));
+        ValueNode index = graph.addOrUniqueWithInputs(new LeftShiftNode(const64(10), const32(1)));
+        AddressNode result = lowering.lower(base, index);
+        assertAddress(result, null, null, Scale.Times2, 1020);
+    }
+
+    @Test
+    public void convertBaseAndNegatedShiftedIndexToDisplacement() {
+        ValueNode base = graph.addOrUniqueWithInputs(const64(1000));
+        ValueNode index = graph.addOrUniqueWithInputs(new NegateNode(new LeftShiftNode(const64(10), const32(2))));
+        AddressNode result = lowering.lower(base, index);
+        assertAddress(result, null, null, Scale.Times4, 960);
+    }
+
+    @Test
+    public void convertNegatedBaseAndNegatedShiftedIndexToDisplacement() {
+        ValueNode base = graph.addOrUniqueWithInputs(new NegateNode(const64(1000)));
+        ValueNode index = graph.addOrUniqueWithInputs(new NegateNode(new LeftShiftNode(const64(10), const32(2))));
+        AddressNode result = lowering.lower(base, index);
+        assertAddress(result, null, null, Scale.Times4, -1040);
+    }
+
+    @Test
+    public void convertNegatedShiftedBaseAndNegatedIndexToDisplacement() {
+        ValueNode base = graph.addOrUniqueWithInputs(new NegateNode(new LeftShiftNode(const64(10), const32(2))));
+        ValueNode index = graph.addOrUniqueWithInputs(new NegateNode(const64(1000)));
+        AddressNode result = lowering.lower(base, index);
+        assertAddress(result, null, null, Scale.Times4, -1040);
+    }
+
+    @Test
+    public void convertTwoLevelsOfNegatedShiftedBaseAndNegatedIndexToDisplacement() {
+        ValueNode base = graph.addOrUniqueWithInputs(new NegateNode(new LeftShiftNode(new NegateNode(new LeftShiftNode(const64(500), const32(1))), const32(1))));
+        ValueNode index = graph.addOrUniqueWithInputs(new NegateNode(new AddNode(new NegateNode(const64(13)), const64(3))));
+        AddressNode result = lowering.lower(base, index);
+        assertAddress(result, null, null, Scale.Times4, 2010);
+    }
+
+    private static ConstantNode const64(long value) {
+        return ConstantNode.forIntegerBits(Long.SIZE, value);
+    }
+
+    private static ConstantNode const32(long value) {
+        return ConstantNode.forIntegerBits(Integer.SIZE, value);
+    }
+
+    private static void assertAddress(AddressNode actual, ValueNode expectedBase, ValueNode expectedIndex, Scale expectedScale, int expectedDisplacement) {
+        AMD64AddressNode address = (AMD64AddressNode) actual;
+        Assert.assertEquals(expectedBase, address.getBase());
+        Assert.assertEquals(expectedIndex, address.getIndex());
+        Assert.assertEquals(expectedScale, address.getScale());
+        Assert.assertEquals(expectedDisplacement, address.getDisplacement());
+    }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64AddressLowering.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64AddressLowering.java	Wed Nov 08 16:03:35 2017 -0500
@@ -23,21 +23,22 @@
 
 package org.graalvm.compiler.core.amd64;
 
-import jdk.vm.ci.meta.JavaConstant;
-
+import org.graalvm.compiler.asm.amd64.AMD64Address.Scale;
 import org.graalvm.compiler.core.common.NumUtil;
-import org.graalvm.compiler.asm.amd64.AMD64Address.Scale;
 import org.graalvm.compiler.core.common.type.IntegerStamp;
 import org.graalvm.compiler.debug.DebugContext;
+import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.AddNode;
 import org.graalvm.compiler.nodes.calc.LeftShiftNode;
+import org.graalvm.compiler.nodes.calc.NegateNode;
 import org.graalvm.compiler.nodes.calc.ZeroExtendNode;
 import org.graalvm.compiler.nodes.memory.address.AddressNode;
 import org.graalvm.compiler.phases.common.AddressLoweringPhase.AddressLowering;
 
+import jdk.vm.ci.meta.JavaConstant;
+
 public class AMD64AddressLowering extends AddressLowering {
-
     @Override
     public AddressNode lower(ValueNode address) {
         return lower(address, null);
@@ -46,24 +47,37 @@
     @Override
     public AddressNode lower(ValueNode base, ValueNode offset) {
         AMD64AddressNode ret = new AMD64AddressNode(base, offset);
+        StructuredGraph graph = base.graph();
+
         boolean changed;
         do {
-            changed = improve(base.getDebug(), ret);
+            changed = improve(graph, base.getDebug(), ret, false, false);
         } while (changed);
-        return base.graph().unique(ret);
+
+        return graph.unique(ret);
     }
 
     /**
-     * @param debug
+     * Tries to optimize addresses so that they match the AMD64-specific addressing mode better
+     * (base + index * scale + displacement).
+     *
+     * @param graph the current graph
+     * @param debug the current debug context
+     * @param ret the address that should be optimized
+     * @param isBaseNegated determines if the address base is negated. if so, all values that are
+     *            extracted from the base will be negated as well
+     * @param isIndexNegated determines if the index is negated. if so, all values that are
+     *            extracted from the index will be negated as well
+     * @return true if the address was modified
      */
-    protected boolean improve(DebugContext debug, AMD64AddressNode ret) {
-        ValueNode newBase = improveInput(ret, ret.getBase(), 0);
+    protected boolean improve(StructuredGraph graph, DebugContext debug, AMD64AddressNode ret, boolean isBaseNegated, boolean isIndexNegated) {
+        ValueNode newBase = improveInput(ret, ret.getBase(), 0, isBaseNegated);
         if (newBase != ret.getBase()) {
             ret.setBase(newBase);
             return true;
         }
 
-        ValueNode newIdx = improveInput(ret, ret.getIndex(), ret.getScale().log2);
+        ValueNode newIdx = improveInput(ret, ret.getIndex(), ret.getScale().log2, isIndexNegated);
         if (newIdx != ret.getIndex()) {
             ret.setIndex(newIdx);
             return true;
@@ -83,55 +97,122 @@
         }
 
         if (ret.getScale() == Scale.Times1) {
-            if (ret.getBase() == null || ret.getIndex() == null) {
-                if (ret.getBase() instanceof AddNode) {
-                    AddNode add = (AddNode) ret.getBase();
-                    ret.setBase(add.getX());
-                    ret.setIndex(add.getY());
-                    return true;
-                } else if (ret.getIndex() instanceof AddNode) {
-                    AddNode add = (AddNode) ret.getIndex();
-                    ret.setBase(add.getX());
-                    ret.setIndex(add.getY());
-                    return true;
-                }
+            if (ret.getIndex() == null && ret.getBase() instanceof AddNode) {
+                AddNode add = (AddNode) ret.getBase();
+                ret.setBase(add.getX());
+                ret.setIndex(considerNegation(graph, add.getY(), isBaseNegated));
+                return true;
+            } else if (ret.getBase() == null && ret.getIndex() instanceof AddNode) {
+                AddNode add = (AddNode) ret.getIndex();
+                ret.setBase(considerNegation(graph, add.getX(), isIndexNegated));
+                ret.setIndex(add.getY());
+                return true;
             }
 
             if (ret.getBase() instanceof LeftShiftNode && !(ret.getIndex() instanceof LeftShiftNode)) {
                 ValueNode tmp = ret.getBase();
-                ret.setBase(ret.getIndex());
-                ret.setIndex(tmp);
+                ret.setBase(considerNegation(graph, ret.getIndex(), isIndexNegated != isBaseNegated));
+                ret.setIndex(considerNegation(graph, tmp, isIndexNegated != isBaseNegated));
                 return true;
             }
         }
 
+        return improveNegation(graph, debug, ret, isBaseNegated, isIndexNegated);
+    }
+
+    private boolean improveNegation(StructuredGraph graph, DebugContext debug, AMD64AddressNode ret, boolean originalBaseNegated, boolean originalIndexNegated) {
+        boolean baseNegated = originalBaseNegated;
+        boolean indexNegated = originalIndexNegated;
+
+        ValueNode originalBase = ret.getBase();
+        ValueNode originalIndex = ret.getIndex();
+
+        if (ret.getBase() instanceof NegateNode) {
+            NegateNode negate = (NegateNode) ret.getBase();
+            ret.setBase(negate.getValue());
+            baseNegated = !baseNegated;
+        }
+
+        if (ret.getIndex() instanceof NegateNode) {
+            NegateNode negate = (NegateNode) ret.getIndex();
+            ret.setIndex(negate.getValue());
+            indexNegated = !indexNegated;
+        }
+
+        if (baseNegated != originalBaseNegated || indexNegated != originalIndexNegated) {
+            ValueNode base = ret.getBase();
+            ValueNode index = ret.getIndex();
+
+            boolean improved = improve(graph, debug, ret, baseNegated, indexNegated);
+            if (baseNegated != originalBaseNegated) {
+                if (base == ret.getBase()) {
+                    ret.setBase(originalBase);
+                } else if (ret.getBase() != null) {
+                    ret.setBase(graph.maybeAddOrUnique(NegateNode.create(ret.getBase())));
+                }
+            }
+
+            if (indexNegated != originalIndexNegated) {
+                if (index == ret.getIndex()) {
+                    ret.setIndex(originalIndex);
+                } else if (ret.getIndex() != null) {
+                    ret.setIndex(graph.maybeAddOrUnique(NegateNode.create(ret.getIndex())));
+                }
+            }
+            return improved;
+        } else {
+            assert ret.getBase() == originalBase && ret.getIndex() == originalIndex;
+        }
         return false;
     }
 
-    private static ValueNode improveInput(AMD64AddressNode address, ValueNode node, int shift) {
+    private static ValueNode considerNegation(StructuredGraph graph, ValueNode value, boolean negate) {
+        if (negate && value != null) {
+            return graph.maybeAddOrUnique(NegateNode.create(value));
+        }
+        return value;
+    }
+
+    private ValueNode improveInput(AMD64AddressNode address, ValueNode node, int shift, boolean negateExtractedDisplacement) {
         if (node == null) {
             return null;
         }
 
         JavaConstant c = node.asJavaConstant();
         if (c != null) {
-            return improveConstDisp(address, node, c, null, shift);
+            return improveConstDisp(address, node, c, null, shift, negateExtractedDisplacement);
         } else {
-            if (node.stamp() instanceof IntegerStamp && ((IntegerStamp) node.stamp()).getBits() == 64) {
-                if (node instanceof ZeroExtendNode) {
-                    if (((ZeroExtendNode) node).getInputBits() == 32) {
-                        /*
-                         * We can just swallow a zero-extend from 32 bit to 64 bit because the upper
-                         * half of the register will always be zero.
-                         */
-                        return ((ZeroExtendNode) node).getValue();
+            if (node.stamp() instanceof IntegerStamp) {
+                if (node instanceof ZeroExtendNode && (((ZeroExtendNode) node).getInputBits() == 32)) {
+                    /*
+                     * we can't just swallow all zero-extends as we might encounter something like
+                     * the following: ZeroExtend(Add(negativeValue, positiveValue)).
+                     *
+                     * if we swallow the zero-extend in this case and subsequently optimize the add,
+                     * we might end up with a negative value that has less than 64 bits in base or
+                     * index. such a value would require sign extension instead of zero-extension
+                     * but the backend can only do zero-extension. if we ever want to optimize that
+                     * further, we would also need to be careful about over-/underflows.
+                     *
+                     * furthermore, we also can't swallow zero-extends with less than 32 bits as
+                     * most of these values are immediately sign-extended to 32 bit by the backend
+                     * (therefore, the subsequent implicit zero-extension to 64 bit won't do what we
+                     * expect).
+                     */
+                    ValueNode value = ((ZeroExtendNode) node).getValue();
+                    if (!mightBeOptimized(value)) {
+                        // if the value is not optimized further by the address lowering, then we
+                        // can safely rely on the backend doing the implicitly zero-extension.
+                        return value;
                     }
-                } else if (node instanceof AddNode) {
+                }
+
+                if (node instanceof AddNode) {
                     AddNode add = (AddNode) node;
                     if (add.getX().isConstant()) {
-                        return improveConstDisp(address, node, add.getX().asJavaConstant(), add.getY(), shift);
+                        return improveConstDisp(address, node, add.getX().asJavaConstant(), add.getY(), shift, negateExtractedDisplacement);
                     } else if (add.getY().isConstant()) {
-                        return improveConstDisp(address, node, add.getY().asJavaConstant(), add.getX(), shift);
+                        return improveConstDisp(address, node, add.getY().asJavaConstant(), add.getX(), shift, negateExtractedDisplacement);
                     }
                 }
             }
@@ -140,15 +221,30 @@
         return node;
     }
 
-    private static ValueNode improveConstDisp(AMD64AddressNode address, ValueNode original, JavaConstant c, ValueNode other, int shift) {
+    /**
+     * This method returns true for all nodes that might be optimized by the address lowering.
+     */
+    protected boolean mightBeOptimized(ValueNode value) {
+        return value instanceof AddNode || value instanceof LeftShiftNode || value instanceof NegateNode || value instanceof ZeroExtendNode;
+    }
+
+    private static ValueNode improveConstDisp(AMD64AddressNode address, ValueNode original, JavaConstant c, ValueNode other, int shift, boolean negateExtractedDisplacement) {
         if (c.getJavaKind().isNumericInteger()) {
-            long disp = address.getDisplacement();
-            disp += c.asLong() << shift;
-            if (NumUtil.isInt(disp)) {
-                address.setDisplacement((int) disp);
+            long delta = c.asLong() << shift;
+            if (updateDisplacement(address, delta, negateExtractedDisplacement)) {
                 return other;
             }
         }
         return original;
     }
+
+    protected static boolean updateDisplacement(AMD64AddressNode address, long displacementDelta, boolean negateDelta) {
+        long sign = negateDelta ? -1 : 1;
+        long disp = address.getDisplacement() + displacementDelta * sign;
+        if (NumUtil.isInt(disp)) {
+            address.setDisplacement((int) disp);
+            return true;
+        }
+        return false;
+    }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64LIRGenerator.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64LIRGenerator.java	Wed Nov 08 16:03:35 2017 -0500
@@ -33,15 +33,17 @@
 import static org.graalvm.compiler.lir.LIRValueUtil.asConstantValue;
 import static org.graalvm.compiler.lir.LIRValueUtil.asJavaConstant;
 import static org.graalvm.compiler.lir.LIRValueUtil.isConstantValue;
+import static org.graalvm.compiler.lir.LIRValueUtil.isIntConstant;
 import static org.graalvm.compiler.lir.LIRValueUtil.isJavaConstant;
 
-import org.graalvm.compiler.core.common.NumUtil;
+import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic;
 import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64MIOp;
 import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMOp;
 import org.graalvm.compiler.asm.amd64.AMD64Assembler.ConditionFlag;
 import org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize;
 import org.graalvm.compiler.asm.amd64.AMD64Assembler.SSEOp;
 import org.graalvm.compiler.core.common.LIRKind;
+import org.graalvm.compiler.core.common.NumUtil;
 import org.graalvm.compiler.core.common.calc.Condition;
 import org.graalvm.compiler.core.common.spi.ForeignCallLinkage;
 import org.graalvm.compiler.core.common.spi.LIRKindTool;
@@ -58,13 +60,17 @@
 import org.graalvm.compiler.lir.amd64.AMD64AddressValue;
 import org.graalvm.compiler.lir.amd64.AMD64ArithmeticLIRGeneratorTool;
 import org.graalvm.compiler.lir.amd64.AMD64ArrayEqualsOp;
+import org.graalvm.compiler.lir.amd64.AMD64Binary;
 import org.graalvm.compiler.lir.amd64.AMD64BinaryConsumer;
 import org.graalvm.compiler.lir.amd64.AMD64ByteSwapOp;
 import org.graalvm.compiler.lir.amd64.AMD64Call;
+import org.graalvm.compiler.lir.amd64.AMD64ControlFlow;
 import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.BranchOp;
 import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.CondMoveOp;
+import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.CondSetOp;
 import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.FloatBranchOp;
 import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.FloatCondMoveOp;
+import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.FloatCondSetOp;
 import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.ReturnOp;
 import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.StrategySwitchOp;
 import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.TableSwitchOp;
@@ -257,8 +263,7 @@
 
     @Override
     public void emitCompareBranch(PlatformKind cmpKind, Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef trueLabel, LabelRef falseLabel, double trueLabelProbability) {
-        boolean mirrored = emitCompare(cmpKind, left, right);
-        Condition finalCondition = mirrored ? cond.mirror() : cond;
+        Condition finalCondition = emitCompare(cmpKind, left, right, cond);
         if (cmpKind == AMD64Kind.SINGLE || cmpKind == AMD64Kind.DOUBLE) {
             append(new FloatBranchOp(finalCondition, unorderedIsTrue, trueLabel, falseLabel, trueLabelProbability));
         } else {
@@ -290,14 +295,60 @@
 
     @Override
     public Variable emitConditionalMove(PlatformKind cmpKind, Value left, Value right, Condition cond, boolean unorderedIsTrue, Value trueValue, Value falseValue) {
-        boolean mirrored = emitCompare(cmpKind, left, right);
-        Condition finalCondition = mirrored ? cond.mirror() : cond;
+        boolean isFloatComparison = cmpKind == AMD64Kind.SINGLE || cmpKind == AMD64Kind.DOUBLE;
 
-        Variable result = newVariable(trueValue.getValueKind());
-        if (cmpKind == AMD64Kind.SINGLE || cmpKind == AMD64Kind.DOUBLE) {
-            append(new FloatCondMoveOp(result, finalCondition, unorderedIsTrue, load(trueValue), load(falseValue)));
+        Condition finalCondition = cond;
+        Value finalTrueValue = trueValue;
+        Value finalFalseValue = falseValue;
+        if (isFloatComparison) {
+            // eliminate the parity check in case of a float comparison
+            Value finalLeft = left;
+            Value finalRight = right;
+            if (unorderedIsTrue != AMD64ControlFlow.trueOnUnordered(finalCondition)) {
+                if (unorderedIsTrue == AMD64ControlFlow.trueOnUnordered(finalCondition.mirror())) {
+                    finalCondition = finalCondition.mirror();
+                    finalLeft = right;
+                    finalRight = left;
+                } else if (finalCondition != Condition.EQ && finalCondition != Condition.NE) {
+                    // negating EQ and NE does not make any sense as we would need to negate
+                    // unorderedIsTrue as well (otherwise, we would no longer fulfill the Java
+                    // NaN semantics)
+                    assert unorderedIsTrue == AMD64ControlFlow.trueOnUnordered(finalCondition.negate());
+                    finalCondition = finalCondition.negate();
+                    finalTrueValue = falseValue;
+                    finalFalseValue = trueValue;
+                }
+            }
+            emitRawCompare(cmpKind, finalLeft, finalRight);
         } else {
-            append(new CondMoveOp(result, finalCondition, load(trueValue), loadNonConst(falseValue)));
+            finalCondition = emitCompare(cmpKind, left, right, cond);
+        }
+
+        boolean isParityCheckNecessary = isFloatComparison && unorderedIsTrue != AMD64ControlFlow.trueOnUnordered(finalCondition);
+        Variable result = newVariable(finalTrueValue.getValueKind());
+        if (!isParityCheckNecessary && isIntConstant(finalTrueValue, 1) && isIntConstant(finalFalseValue, 0)) {
+            if (isFloatComparison) {
+                append(new FloatCondSetOp(result, finalCondition));
+            } else {
+                append(new CondSetOp(result, finalCondition));
+            }
+        } else if (!isParityCheckNecessary && isIntConstant(finalTrueValue, 0) && isIntConstant(finalFalseValue, 1)) {
+            if (isFloatComparison) {
+                if (unorderedIsTrue == AMD64ControlFlow.trueOnUnordered(finalCondition.negate())) {
+                    append(new FloatCondSetOp(result, finalCondition.negate()));
+                } else {
+                    append(new FloatCondSetOp(result, finalCondition));
+                    Variable negatedResult = newVariable(result.getValueKind());
+                    append(new AMD64Binary.ConstOp(AMD64BinaryArithmetic.XOR, OperandSize.get(result.getPlatformKind()), negatedResult, result, 1));
+                    result = negatedResult;
+                }
+            } else {
+                append(new CondSetOp(result, finalCondition.negate()));
+            }
+        } else if (isFloatComparison) {
+            append(new FloatCondMoveOp(result, finalCondition, unorderedIsTrue, load(finalTrueValue), load(finalFalseValue)));
+        } else {
+            append(new CondMoveOp(result, finalCondition, load(finalTrueValue), loadNonConst(finalFalseValue)));
         }
         return result;
     }
@@ -394,23 +445,21 @@
      *
      * @param a the left operand of the comparison
      * @param b the right operand of the comparison
+     * @param cond the condition of the comparison
      * @return true if the left and right operands were switched, false otherwise
      */
-    private boolean emitCompare(PlatformKind cmpKind, Value a, Value b) {
-        Variable left;
-        Value right;
-        boolean mirrored;
+    private Condition emitCompare(PlatformKind cmpKind, Value a, Value b, Condition cond) {
         if (LIRValueUtil.isVariable(b)) {
-            left = load(b);
-            right = loadNonConst(a);
-            mirrored = true;
+            emitRawCompare(cmpKind, b, a);
+            return cond.mirror();
         } else {
-            left = load(a);
-            right = loadNonConst(b);
-            mirrored = false;
+            emitRawCompare(cmpKind, a, b);
+            return cond;
         }
-        ((AMD64ArithmeticLIRGeneratorTool) arithmeticLIRGen).emitCompareOp((AMD64Kind) cmpKind, left, right);
-        return mirrored;
+    }
+
+    private void emitRawCompare(PlatformKind cmpKind, Value left, Value right) {
+        ((AMD64ArithmeticLIRGeneratorTool) arithmeticLIRGen).emitCompareOp((AMD64Kind) cmpKind, load(left), loadNonConst(right));
     }
 
     @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64LIRKindTool.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64LIRKindTool.java	Wed Nov 08 16:03:35 2017 -0500
@@ -28,7 +28,7 @@
 
 import jdk.vm.ci.amd64.AMD64Kind;
 
-public class AMD64LIRKindTool implements LIRKindTool {
+public abstract class AMD64LIRKindTool implements LIRKindTool {
 
     @Override
     public LIRKind getIntegerKind(int bits) {
@@ -67,12 +67,8 @@
     }
 
     @Override
-    public LIRKind getNarrowOopKind() {
-        return LIRKind.reference(AMD64Kind.DWORD);
-    }
+    public abstract LIRKind getNarrowOopKind();
 
     @Override
-    public LIRKind getNarrowPointerKind() {
-        return LIRKind.value(AMD64Kind.DWORD);
-    }
+    public abstract LIRKind getNarrowPointerKind();
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/CompressEncoding.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/CompressEncoding.java	Wed Nov 08 16:03:35 2017 -0500
@@ -34,14 +34,6 @@
         this.shift = shift;
     }
 
-    public int compress(long ptr) {
-        if (ptr == 0L) {
-            return 0;
-        } else {
-            return (int) ((ptr - base) >>> shift);
-        }
-    }
-
     public boolean hasBase() {
         return base != 0;
     }
@@ -58,14 +50,6 @@
         return shift;
     }
 
-    public long uncompress(int ptr) {
-        if (ptr == 0) {
-            return 0L;
-        } else {
-            return ((ptr & 0xFFFFFFFFL) << shift) + base;
-        }
-    }
-
     @Override
     public String toString() {
         return "base: " + base + " shift: " + shift;
@@ -85,8 +69,7 @@
         if (obj instanceof CompressEncoding) {
             CompressEncoding other = (CompressEncoding) obj;
             return base == other.base && shift == other.shift;
-        } else {
-            return false;
         }
+        return false;
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/calc/FloatConvert.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/calc/FloatConvert.java	Wed Nov 08 16:03:35 2017 -0500
@@ -25,21 +25,23 @@
 import org.graalvm.compiler.debug.GraalError;
 
 public enum FloatConvert {
-    F2I(FloatConvertCategory.FloatingPointToInteger),
-    D2I(FloatConvertCategory.FloatingPointToInteger),
-    F2L(FloatConvertCategory.FloatingPointToInteger),
-    D2L(FloatConvertCategory.FloatingPointToInteger),
-    I2F(FloatConvertCategory.IntegerToFloatingPoint),
-    L2F(FloatConvertCategory.IntegerToFloatingPoint),
-    D2F(FloatConvertCategory.FloatingPointToFloatingPoint),
-    I2D(FloatConvertCategory.IntegerToFloatingPoint),
-    L2D(FloatConvertCategory.IntegerToFloatingPoint),
-    F2D(FloatConvertCategory.FloatingPointToFloatingPoint);
+    F2I(FloatConvertCategory.FloatingPointToInteger, 32),
+    D2I(FloatConvertCategory.FloatingPointToInteger, 64),
+    F2L(FloatConvertCategory.FloatingPointToInteger, 32),
+    D2L(FloatConvertCategory.FloatingPointToInteger, 64),
+    I2F(FloatConvertCategory.IntegerToFloatingPoint, 32),
+    L2F(FloatConvertCategory.IntegerToFloatingPoint, 64),
+    D2F(FloatConvertCategory.FloatingPointToFloatingPoint, 64),
+    I2D(FloatConvertCategory.IntegerToFloatingPoint, 32),
+    L2D(FloatConvertCategory.IntegerToFloatingPoint, 64),
+    F2D(FloatConvertCategory.FloatingPointToFloatingPoint, 32);
 
-    private FloatConvertCategory category;
+    private final FloatConvertCategory category;
+    private final int inputBits;
 
-    FloatConvert(FloatConvertCategory category) {
+    FloatConvert(FloatConvertCategory category, int inputBits) {
         this.category = category;
+        this.inputBits = inputBits;
     }
 
     public FloatConvertCategory getCategory() {
@@ -72,4 +74,8 @@
                 throw GraalError.shouldNotReachHere();
         }
     }
+
+    public int getInputBits() {
+        return inputBits;
+    }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/cfg/Loop.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/cfg/Loop.java	Wed Nov 08 16:03:35 2017 -0500
@@ -41,7 +41,6 @@
         this.parent = parent;
         if (parent != null) {
             this.depth = parent.getDepth() + 1;
-            parent.getChildren().add(this);
         } else {
             this.depth = 1;
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/ArithmeticOpTable.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/ArithmeticOpTable.java	Wed Nov 08 16:03:35 2017 -0500
@@ -96,6 +96,22 @@
         }
     }
 
+    public BinaryOp<?>[] getBinaryOps() {
+        return new BinaryOp<?>[]{add, sub, mul, mulHigh, umulHigh, div, rem, and, or, xor};
+    }
+
+    public UnaryOp<?>[] getUnaryOps() {
+        return new UnaryOp<?>[]{neg, not, abs, sqrt};
+    }
+
+    public ShiftOp<?>[] getShiftOps() {
+        return new ShiftOp<?>[]{shl, shr, ushr};
+    }
+
+    public IntegerConvertOp<?>[] getIntegerConvertOps() {
+        return new IntegerConvertOp<?>[]{zeroExtend, signExtend, narrow};
+    }
+
     public static final ArithmeticOpTable EMPTY = new ArithmeticOpTable(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null);
 
     public interface ArithmeticOpWrapper {
@@ -562,7 +578,10 @@
         }
 
         /**
-         * Apply the operation to two {@linkplain Constant Constants}.
+         * Applies this operation to {@code a} and {@code b}.
+         *
+         * @return the result of applying this operation or {@code null} if applying it would raise
+         *         an exception (e.g., {@link ArithmeticException} for dividing by 0)
          */
         public abstract Constant foldConstant(Constant a, Constant b);
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/FloatStamp.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/FloatStamp.java	Wed Nov 08 16:03:35 2017 -0500
@@ -291,7 +291,7 @@
 
     @Override
     public JavaConstant asConstant() {
-        if (nonNaN && Double.compare(lowerBound, upperBound) == 0) {
+        if (isConstant()) {
             switch (getBits()) {
                 case 32:
                     return JavaConstant.forFloat((float) lowerBound);
@@ -302,6 +302,68 @@
         return null;
     }
 
+    private boolean isConstant() {
+        /*
+         * There are many forms of NaNs and any operations on them can silently convert them into
+         * the canonical NaN.
+         */
+        return (Double.compare(lowerBound, upperBound) == 0 && nonNaN);
+    }
+
+    private static FloatStamp stampForConstant(Constant constant) {
+        FloatStamp result;
+        PrimitiveConstant value = (PrimitiveConstant) constant;
+        switch (value.getJavaKind()) {
+            case Float:
+                if (Float.isNaN(value.asFloat())) {
+                    result = new FloatStamp(32, Double.NaN, Double.NaN, false);
+                } else {
+                    result = new FloatStamp(32, value.asFloat(), value.asFloat(), !Float.isNaN(value.asFloat()));
+                }
+                break;
+            case Double:
+                if (Double.isNaN(value.asDouble())) {
+                    result = new FloatStamp(64, Double.NaN, Double.NaN, false);
+                } else {
+                    result = new FloatStamp(64, value.asDouble(), value.asDouble(), !Double.isNaN(value.asDouble()));
+                }
+                break;
+            default:
+                throw GraalError.shouldNotReachHere();
+        }
+        if (result.isConstant()) {
+            return result;
+        }
+        return null;
+    }
+
+    private static Stamp maybeFoldConstant(UnaryOp<?> op, FloatStamp stamp) {
+        if (stamp.isConstant()) {
+            JavaConstant constant = stamp.asConstant();
+            Constant folded = op.foldConstant(constant);
+            if (folded != null) {
+                return FloatStamp.stampForConstant(folded);
+            }
+        }
+        return null;
+    }
+
+    private static Stamp maybeFoldConstant(BinaryOp<?> op, FloatStamp stamp1, FloatStamp stamp2) {
+        if (stamp1.isConstant() && stamp2.isConstant()) {
+            JavaConstant constant1 = stamp1.asConstant();
+            JavaConstant constant2 = stamp2.asConstant();
+            Constant folded = op.foldConstant(constant1, constant2);
+            if (folded != null) {
+                FloatStamp stamp = stampForConstant(folded);
+                if (stamp != null && stamp.isConstant()) {
+                    assert stamp.asConstant().equals(folded);
+                    return stamp;
+                }
+            }
+        }
+        return null;
+    }
+
     public static final ArithmeticOpTable OPS = new ArithmeticOpTable(
 
                     new UnaryOp.Neg() {
@@ -322,8 +384,13 @@
                         @Override
                         public Stamp foldStamp(Stamp s) {
                             FloatStamp stamp = (FloatStamp) s;
+                            Stamp folded = maybeFoldConstant(this, stamp);
+                            if (folded != null) {
+                                return folded;
+                            }
                             return new FloatStamp(stamp.getBits(), -stamp.upperBound(), -stamp.lowerBound(), stamp.isNonNaN());
                         }
+
                     },
 
                     new BinaryOp.Add(false, true) {
@@ -344,8 +411,13 @@
                         }
 
                         @Override
-                        public Stamp foldStamp(Stamp stamp1, Stamp stamp2) {
-                            // TODO
+                        public Stamp foldStamp(Stamp s1, Stamp s2) {
+                            FloatStamp stamp1 = (FloatStamp) s1;
+                            FloatStamp stamp2 = (FloatStamp) s2;
+                            Stamp folded = maybeFoldConstant(this, stamp1, stamp2);
+                            if (folded != null) {
+                                return folded;
+                            }
                             return stamp1.unrestricted();
                         }
 
@@ -381,8 +453,13 @@
                         }
 
                         @Override
-                        public Stamp foldStamp(Stamp stamp1, Stamp stamp2) {
-                            // TODO
+                        public Stamp foldStamp(Stamp s1, Stamp s2) {
+                            FloatStamp stamp1 = (FloatStamp) s1;
+                            FloatStamp stamp2 = (FloatStamp) s2;
+                            Stamp folded = maybeFoldConstant(this, stamp1, stamp2);
+                            if (folded != null) {
+                                return folded;
+                            }
                             return stamp1.unrestricted();
                         }
 
@@ -418,9 +495,14 @@
                         }
 
                         @Override
-                        public Stamp foldStamp(Stamp a, Stamp b) {
-                            // TODO
-                            return a.unrestricted();
+                        public Stamp foldStamp(Stamp s1, Stamp s2) {
+                            FloatStamp stamp1 = (FloatStamp) s1;
+                            FloatStamp stamp2 = (FloatStamp) s2;
+                            Stamp folded = maybeFoldConstant(this, stamp1, stamp2);
+                            if (folded != null) {
+                                return folded;
+                            }
+                            return stamp1.unrestricted();
                         }
 
                         @Override
@@ -450,17 +532,24 @@
                             assert a.getJavaKind() == b.getJavaKind();
                             switch (a.getJavaKind()) {
                                 case Float:
-                                    return JavaConstant.forFloat(a.asFloat() / b.asFloat());
+                                    float floatDivisor = b.asFloat();
+                                    return (floatDivisor == 0) ? null : JavaConstant.forFloat(a.asFloat() / floatDivisor);
                                 case Double:
-                                    return JavaConstant.forDouble(a.asDouble() / b.asDouble());
+                                    double doubleDivisor = b.asDouble();
+                                    return (doubleDivisor == 0) ? null : JavaConstant.forDouble(a.asDouble() / doubleDivisor);
                                 default:
                                     throw GraalError.shouldNotReachHere();
                             }
                         }
 
                         @Override
-                        public Stamp foldStamp(Stamp stamp1, Stamp stamp2) {
-                            // TODO
+                        public Stamp foldStamp(Stamp s1, Stamp s2) {
+                            FloatStamp stamp1 = (FloatStamp) s1;
+                            FloatStamp stamp2 = (FloatStamp) s2;
+                            Stamp folded = maybeFoldConstant(this, stamp1, stamp2);
+                            if (folded != null) {
+                                return folded;
+                            }
                             return stamp1.unrestricted();
                         }
 
@@ -496,8 +585,13 @@
                         }
 
                         @Override
-                        public Stamp foldStamp(Stamp stamp1, Stamp stamp2) {
-                            // TODO
+                        public Stamp foldStamp(Stamp s1, Stamp s2) {
+                            FloatStamp stamp1 = (FloatStamp) s1;
+                            FloatStamp stamp2 = (FloatStamp) s2;
+                            Stamp folded = maybeFoldConstant(this, stamp1, stamp2);
+                            if (folded != null) {
+                                return folded;
+                            }
                             return stamp1.unrestricted();
                         }
                     },
@@ -521,6 +615,17 @@
 
                         @Override
                         public Stamp foldStamp(Stamp s) {
+                            FloatStamp stamp = (FloatStamp) s;
+                            JavaConstant constant = stamp.asConstant();
+                            if (constant != null) {
+                                Constant folded = foldConstant(constant);
+                                if (folded != null) {
+                                    FloatStamp result = stampForConstant(folded);
+                                    if (result != null && result.isConstant()) {
+                                        return result;
+                                    }
+                                }
+                            }
                             return s.unrestricted();
                         }
                     },
@@ -547,7 +652,13 @@
                         }
 
                         @Override
-                        public Stamp foldStamp(Stamp stamp1, Stamp stamp2) {
+                        public Stamp foldStamp(Stamp s1, Stamp s2) {
+                            FloatStamp stamp1 = (FloatStamp) s1;
+                            FloatStamp stamp2 = (FloatStamp) s2;
+                            Stamp folded = maybeFoldConstant(this, stamp1, stamp2);
+                            if (folded != null) {
+                                return folded;
+                            }
                             return stamp1.unrestricted();
                         }
 
@@ -576,7 +687,9 @@
                                 case Float:
                                     int fa = Float.floatToRawIntBits(a.asFloat());
                                     int fb = Float.floatToRawIntBits(b.asFloat());
-                                    return JavaConstant.forFloat(Float.intBitsToFloat(fa | fb));
+                                    float floatOr = Float.intBitsToFloat(fa | fb);
+                                    assert (fa | fb) == Float.floatToRawIntBits((floatOr));
+                                    return JavaConstant.forFloat(floatOr);
                                 case Double:
                                     long da = Double.doubleToRawLongBits(a.asDouble());
                                     long db = Double.doubleToRawLongBits(b.asDouble());
@@ -587,7 +700,13 @@
                         }
 
                         @Override
-                        public Stamp foldStamp(Stamp stamp1, Stamp stamp2) {
+                        public Stamp foldStamp(Stamp s1, Stamp s2) {
+                            FloatStamp stamp1 = (FloatStamp) s1;
+                            FloatStamp stamp2 = (FloatStamp) s2;
+                            Stamp folded = maybeFoldConstant(this, stamp1, stamp2);
+                            if (folded != null) {
+                                return folded;
+                            }
                             return stamp1.unrestricted();
                         }
 
@@ -627,7 +746,13 @@
                         }
 
                         @Override
-                        public Stamp foldStamp(Stamp stamp1, Stamp stamp2) {
+                        public Stamp foldStamp(Stamp s1, Stamp s2) {
+                            FloatStamp stamp1 = (FloatStamp) s1;
+                            FloatStamp stamp2 = (FloatStamp) s2;
+                            Stamp folded = maybeFoldConstant(this, stamp1, stamp2);
+                            if (folded != null) {
+                                return folded;
+                            }
                             return stamp1.unrestricted();
                         }
 
@@ -665,6 +790,10 @@
                         @Override
                         public Stamp foldStamp(Stamp s) {
                             FloatStamp stamp = (FloatStamp) s;
+                            Stamp folded = maybeFoldConstant(this, stamp);
+                            if (folded != null) {
+                                return folded;
+                            }
                             if (stamp.isNaN()) {
                                 return stamp;
                             }
@@ -689,6 +818,11 @@
 
                         @Override
                         public Stamp foldStamp(Stamp s) {
+                            FloatStamp stamp = (FloatStamp) s;
+                            Stamp folded = maybeFoldConstant(this, stamp);
+                            if (folded != null) {
+                                return folded;
+                            }
                             return s.unrestricted();
                         }
                     },
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/IntegerStamp.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/IntegerStamp.java	Wed Nov 08 16:03:35 2017 -0500
@@ -597,6 +597,10 @@
                         public Stamp foldStamp(Stamp s) {
                             IntegerStamp stamp = (IntegerStamp) s;
                             int bits = stamp.getBits();
+                            if (stamp.lowerBound == stamp.upperBound) {
+                                long value = CodeUtil.convert(-stamp.lowerBound(), stamp.getBits(), false);
+                                return StampFactory.forInteger(stamp.getBits(), value, value);
+                            }
                             if (stamp.lowerBound() != CodeUtil.minValue(bits)) {
                                 // TODO(ls) check if the mask calculation is correct...
                                 return StampFactory.forInteger(bits, -stamp.upperBound(), -stamp.lowerBound());
@@ -624,6 +628,11 @@
                             int bits = a.getBits();
                             assert bits == b.getBits();
 
+                            if (a.lowerBound == a.upperBound && b.lowerBound == b.upperBound) {
+                                long value = CodeUtil.convert(a.lowerBound() + b.lowerBound(), a.getBits(), false);
+                                return StampFactory.forInteger(a.getBits(), value, value);
+                            }
+
                             if (a.isUnrestricted()) {
                                 return a;
                             } else if (b.isUnrestricted()) {
@@ -711,6 +720,12 @@
 
                             int bits = a.getBits();
                             assert bits == b.getBits();
+
+                            if (a.lowerBound == a.upperBound && b.lowerBound == b.upperBound) {
+                                long value = CodeUtil.convert(a.lowerBound() * b.lowerBound(), a.getBits(), false);
+                                return StampFactory.forInteger(a.getBits(), value, value);
+                            }
+
                             // if a==0 or b==0 result of a*b is always 0
                             if (a.upMask() == 0) {
                                 return a;
@@ -791,7 +806,7 @@
                                 long maxPosB = b.upperBound();
 
                                 // multiplication has shift semantics
-                                long newUpMask = ~CodeUtil.mask(Long.numberOfTrailingZeros(a.upMask) + Long.numberOfTrailingZeros(b.upMask)) & CodeUtil.mask(bits);
+                                long newUpMask = ~CodeUtil.mask(Math.min(64, Long.numberOfTrailingZeros(a.upMask) + Long.numberOfTrailingZeros(b.upMask))) & CodeUtil.mask(bits);
 
                                 if (a.canBePositive()) {
                                     if (b.canBePositive()) {
@@ -1023,6 +1038,9 @@
                             PrimitiveConstant a = (PrimitiveConstant) const1;
                             PrimitiveConstant b = (PrimitiveConstant) const2;
                             assert a.getJavaKind() == b.getJavaKind();
+                            if (b.asLong() == 0) {
+                                return null;
+                            }
                             return JavaConstant.forIntegerKind(a.getJavaKind(), a.asLong() / b.asLong());
                         }
 
@@ -1031,9 +1049,12 @@
                             IntegerStamp a = (IntegerStamp) stamp1;
                             IntegerStamp b = (IntegerStamp) stamp2;
                             assert a.getBits() == b.getBits();
-                            if (b.isStrictlyPositive()) {
-                                long newLowerBound = a.lowerBound() / b.upperBound();
-                                long newUpperBound = a.upperBound() / b.lowerBound();
+                            if (a.lowerBound == a.upperBound && b.lowerBound == b.upperBound && b.lowerBound != 0) {
+                                long value = CodeUtil.convert(a.lowerBound() / b.lowerBound(), a.getBits(), false);
+                                return StampFactory.forInteger(a.getBits(), value, value);
+                            } else if (b.isStrictlyPositive()) {
+                                long newLowerBound = a.lowerBound() < 0 ? a.lowerBound() / b.lowerBound() : a.lowerBound() / b.upperBound();
+                                long newUpperBound = a.upperBound() < 0 ? a.upperBound() / b.upperBound() : a.upperBound() / b.lowerBound();
                                 return StampFactory.forInteger(a.getBits(), newLowerBound, newUpperBound);
                             } else {
                                 return a.unrestricted();
@@ -1054,6 +1075,9 @@
                             PrimitiveConstant a = (PrimitiveConstant) const1;
                             PrimitiveConstant b = (PrimitiveConstant) const2;
                             assert a.getJavaKind() == b.getJavaKind();
+                            if (b.asLong() == 0) {
+                                return null;
+                            }
                             return JavaConstant.forIntegerKind(a.getJavaKind(), a.asLong() % b.asLong());
                         }
 
@@ -1062,6 +1086,12 @@
                             IntegerStamp a = (IntegerStamp) stamp1;
                             IntegerStamp b = (IntegerStamp) stamp2;
                             assert a.getBits() == b.getBits();
+
+                            if (a.lowerBound == a.upperBound && b.lowerBound == b.upperBound && b.lowerBound != 0) {
+                                long value = CodeUtil.convert(a.lowerBound() % b.lowerBound(), a.getBits(), false);
+                                return StampFactory.forInteger(a.getBits(), value, value);
+                            }
+
                             // zero is always possible
                             long newLowerBound = Math.min(a.lowerBound(), 0);
                             long newUpperBound = Math.max(a.upperBound(), 0);
@@ -1364,6 +1394,10 @@
                         public Stamp foldStamp(Stamp input) {
                             IntegerStamp stamp = (IntegerStamp) input;
                             int bits = stamp.getBits();
+                            if (stamp.lowerBound == stamp.upperBound) {
+                                long value = CodeUtil.convert(Math.abs(stamp.lowerBound()), stamp.getBits(), false);
+                                return StampFactory.forInteger(stamp.getBits(), value, value);
+                            }
                             if (stamp.lowerBound() == CodeUtil.minValue(bits)) {
                                 return input.unrestricted();
                             } else {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CheckGraalInvariants.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CheckGraalInvariants.java	Wed Nov 08 16:03:35 2017 -0500
@@ -49,8 +49,8 @@
 import org.graalvm.compiler.core.common.LIRKind;
 import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
 import org.graalvm.compiler.debug.DebugCloseable;
+import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.debug.DebugHandlersFactory;
-import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.debug.GraalError;
 import org.graalvm.compiler.graph.Node;
 import org.graalvm.compiler.graph.NodeClass;
@@ -73,6 +73,8 @@
 import org.graalvm.compiler.phases.verify.VerifyBailoutUsage;
 import org.graalvm.compiler.phases.verify.VerifyCallerSensitiveMethods;
 import org.graalvm.compiler.phases.verify.VerifyDebugUsage;
+import org.graalvm.compiler.phases.verify.VerifyGetOptionsUsage;
+import org.graalvm.compiler.phases.verify.VerifyGraphAddUsage;
 import org.graalvm.compiler.phases.verify.VerifyInstanceOfUsage;
 import org.graalvm.compiler.phases.verify.VerifyUpdateUsages;
 import org.graalvm.compiler.phases.verify.VerifyUsageWithEquals;
@@ -381,6 +383,8 @@
         new VerifyUpdateUsages().apply(graph, context);
         new VerifyBailoutUsage().apply(graph, context);
         new VerifyInstanceOfUsage().apply(graph, context);
+        new VerifyGraphAddUsage().apply(graph, context);
+        new VerifyGetOptionsUsage().apply(graph, context);
         if (graph.method().isBridge()) {
             BridgeMethodUtils.getBridgedMethod(graph.method());
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ConditionalEliminationTest14.java	Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.graalvm.compiler.core.test;
+
+import org.graalvm.compiler.graph.iterators.NodeIterable;
+import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.FixedGuardNode;
+import org.graalvm.compiler.nodes.GuardNode;
+import org.graalvm.compiler.nodes.LogicNode;
+import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
+import org.graalvm.compiler.nodes.calc.IntegerBelowNode;
+import org.graalvm.compiler.nodes.java.LoadIndexedNode;
+import org.graalvm.compiler.nodes.memory.FloatingReadNode;
+import org.graalvm.compiler.nodes.memory.ReadNode;
+import org.graalvm.compiler.nodes.spi.LoweringTool;
+import org.graalvm.compiler.phases.common.CanonicalizerPhase;
+import org.graalvm.compiler.phases.common.FloatingReadPhase;
+import org.graalvm.compiler.phases.common.IterativeConditionalEliminationPhase;
+import org.graalvm.compiler.phases.common.LoweringPhase;
+import org.graalvm.compiler.phases.tiers.PhaseContext;
+import org.junit.Assert;
+import org.junit.Test;
+
+import jdk.vm.ci.meta.DeoptimizationReason;
+
+/**
+ * Check that multiple bounds checks are correctly grouped together.
+ */
+public class ConditionalEliminationTest14 extends ConditionalEliminationTestBase {
+
+    public static void test1Snippet(Object[] args) {
+        Object a5 = args[5];
+        Object a7 = args[7];
+        Object a6 = args[6];
+
+        /*
+         * The order of the conditions matters: The scheduler processes the floating reads for the
+         * array loads in the order of the conditions here, and we want the index 7 access to be
+         * processed before the index 6 access.
+         */
+        if (a5 != null && a7 != null && a6 != null) {
+            sink1 = 1;
+        }
+        sink0 = 0;
+    }
+
+    @Test
+    public void test1() {
+        StructuredGraph graph = parseEager("test1Snippet", AllowAssumptions.YES);
+        CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
+        PhaseContext context = new PhaseContext(getProviders());
+
+        /* Convert the LoadIndexNode to ReadNode with floating guards. */
+        new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
+        /* Convert the ReadNode to FloatingReadNode. */
+        new FloatingReadPhase().apply(graph);
+        /* Apply the phase that we want to test. */
+        new IterativeConditionalEliminationPhase(canonicalizer, true).apply(graph, context);
+
+        Assert.assertEquals("All guards must be floating", 0, graph.getNodes(FixedGuardNode.TYPE).count());
+        Assert.assertEquals("All array accesses must have been lowered", 0, graph.getNodes().filter(LoadIndexedNode.class).count());
+        Assert.assertEquals("All reads must be floating", 0, graph.getNodes().filter(ReadNode.class).count());
+        Assert.assertEquals("Must have floating reads (3 array accesses, 1 array length)", 4, graph.getNodes().filter(FloatingReadNode.class).count());
+
+        NodeIterable<GuardNode> boundsChecks = graph.getNodes(GuardNode.TYPE).filter(n -> ((GuardNode) n).getReason() == DeoptimizationReason.BoundsCheckException);
+        Assert.assertEquals("Must have only 1 bounds check remaining", 1, boundsChecks.count());
+        LogicNode condition = boundsChecks.first().getCondition();
+        Assert.assertTrue("Bounds check must check for array length 8", condition instanceof IntegerBelowNode && ((IntegerBelowNode) condition).getY().valueEquals(ConstantNode.forInt(8)));
+    }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ConditionalEliminationTestBase.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ConditionalEliminationTestBase.java	Wed Nov 08 16:03:35 2017 -0500
@@ -27,12 +27,15 @@
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
 import org.graalvm.compiler.nodes.spi.LoweringTool;
+import org.graalvm.compiler.phases.OptimisticOptimizations;
+import org.graalvm.compiler.phases.OptimisticOptimizations.Optimization;
 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
 import org.graalvm.compiler.phases.common.ConditionalEliminationPhase;
 import org.graalvm.compiler.phases.common.ConvertDeoptimizeToGuardPhase;
 import org.graalvm.compiler.phases.common.IterativeConditionalEliminationPhase;
 import org.graalvm.compiler.phases.common.LoweringPhase;
 import org.graalvm.compiler.phases.schedule.SchedulePhase;
+import org.graalvm.compiler.phases.tiers.HighTierContext;
 import org.graalvm.compiler.phases.tiers.PhaseContext;
 import org.junit.Assert;
 
@@ -45,6 +48,15 @@
     protected static int sink1;
     protected static int sink2;
 
+    /**
+     * These tests assume all code paths in called routines are reachable so disable removal of dead
+     * code based on method profiles.
+     */
+    @Override
+    protected HighTierContext getDefaultHighTierContext() {
+        return new HighTierContext(getProviders(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL.remove(Optimization.RemoveNeverExecutedCode));
+    }
+
     protected void testConditionalElimination(String snippet, String referenceSnippet) {
         testConditionalElimination(snippet, referenceSnippet, false, false);
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/DumpPathTest.java	Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 org.graalvm.compiler.core.test;
+
+import java.io.IOException;
+import java.nio.file.DirectoryStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import org.graalvm.compiler.debug.DebugOptions;
+import org.graalvm.compiler.options.OptionKey;
+import org.graalvm.compiler.options.OptionValues;
+import org.graalvm.util.EconomicMap;
+import org.junit.Test;
+
+/**
+ * Check that setting the dump path results in files ending up in the right directory with matching
+ * names.
+ */
+public class DumpPathTest extends GraalCompilerTest {
+
+    public static Object snippet() {
+        return new String("snippet");
+    }
+
+    @Test
+    public void testDump() throws IOException {
+        Path dumpDirectoryPath = Files.createTempDirectory("DumpPathTest");
+        String[] extensions = new String[]{".cfg", ".bgv", ".graph-strings"};
+        EconomicMap<OptionKey<?>, Object> overrides = OptionValues.newOptionMap();
+        overrides.put(DebugOptions.DumpPath, dumpDirectoryPath.toString());
+        overrides.put(DebugOptions.PrintGraphFile, true);
+        overrides.put(DebugOptions.PrintCanonicalGraphStrings, true);
+        overrides.put(DebugOptions.Dump, "*");
+
+        // Generate dump files.
+        test(new OptionValues(getInitialOptions(), overrides), "snippet");
+        // Check that Ideal files got created, in the right place.
+        checkForFiles(dumpDirectoryPath, extensions);
+
+        // Clean up the generated files.
+        scrubDirectory(dumpDirectoryPath);
+    }
+
+    /**
+     * Check that the given directory contains file or directory names with all the given
+     * extensions.
+     */
+    private static void checkForFiles(Path directoryPath, String[] extensions) throws IOException {
+        String[] paths = new String[extensions.length];
+        try (DirectoryStream<Path> stream = Files.newDirectoryStream(directoryPath)) {
+            for (Path filePath : stream) {
+                String fileName = filePath.getFileName().toString();
+                for (int i = 0; i < extensions.length; i++) {
+                    String extension = extensions[i];
+                    if (fileName.endsWith(extensions[i])) {
+                        assertTrue(paths[i] == null, "multiple files found for %s in %s", extension, directoryPath);
+                        paths[i] = fileName.replace(extensions[i], "");
+                    }
+                }
+            }
+        }
+        for (int i = 0; i < paths.length; i++) {
+            assertTrue(paths[i] != null, "missing file for extension %s in %s", extensions[i], directoryPath);
+        }
+        // Ensure that all file names are the same.
+        for (int i = 1; i < paths.length; i++) {
+            assertTrue(paths[0].equals(paths[i]), paths[0] + " != " + paths[i]);
+        }
+    }
+
+    /**
+     * Remove the temporary directory.
+     */
+    private static void scrubDirectory(Path directoryPath) {
+        try {
+            try (DirectoryStream<Path> stream = Files.newDirectoryStream(directoryPath)) {
+                for (Path filePath : stream) {
+                    if (Files.isRegularFile(filePath)) {
+                        Files.delete(filePath);
+                    } else if (Files.isDirectory(filePath)) {
+                        scrubDirectory(filePath);
+                    }
+                }
+            }
+            Files.delete(directoryPath);
+        } catch (IOException ioe) {
+            ioe.printStackTrace();
+        }
+    }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/FinalizableSubclassTest.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/FinalizableSubclassTest.java	Wed Nov 08 16:03:35 2017 -0500
@@ -72,7 +72,7 @@
         Assert.assertTrue(constructors.length == 1);
         final ResolvedJavaMethod javaMethod = getMetaAccess().lookupJavaMethod(constructors[0]);
         OptionValues options = getInitialOptions();
-        StructuredGraph graph = new StructuredGraph.Builder(options, getDebugContext(options), allowAssumptions).method(javaMethod).build();
+        StructuredGraph graph = new StructuredGraph.Builder(options, getDebugContext(options, null, javaMethod), allowAssumptions).method(javaMethod).build();
 
         GraphBuilderConfiguration conf = GraphBuilderConfiguration.getSnippetDefault(getDefaultGraphBuilderPlugins());
         new GraphBuilderPhase.Instance(getMetaAccess(), getProviders().getStampProvider(), getProviders().getConstantReflection(), getProviders().getConstantFieldProvider(), conf,
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GraalCompilerTest.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GraalCompilerTest.java	Wed Nov 08 16:03:35 2017 -0500
@@ -389,7 +389,7 @@
      * {@link DebugDumpHandler}s closed in {@link #afterTest()}.
      */
     protected DebugContext getDebugContext() {
-        return getDebugContext(getInitialOptions());
+        return getDebugContext(getInitialOptions(), null, null);
     }
 
     @Override
@@ -862,7 +862,7 @@
         Result actual = executeActual(options, method, receiver, args);
         profile = method.getProfilingInfo(); // profile can change after execution
         for (DeoptimizationReason reason : shouldNotDeopt) {
-            Assert.assertEquals((int) deoptCounts.get(reason), profile.getDeoptimizationCount(reason));
+            Assert.assertEquals("wrong number of deopt counts for " + reason, (int) deoptCounts.get(reason), profile.getDeoptimizationCount(reason));
         }
         return actual;
     }
@@ -1216,15 +1216,15 @@
 
     protected final Builder builder(ResolvedJavaMethod method, AllowAssumptions allowAssumptions) {
         OptionValues options = getInitialOptions();
-        return new Builder(options, getDebugContext(options), allowAssumptions).method(method).compilationId(getCompilationId(method));
+        return new Builder(options, getDebugContext(options, null, method), allowAssumptions).method(method).compilationId(getCompilationId(method));
     }
 
     protected final Builder builder(ResolvedJavaMethod method, AllowAssumptions allowAssumptions, CompilationIdentifier compilationId, OptionValues options) {
-        return new Builder(options, getDebugContext(options), allowAssumptions).method(method).compilationId(compilationId);
+        return new Builder(options, getDebugContext(options, compilationId.toString(CompilationIdentifier.Verbosity.ID), method), allowAssumptions).method(method).compilationId(compilationId);
     }
 
     protected final Builder builder(ResolvedJavaMethod method, AllowAssumptions allowAssumptions, OptionValues options) {
-        return new Builder(options, getDebugContext(options), allowAssumptions).method(method).compilationId(getCompilationId(method));
+        return new Builder(options, getDebugContext(options, null, method), allowAssumptions).method(method).compilationId(getCompilationId(method));
     }
 
     protected PhaseSuite<HighTierContext> getDebugGraphBuilderSuite() {
@@ -1234,6 +1234,7 @@
     @SuppressWarnings("try")
     protected StructuredGraph parse(StructuredGraph.Builder builder, PhaseSuite<HighTierContext> graphBuilderSuite) {
         ResolvedJavaMethod javaMethod = builder.getMethod();
+        builder.speculationLog(getSpeculationLog());
         if (builder.getCancellable() == null) {
             builder.cancellable(getCancellable(javaMethod));
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GraalDebugHandlersFactoryTest.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GraalDebugHandlersFactoryTest.java	Wed Nov 08 16:03:35 2017 -0500
@@ -31,8 +31,12 @@
 import java.nio.file.Paths;
 import java.util.Comparator;
 
-import org.graalvm.compiler.printer.GraalDebugHandlersFactory;
+import org.graalvm.compiler.debug.DebugOptions;
+import org.graalvm.compiler.debug.PathUtilities;
+import org.graalvm.compiler.options.OptionKey;
+import org.graalvm.compiler.options.OptionValues;
 import org.graalvm.compiler.test.AddExports;
+import org.junit.Assume;
 import org.junit.Test;
 
 @AddExports("jdk.internal.vm.compiler/org.graalvm.compiler.printer")
@@ -40,23 +44,28 @@
 
     @Test
     public void createUniqueTest() throws Exception {
-        Field maxFileNameLengthField = GraalDebugHandlersFactory.class.getDeclaredField("MAX_FILE_NAME_LENGTH");
-        maxFileNameLengthField.setAccessible(true);
+        Field maxFileNameLengthField = PathUtilities.class.getDeclaredField("MAX_FILE_NAME_LENGTH");
+        try {
+            maxFileNameLengthField.setAccessible(true);
+        } catch (RuntimeException ex) {
+            Assume.assumeFalse("If InaccessibleObjectException is thrown, skip the test, we are on JDK9", ex.getClass().getSimpleName().equals("InaccessibleObjectException"));
+        }
         int maxFileNameLength = maxFileNameLengthField.getInt(null);
-        Method createUniqueMethod = GraalDebugHandlersFactory.class.getDeclaredMethod("createUnique", Path.class, String.class, String.class, String.class, boolean.class);
+        Method createUniqueMethod = PathUtilities.class.getDeclaredMethod("createUnique", OptionValues.class, OptionKey.class, String.class, String.class, String.class, boolean.class);
         createUniqueMethod.setAccessible(true);
         Path tmpDir = Files.createTempDirectory(Paths.get("."), "createUniqueTest");
+        OptionValues options = new OptionValues(OptionValues.asMap(DebugOptions.DumpPath, tmpDir.toString()));
         try {
             for (boolean createDirectory : new boolean[]{true, false}) {
                 for (String ext : new String[]{"", ".bgv", ".graph-strings"}) {
                     for (int i = 0; i < maxFileNameLength + 5; i++) {
                         String id = new String(new char[i]).replace('\0', 'i');
                         String label = "";
-                        createUniqueMethod.invoke(null, tmpDir, id, label, ext, createDirectory);
+                        createUniqueMethod.invoke(null, options, null, id, label, ext, createDirectory);
 
                         id = "";
                         label = new String(new char[i]).replace('\0', 'l');
-                        createUniqueMethod.invoke(null, tmpDir, id, label, ext, createDirectory);
+                        createUniqueMethod.invoke(null, options, null, id, label, ext, createDirectory);
                     }
                 }
             }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GuardedIntrinsicTest.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GuardedIntrinsicTest.java	Wed Nov 08 16:03:35 2017 -0500
@@ -144,6 +144,11 @@
     public void test01() {
         Super inheritsHC = new Super();
         Person overridesHC = new Person(0);
+
+        // Ensure the profile for getSuperAge includes both receiver types
+        getSuperAge(inheritsHC);
+        getSuperAge(overridesHC);
+
         test("getSuperAge", inheritsHC);
         test("getSuperAge", overridesHC);
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/HashCodeTest.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/HashCodeTest.java	Wed Nov 08 16:03:35 2017 -0500
@@ -22,6 +22,8 @@
  */
 package org.graalvm.compiler.core.test;
 
+import java.util.HashMap;
+
 import org.graalvm.compiler.core.phases.HighTier;
 import org.graalvm.compiler.core.phases.MidTier;
 import org.graalvm.compiler.nodes.InvokeNode;
@@ -139,6 +141,10 @@
     public void test08() {
         initialize(Appendable.class);
         checkForGuardedIntrinsicPattern("hashCodeInterface");
+
+        // Ensure the profile for the dispatch in hashCodeSnippet01
+        // has a receiver type that does not select Object.hashCode intrinsic
+        hashCodeSnippet01(new HashMap<>());
         checkForGuardedIntrinsicPattern("hashCodeSnippet01");
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/MarkUnsafeAccessTest.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/MarkUnsafeAccessTest.java	Wed Nov 08 16:03:35 2017 -0500
@@ -25,6 +25,7 @@
 import static java.nio.file.StandardOpenOption.READ;
 import static java.nio.file.StandardOpenOption.WRITE;
 
+import java.io.File;
 import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.nio.MappedByteBuffer;
@@ -33,22 +34,20 @@
 import java.nio.file.Files;
 import java.nio.file.Path;
 
-import jdk.vm.ci.code.InstalledCode;
-import jdk.vm.ci.code.InvalidInstalledCodeException;
-import jdk.vm.ci.meta.ResolvedJavaMethod;
-import jdk.vm.ci.meta.ResolvedJavaType;
-
-import org.junit.Assert;
-import org.junit.Assume;
-import org.junit.Test;
-
-import sun.misc.Unsafe;
-
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
 import org.graalvm.compiler.phases.common.inlining.InliningPhase;
 import org.graalvm.compiler.phases.common.inlining.policy.InlineEverythingPolicy;
 import org.graalvm.compiler.phases.tiers.HighTierContext;
+import org.junit.Assert;
+import org.junit.Assume;
+import org.junit.Test;
+
+import jdk.vm.ci.code.InstalledCode;
+import jdk.vm.ci.code.InvalidInstalledCodeException;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.meta.ResolvedJavaType;
+import sun.misc.Unsafe;
 
 public class MarkUnsafeAccessTest extends GraalCompilerTest {
 
@@ -170,7 +169,9 @@
         try {
             mbb.position(BLOCK_SIZE);
             getter.get(mbb);
-            System.currentTimeMillis(); // materialize async exception
+
+            // Make a call that goes into native code to materialize async exception
+            new File("").exists();
         } catch (InternalError e) {
             return;
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/MergeCanonicalizerTest.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/MergeCanonicalizerTest.java	Wed Nov 08 16:03:35 2017 -0500
@@ -26,12 +26,23 @@
 import org.graalvm.compiler.nodes.ReturnNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
+import org.graalvm.compiler.phases.OptimisticOptimizations;
+import org.graalvm.compiler.phases.OptimisticOptimizations.Optimization;
 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
+import org.graalvm.compiler.phases.tiers.HighTierContext;
 import org.graalvm.compiler.phases.tiers.PhaseContext;
 import org.junit.Test;
 
 public class MergeCanonicalizerTest extends GraalCompilerTest {
 
+    /**
+     * These tests assume all code paths are reachable so disable profile based dead code removal.
+     */
+    @Override
+    protected HighTierContext getDefaultHighTierContext() {
+        return new HighTierContext(getProviders(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL.remove(Optimization.RemoveNeverExecutedCode));
+    }
+
     public static int staticField;
 
     private int field;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ProfilingInfoTest.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ProfilingInfoTest.java	Wed Nov 08 16:03:35 2017 -0500
@@ -24,15 +24,17 @@
 
 import java.io.Serializable;
 
+import org.graalvm.compiler.test.SubprocessUtil;
+import org.junit.Assert;
+import org.junit.Assume;
+import org.junit.Test;
+
 import jdk.vm.ci.meta.JavaTypeProfile;
 import jdk.vm.ci.meta.ProfilingInfo;
 import jdk.vm.ci.meta.ResolvedJavaMethod;
 import jdk.vm.ci.meta.ResolvedJavaType;
 import jdk.vm.ci.meta.TriState;
 
-import org.junit.Assert;
-import org.junit.Test;
-
 /**
  * Tests profiling information provided by the runtime.
  * <p>
@@ -40,7 +42,7 @@
  * information may be gathered for any given method. For example, HotSpot's advanced compilation
  * policy can decide to only gather partial profiles in a first level compilation (see
  * AdvancedThresholdPolicy::common(...) in advancedThresholdPolicy.cpp). Because of this,
- * occasionally tests for {@link ProfilingInfo#getNullSeen(int)} can fail since HotSpot only set's
+ * occasionally tests for {@link ProfilingInfo#getNullSeen(int)} can fail since HotSpot only sets
  * the null_seen bit when doing full profiling.
  */
 public class ProfilingInfoTest extends GraalCompilerTest {
@@ -182,6 +184,14 @@
         Assert.assertNull(typeProfile);
     }
 
+    public ProfilingInfoTest() {
+        // These tests are explicitly testing the profiling behavior of the
+        // interpreter. C1-based profiling differs slightly and when -Xcomp
+        // is present, profiles will be created by C1 compiled code, not the
+        // interpreter.
+        Assume.assumeTrue(!SubprocessUtil.getVMCommandLine().contains("-Xcomp"));
+    }
+
     @Test
     public void testExceptionSeen() {
         // NullPointerException
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/SubWordReturnTest.java	Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 org.graalvm.compiler.core.test;
+
+import java.util.ArrayList;
+import java.util.List;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+
+@RunWith(Parameterized.class)
+public class SubWordReturnTest extends GraalCompilerTest {
+
+    private final JavaKind kind;
+    private final int value;
+
+    private final String generatedClassName;
+    private final String generatedClassNameInternal;
+
+    private final String testMethodName;
+
+    /**
+     * The {@link AsmLoader} generates a class looking like this for the types byte, short, int and
+     * char.
+     */
+    static class ByteGetter {
+
+        // private static int intField = 1000000;
+
+        private static byte get() {
+            // GETSTATIC intField
+            // IRETURN
+            return 0;
+        }
+
+        public static int testByteSnippet() {
+            return get();
+        }
+    }
+
+    @Parameters(name = "{0}, {1}")
+    public static List<Object[]> data() {
+        ArrayList<Object[]> ret = new ArrayList<>();
+        for (int i : new int[]{1000000, 1000001, -1000000, -1}) {
+            ret.add(new Object[]{JavaKind.Boolean, i});
+            ret.add(new Object[]{JavaKind.Byte, i});
+            ret.add(new Object[]{JavaKind.Short, i});
+            ret.add(new Object[]{JavaKind.Char, i});
+        }
+        return ret;
+    }
+
+    public SubWordReturnTest(JavaKind kind, int value) {
+        this.kind = kind;
+        this.value = value;
+
+        this.generatedClassName = SubWordReturnTest.class.getName() + "$" + kind.toString() + "Getter";
+        this.generatedClassNameInternal = generatedClassName.replace('.', '/');
+        this.testMethodName = "test" + kind.name() + "Snippet";
+    }
+
+    @Test
+    public void test() throws ClassNotFoundException {
+        Class<?> testClass = new AsmLoader(SubWordReturnTest.class.getClassLoader()).findClass(generatedClassName);
+        ResolvedJavaMethod method = getResolvedJavaMethod(testClass, testMethodName);
+        test(method, null);
+    }
+
+    class AsmLoader extends ClassLoader implements Opcodes {
+
+        Class<?> loaded;
+
+        AsmLoader(ClassLoader parent) {
+            super(parent);
+        }
+
+        @Override
+        protected Class<?> findClass(String name) throws ClassNotFoundException {
+            if (name.equals(generatedClassName)) {
+                if (loaded == null) {
+                    byte[] gen = generateClass();
+                    loaded = defineClass(name, gen, 0, gen.length);
+                }
+                return loaded;
+            } else {
+                return super.findClass(name);
+            }
+        }
+
+        private byte[] generateClass() {
+            ClassWriter cw = new ClassWriter(0);
+            cw.visit(52, ACC_SUPER | ACC_PUBLIC, generatedClassNameInternal, null, "java/lang/Object", null);
+
+            FieldVisitor intField = cw.visitField(ACC_PRIVATE | ACC_STATIC, "intField", "I", null, value);
+            intField.visitEnd();
+
+            MethodVisitor get = cw.visitMethod(ACC_PRIVATE | ACC_STATIC, "get", "()" + kind.getTypeChar(), null, null);
+            get.visitCode();
+            get.visitFieldInsn(GETSTATIC, generatedClassNameInternal, "intField", "I");
+            get.visitInsn(IRETURN);
+            get.visitMaxs(1, 0);
+            get.visitEnd();
+
+            MethodVisitor snippet = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, testMethodName, "()I", null, null);
+            snippet.visitCode();
+            snippet.visitMethodInsn(INVOKESTATIC, generatedClassNameInternal, "get", "()" + kind.getTypeChar(), false);
+            snippet.visitInsn(IRETURN);
+            snippet.visitMaxs(1, 0);
+            snippet.visitEnd();
+
+            cw.visitEnd();
+            return cw.toByteArray();
+        }
+    }
+
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/UnbalancedMonitorsTest.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/UnbalancedMonitorsTest.java	Wed Nov 08 16:03:35 2017 -0500
@@ -87,7 +87,7 @@
         ResolvedJavaMethod method = getResolvedJavaMethod(LOADER.findClass(INNER_CLASS_NAME), name);
         try {
             OptionValues options = getInitialOptions();
-            StructuredGraph graph = new StructuredGraph.Builder(options, getDebugContext(options)).method(method).build();
+            StructuredGraph graph = new StructuredGraph.Builder(options, getDebugContext(options, null, method)).method(method).build();
             Plugins plugins = new Plugins(new InvocationPlugins());
             GraphBuilderConfiguration graphBuilderConfig = GraphBuilderConfiguration.getDefault(plugins).withEagerResolving(true).withUnresolvedIsError(true);
             OptimisticOptimizations optimisticOpts = OptimisticOptimizations.NONE;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/UnsafeVirtualizationTest.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/UnsafeVirtualizationTest.java	Wed Nov 08 16:03:35 2017 -0500
@@ -32,9 +32,20 @@
 import org.graalvm.compiler.virtual.phases.ea.PartialEscapePhase;
 import org.junit.Test;
 
+import jdk.vm.ci.code.InstalledCode;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+
 public class UnsafeVirtualizationTest extends GraalCompilerTest {
 
-    public static class A {
+    public static class Base {
+        /*
+         * This padding ensure that the size of the Base class ends up as a multiple of 8, which
+         * makes the first field of the subclass 8-byte aligned.
+         */
+        double padding;
+    }
+
+    public static class A extends Base {
         int f1;
         int f2;
     }
@@ -56,39 +67,96 @@
         AF2Offset = o2;
     }
 
-    public static int unsafeSnippet0(int i1, int i2) {
+    public static int unsafeSnippet1(double i1) {
         A a = new A();
-        UNSAFE.putDouble(a, AF1Offset, i1 + i2);
+        UNSAFE.putDouble(a, AF1Offset, i1);
         return UNSAFE.getInt(a, AF1Offset) + UNSAFE.getInt(a, AF2Offset);
     }
 
-    public static int unsafeSnippet1(int i1, int i2) {
+    public static long unsafeSnippet2a(int i1) {
+        A a = new A();
+        UNSAFE.putDouble(a, AF1Offset, i1);
+        a.f1 = i1;
+        return UNSAFE.getLong(a, AF1Offset);
+    }
+
+    public static long unsafeSnippet2b(int i1) {
+        A a = new A();
+        UNSAFE.putDouble(a, AF1Offset, i1);
+        a.f2 = i1;
+        return UNSAFE.getLong(a, AF1Offset);
+    }
+
+    public static long unsafeSnippet3a(int i1) {
         A a = new A();
-        UNSAFE.putDouble(a, AF1Offset, i1 + i2);
-        a.f2 = i1;
-        return (int) UNSAFE.getDouble(a, AF1Offset);
+        UNSAFE.putDouble(a, AF1Offset, i1);
+        UNSAFE.putInt(a, AF1Offset, i1);
+        return UNSAFE.getLong(a, AF1Offset);
+    }
+
+    public static long unsafeSnippet3b(int i1) {
+        A a = new A();
+        UNSAFE.putDouble(a, AF1Offset, i1);
+        UNSAFE.putInt(a, AF2Offset, i1);
+        return UNSAFE.getLong(a, AF1Offset);
+    }
+
+    public static int unsafeSnippet4(double i1) {
+        A a = new A();
+        UNSAFE.putDouble(a, AF1Offset, i1);
+        UNSAFE.putDouble(a, AF1Offset, i1);
+        return UNSAFE.getInt(a, AF1Offset) + UNSAFE.getInt(a, AF2Offset);
     }
 
     @Test
     public void testUnsafePEA01() {
-        testPartialEscapeReadElimination(parseEager("unsafeSnippet0", AllowAssumptions.NO), false);
-        testPartialEscapeReadElimination(parseEager("unsafeSnippet0", AllowAssumptions.NO), true);
+        testPartialEscapeReadElimination("unsafeSnippet1", false, 1.0);
+        testPartialEscapeReadElimination("unsafeSnippet1", true, 1.0);
     }
 
     @Test
     public void testUnsafePEA02() {
-        testPartialEscapeReadElimination(parseEager("unsafeSnippet1", AllowAssumptions.NO), false);
-        testPartialEscapeReadElimination(parseEager("unsafeSnippet1", AllowAssumptions.NO), true);
+        testPartialEscapeReadElimination("unsafeSnippet2a", false, 1);
+        testPartialEscapeReadElimination("unsafeSnippet2a", true, 1);
+
+        testPartialEscapeReadElimination("unsafeSnippet2b", false, 1);
+        testPartialEscapeReadElimination("unsafeSnippet2b", true, 1);
     }
 
-    public void testPartialEscapeReadElimination(StructuredGraph graph, boolean canonicalizeBefore) {
+    @Test
+    public void testUnsafePEA03() {
+        testPartialEscapeReadElimination("unsafeSnippet3a", false, 1);
+        testPartialEscapeReadElimination("unsafeSnippet3a", true, 1);
+
+        testPartialEscapeReadElimination("unsafeSnippet3b", false, 1);
+        testPartialEscapeReadElimination("unsafeSnippet3b", true, 1);
+    }
+
+    @Test
+    public void testUnsafePEA04() {
+        testPartialEscapeReadElimination("unsafeSnippet4", false, 1.0);
+        testPartialEscapeReadElimination("unsafeSnippet4", true, 1.0);
+    }
+
+    public void testPartialEscapeReadElimination(String snippet, boolean canonicalizeBefore, Object... args) {
+        assert AF1Offset % 8 == 0 : "First of the two int-fields must be 8-byte aligned";
+
+        ResolvedJavaMethod method = getResolvedJavaMethod(snippet);
+        StructuredGraph graph = parseEager(snippet, AllowAssumptions.NO);
         OptionValues options = graph.getOptions();
         PhaseContext context = getDefaultHighTierContext();
         CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
         if (canonicalizeBefore) {
             canonicalizer.apply(graph, context);
         }
+        Result r = executeExpected(method, null, args);
         new PartialEscapePhase(true, true, canonicalizer, null, options).apply(graph, context);
+        try {
+            InstalledCode code = getCode(method, graph);
+            Object result = code.executeVarargs(args);
+            assertEquals(r, new Result(result, null));
+        } catch (Throwable e) {
+            assertFalse(true, e.toString());
+        }
     }
-
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/EATestBase.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/EATestBase.java	Wed Nov 08 16:03:35 2017 -0500
@@ -77,7 +77,7 @@
 
         @Override
         public String toString() {
-            return "{" + x + "," + y + "}";
+            return "{" + x + "," + y + "," + z + "}";
         }
 
         @Override
@@ -158,11 +158,19 @@
             context = getDefaultHighTierContext();
             new InliningPhase(new CanonicalizerPhase()).apply(graph, context);
             new DeadCodeEliminationPhase().apply(graph);
-            new CanonicalizerPhase().apply(graph, context);
+            canonicalizeGraph();
             new PartialEscapePhase(iterativeEscapeAnalysis, false, new CanonicalizerPhase(), null, graph.getOptions()).apply(graph, context);
+            postEACanonicalizeGraph();
             returnNodes = graph.getNodes(ReturnNode.TYPE).snapshot();
         } catch (Throwable e) {
             throw debug.handle(e);
         }
     }
+
+    protected void postEACanonicalizeGraph() {
+    }
+
+    protected void canonicalizeGraph() {
+        new CanonicalizerPhase().apply(graph, context);
+    }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/PEAAssertionsTest.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/PEAAssertionsTest.java	Wed Nov 08 16:03:35 2017 -0500
@@ -27,9 +27,20 @@
 import org.graalvm.compiler.api.directives.GraalDirectives;
 import org.graalvm.compiler.code.SourceStackTraceBailoutException;
 import org.graalvm.compiler.core.test.GraalCompilerTest;
+import org.graalvm.compiler.phases.OptimisticOptimizations;
+import org.graalvm.compiler.phases.OptimisticOptimizations.Optimization;
+import org.graalvm.compiler.phases.tiers.HighTierContext;
 
 public class PEAAssertionsTest extends GraalCompilerTest {
 
+    /**
+     * These tests assume all code paths are reachable so disable profile based dead code removal.
+     */
+    @Override
+    protected HighTierContext getDefaultHighTierContext() {
+        return new HighTierContext(getProviders(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL.remove(Optimization.RemoveNeverExecutedCode));
+    }
+
     public static Object field;
 
     public static void snippet1(int i) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/TrufflePEATest.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/TrufflePEATest.java	Wed Nov 08 16:03:35 2017 -0500
@@ -22,6 +22,8 @@
  */
 package org.graalvm.compiler.core.test.ea;
 
+import java.lang.reflect.Field;
+
 import org.graalvm.compiler.core.common.GraalOptions;
 import org.graalvm.compiler.core.test.GraalCompilerTest;
 import org.graalvm.compiler.nodes.StructuredGraph;
@@ -33,10 +35,9 @@
 import org.graalvm.compiler.phases.tiers.HighTierContext;
 import org.graalvm.compiler.virtual.phases.ea.PartialEscapePhase;
 import org.junit.Test;
+
 import sun.misc.Unsafe;
 
-import java.lang.reflect.Field;
-
 public class TrufflePEATest extends GraalCompilerTest {
 
     /**
@@ -56,6 +57,7 @@
     static class DynamicObject {
         int primitiveField0;
         int primitiveField1;
+        int primitiveField2;
     }
 
     private static final long offsetLong1 = Unsafe.ARRAY_LONG_BASE_OFFSET + Unsafe.ARRAY_LONG_INDEX_SCALE * 1;
@@ -66,7 +68,15 @@
     static {
         try {
             Field primitiveField0 = DynamicObject.class.getDeclaredField("primitiveField0");
-            primitiveField0Offset = UNSAFE.objectFieldOffset(primitiveField0);
+            long offset = UNSAFE.objectFieldOffset(primitiveField0);
+            if (offset % 8 == 0) {
+                primitiveField0Offset = offset;
+            } else {
+                Field primitiveField1 = DynamicObject.class.getDeclaredField("primitiveField1");
+                offset = UNSAFE.objectFieldOffset(primitiveField1);
+                assert offset % 8 == 0;
+                primitiveField0Offset = offset;
+            }
         } catch (NoSuchFieldException | SecurityException e) {
             throw new AssertionError(e);
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/UnsafeEATest.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/UnsafeEATest.java	Wed Nov 08 16:03:35 2017 -0500
@@ -22,14 +22,26 @@
  */
 package org.graalvm.compiler.core.test.ea;
 
-import jdk.vm.ci.meta.JavaConstant;
+import java.nio.ByteBuffer;
 
+import org.graalvm.compiler.api.directives.GraalDirectives;
+import org.graalvm.compiler.graph.Graph;
+import org.graalvm.compiler.graph.Node;
+import org.graalvm.compiler.nodes.NamedLocationIdentity;
+import org.graalvm.compiler.nodes.PhiNode;
+import org.graalvm.compiler.nodes.ValuePhiNode;
+import org.graalvm.compiler.nodes.calc.UnpackEndianHalfNode;
+import org.graalvm.compiler.nodes.extended.RawLoadNode;
+import org.graalvm.compiler.nodes.extended.RawStoreNode;
+import org.graalvm.compiler.nodes.extended.UnsafeAccessNode;
+import org.graalvm.compiler.nodes.java.LoadFieldNode;
+import org.graalvm.compiler.phases.common.CanonicalizerPhase;
 import org.junit.Assert;
 import org.junit.Test;
 
-import org.graalvm.compiler.nodes.PhiNode;
-import org.graalvm.compiler.nodes.ValuePhiNode;
-import org.graalvm.compiler.nodes.java.LoadFieldNode;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
 
 public class UnsafeEATest extends EATestBase {
 
@@ -56,6 +68,64 @@
         }
     }
 
+    @Override
+    protected void testEscapeAnalysis(String snippet, JavaConstant expectedConstantResult, boolean iterativeEscapeAnalysis) {
+        // Exercise both a graph containing UnsafeAccessNodes and one which has been possibly been
+        // canonicalized into AccessFieldNodes.
+        testingUnsafe = true;
+        super.testEscapeAnalysis(snippet, expectedConstantResult, iterativeEscapeAnalysis);
+        testingUnsafe = false;
+        super.testEscapeAnalysis(snippet, expectedConstantResult, iterativeEscapeAnalysis);
+        if (expectedConstantResult != null) {
+            // Check that a compiled version of this method returns the same value if we expect a
+            // constant result.
+            ResolvedJavaMethod method = getResolvedJavaMethod(snippet);
+            JavaKind[] javaKinds = method.getSignature().toParameterKinds(false);
+            Object[] args = new Object[javaKinds.length];
+            int i = 0;
+            for (JavaKind k : javaKinds) {
+                args[i++] = JavaConstant.defaultForKind(k).asBoxedPrimitive();
+            }
+            Result result = executeExpected(method, null, args);
+            assertTrue(result.returnValue.equals(expectedConstantResult.asBoxedPrimitive()));
+        }
+    }
+
+    @Override
+    protected void canonicalizeGraph() {
+        if (testingUnsafe) {
+            // For testing purposes we'd like to ensure that our raw unsafe operations stay as
+            // unsafe nodes, so force them to appear to have LocationIdentity.any to disable
+            // transformation into field access nodes.
+            for (Node node : graph.getNodes().filter(x -> x instanceof UnsafeAccessNode).snapshot()) {
+                if (node instanceof RawStoreNode) {
+                    RawStoreNode store = (RawStoreNode) node;
+                    RawStoreNode newStore = graph.add(new RawStoreNode(store.object(), store.offset(), store.value(), store.accessKind(), NamedLocationIdentity.any(),
+                                    store.needsBarrier(), store.stateAfter(), true));
+                    graph.replaceFixedWithFixed(store, newStore);
+                } else if (node instanceof RawLoadNode) {
+                    RawLoadNode load = (RawLoadNode) node;
+                    RawLoadNode newLoad = graph.add(new RawLoadNode(load.object(), load.offset(), load.accessKind(), NamedLocationIdentity.any(),
+                                    true));
+                    graph.replaceFixedWithFixed(load, newLoad);
+                }
+            }
+        }
+        super.canonicalizeGraph();
+    }
+
+    @Override
+    protected void postEACanonicalizeGraph() {
+        // Simplify any UnpackEndianHalfNode so we end up with constants.
+        Graph.Mark mark = graph.getMark();
+        for (UnpackEndianHalfNode node : graph.getNodes().filter(UnpackEndianHalfNode.class)) {
+            node.lower(getTarget().arch.getByteOrder());
+        }
+        new CanonicalizerPhase().applyIncremental(graph, context, mark);
+    }
+
+    private boolean testingUnsafe;
+
     @Test
     public void testSimpleInt() {
         testEscapeAnalysis("testSimpleIntSnippet", JavaConstant.forInt(101), false);
@@ -90,6 +160,82 @@
     }
 
     @Test
+    public void testSimpleDoubleOverwriteWithInt() {
+        testEscapeAnalysis("testSimpleDoubleOverwriteWithIntSnippet", JavaConstant.forInt(10), false);
+    }
+
+    public static int testSimpleDoubleOverwriteWithIntSnippet() {
+        TestClassInt x = new TestClassInt();
+        UNSAFE.putDouble(x, fieldOffset1, 10.1);
+        UNSAFE.putInt(x, fieldOffset1, 10);
+        return UNSAFE.getInt(x, fieldOffset1);
+    }
+
+    @Test
+    public void testSimpleDoubleOverwriteWithSecondInt() {
+        ByteBuffer bb = ByteBuffer.allocate(8).order(getTarget().arch.getByteOrder());
+        bb.putDouble(10.1);
+        int value = bb.getInt(4);
+
+        testEscapeAnalysis("testSimpleDoubleOverwriteWithSecondIntSnippet", JavaConstant.forInt(value), false);
+    }
+
+    public static int testSimpleDoubleOverwriteWithSecondIntSnippet() {
+        TestClassInt x = new TestClassInt();
+        UNSAFE.putDouble(x, fieldOffset1, 10.1);
+        UNSAFE.putInt(x, fieldOffset1, 10);
+        return UNSAFE.getInt(x, fieldOffset2);
+    }
+
+    @Test
+    public void testSimpleDoubleOverwriteWithFirstInt() {
+        ByteBuffer bb = ByteBuffer.allocate(8).order(getTarget().arch.getByteOrder());
+        bb.putDouble(10.1);
+        int value = bb.getInt(0);
+
+        testEscapeAnalysis("testSimpleDoubleOverwriteWithFirstIntSnippet", JavaConstant.forInt(value), false);
+    }
+
+    public static int testSimpleDoubleOverwriteWithFirstIntSnippet() {
+        TestClassInt x = new TestClassInt();
+        UNSAFE.putDouble(x, fieldOffset1, 10.1);
+        UNSAFE.putInt(x, fieldOffset2, 10);
+        return UNSAFE.getInt(x, fieldOffset1);
+    }
+
+    @Test
+    public void testSimpleLongOverwriteWithSecondInt() {
+        ByteBuffer bb = ByteBuffer.allocate(8).order(getTarget().arch.getByteOrder());
+        bb.putLong(0, 0x1122334455667788L);
+        int value = bb.getInt(4);
+
+        testEscapeAnalysis("testSimpleLongOverwriteWithSecondIntSnippet", JavaConstant.forInt(value), false);
+    }
+
+    public static int testSimpleLongOverwriteWithSecondIntSnippet() {
+        TestClassInt x = new TestClassInt();
+        UNSAFE.putLong(x, fieldOffset1, 0x1122334455667788L);
+        UNSAFE.putInt(x, fieldOffset1, 10);
+        return UNSAFE.getInt(x, fieldOffset2);
+    }
+
+    @Test
+    public void testSimpleLongOverwriteWithFirstInt() {
+        ByteBuffer bb = ByteBuffer.allocate(8).order(getTarget().arch.getByteOrder());
+        bb.putLong(0, 0x1122334455667788L);
+        int value = bb.getInt(0);
+
+        testEscapeAnalysis("testSimpleLongOverwriteWithFirstIntSnippet", JavaConstant.forInt(value), false);
+    }
+
+    public static int testSimpleLongOverwriteWithFirstIntSnippet() {
+        TestClassInt x = new TestClassInt();
+        UNSAFE.putLong(x, fieldOffset1, 0x1122334455667788L);
+        UNSAFE.putInt(x, fieldOffset2, 10);
+        return UNSAFE.getInt(x, fieldOffset1);
+    }
+
+    @Test
     public void testMergedDouble() {
         testEscapeAnalysis("testMergedDoubleSnippet", null, false);
         Assert.assertEquals(1, returnNodes.size());
@@ -111,6 +257,32 @@
         return UNSAFE.getDouble(x, fieldOffset1);
     }
 
+    static class ExtendedTestClassInt extends TestClassInt {
+        public long l;
+    }
+
+    @Test
+    public void testMergedVirtualObjects() {
+        testEscapeAnalysis("testMergedVirtualObjectsSnippet", null, false);
+    }
+
+    public static TestClassInt testMergedVirtualObjectsSnippet(int value) {
+        TestClassInt x;
+        if (value == 1) {
+            x = new TestClassInt();
+            UNSAFE.putDouble(x, fieldOffset1, 10);
+        } else {
+            x = new TestClassInt();
+            UNSAFE.putInt(x, fieldOffset1, 0);
+        }
+        UNSAFE.putInt(x, fieldOffset1, 0);
+        if (value == 2) {
+            UNSAFE.putInt(x, fieldOffset2, 0);
+        }
+        GraalDirectives.deoptimizeAndInvalidate();
+        return x;
+    }
+
     @Test
     public void testMaterializedDouble() {
         test("testMaterializedDoubleSnippet");
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/inlining/NestedLoopEffectsPhaseComplexityTest.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/inlining/NestedLoopEffectsPhaseComplexityTest.java	Wed Nov 08 16:03:35 2017 -0500
@@ -146,7 +146,7 @@
 
     private StructuredGraph parseBytecodes(ResolvedJavaMethod method, HighTierContext context, CanonicalizerPhase canonicalizer) {
         OptionValues options = getInitialOptions();
-        StructuredGraph newGraph = new StructuredGraph.Builder(options, getDebugContext(options), AllowAssumptions.NO).method(method).build();
+        StructuredGraph newGraph = new StructuredGraph.Builder(options, getDebugContext(options, null, method), AllowAssumptions.NO).method(method).build();
         context.getGraphBuilderSuite().apply(newGraph, context);
         new DeadCodeEliminationPhase(Optional).apply(newGraph);
         canonicalizer.apply(newGraph, context);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/GraalCompilerOptions.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/GraalCompilerOptions.java	Wed Nov 08 16:03:35 2017 -0500
@@ -47,7 +47,7 @@
      public static final EnumOptionKey<ExceptionAction> CompilationFailureAction = new EnumOptionKey<>(ExceptionAction.Diagnose);
     @Option(help = "The maximum number of compilation failures or bailouts to handle with the action specified " +
                    "by CompilationFailureAction or CompilationBailoutAction before changing to a less verbose action.", type = OptionType.User)
-    public static final OptionKey<Integer> MaxCompilationProblemsPerAction = new OptionKey<>(5);
+    public static final OptionKey<Integer> MaxCompilationProblemsPerAction = new OptionKey<>(2);
     @Option(help = "Alias for CompilationFailureAction=ExitVM.", type = OptionType.User)
     public static final OptionKey<Boolean> ExitVMOnException = new OptionKey<>(false);
     // @formatter:on
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/DebugInfoBuilder.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/DebugInfoBuilder.java	Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -132,8 +132,17 @@
                             slotKinds[pos] = toSlotKind(value);
                             pos++;
                         } else {
-                            assert currentField.values().get(i - 1).getStackKind() == JavaKind.Double || currentField.values().get(i - 1).getStackKind() == JavaKind.Long : vobjNode + " " + i + " " +
-                                            currentField.values().get(i - 1);
+                            assert value.getStackKind() == JavaKind.Illegal;
+                            ValueNode previousValue = currentField.values().get(i - 1);
+                            assert (previousValue != null && previousValue.getStackKind().needsTwoSlots()) : vobjNode + " " + i +
+                                            " " + previousValue + " " + currentField.values().snapshot();
+                            if (previousValue == null || !previousValue.getStackKind().needsTwoSlots()) {
+                                // Don't allow the IllegalConstant to leak into the debug info
+                                JavaKind entryKind = vobjNode.entryKind(i);
+                                values[pos] = JavaConstant.defaultForKind(entryKind.getStackKind());
+                                slotKinds[pos] = entryKind.getStackKind();
+                                pos++;
+                            }
                         }
                     }
                     if (pos != entryCount) {
@@ -164,19 +173,19 @@
             if (!type.isArray()) {
                 ResolvedJavaField[] fields = type.getInstanceFields(true);
                 int fieldIndex = 0;
-                for (int i = 0; i < values.length; i++) {
-                    ResolvedJavaField field = fields[fieldIndex++];
-                    JavaKind valKind = slotKinds[i].getStackKind();
+                for (int valueIndex = 0; valueIndex < values.length; valueIndex++, fieldIndex++) {
+                    ResolvedJavaField field = fields[fieldIndex];
+                    JavaKind valKind = slotKinds[valueIndex].getStackKind();
                     JavaKind fieldKind = storageKind(field.getType());
-                    if (fieldKind == JavaKind.Object) {
-                        assert valKind.isObject() : field + ": " + valKind + " != " + fieldKind;
+                    if ((valKind == JavaKind.Double || valKind == JavaKind.Long) && fieldKind == JavaKind.Int) {
+                        assert fieldIndex + 1 < fields.length : String.format("Not enough fields for fieldIndex = %d valueIndex = %d %s %s", fieldIndex, valueIndex, Arrays.toString(fields),
+                                        Arrays.toString(values));
+                        assert storageKind(fields[fieldIndex + 1].getType()) == JavaKind.Int : String.format("fieldIndex = %d valueIndex = %d %s %s %s", fieldIndex, valueIndex,
+                                        storageKind(fields[fieldIndex + 1].getType()), Arrays.toString(fields),
+                                        Arrays.toString(values));
+                        fieldIndex++;
                     } else {
-                        if ((valKind == JavaKind.Double || valKind == JavaKind.Long) && fieldKind == JavaKind.Int) {
-                            assert storageKind(fields[fieldIndex].getType()) == JavaKind.Int;
-                            fieldIndex++;
-                        } else {
-                            assert valKind == fieldKind.getStackKind() : field + ": " + valKind + " != " + fieldKind;
-                        }
+                        assert valKind == fieldKind.getStackKind() : field + ": " + valKind + " != " + fieldKind;
                     }
                 }
                 assert fields.length == fieldIndex : type + ": fields=" + Arrays.toString(fields) + ", field values=" + Arrays.toString(values);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/NodeLIRBuilder.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/NodeLIRBuilder.java	Wed Nov 08 16:03:35 2017 -0500
@@ -59,6 +59,7 @@
 import org.graalvm.compiler.lir.SwitchStrategy;
 import org.graalvm.compiler.lir.Variable;
 import org.graalvm.compiler.lir.debug.LIRGenerationDebugContext;
+import org.graalvm.compiler.lir.framemap.FrameMapBuilder;
 import org.graalvm.compiler.lir.gen.LIRGenerator;
 import org.graalvm.compiler.lir.gen.LIRGenerator.Options;
 import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
@@ -577,9 +578,9 @@
     @Override
     public void emitInvoke(Invoke x) {
         LoweredCallTargetNode callTarget = (LoweredCallTargetNode) x.callTarget();
-        CallingConvention invokeCc = gen.getResult().getFrameMapBuilder().getRegisterConfig().getCallingConvention(callTarget.callType(), x.asNode().stamp().javaType(gen.getMetaAccess()),
-                        callTarget.signature(), gen);
-        gen.getResult().getFrameMapBuilder().callsMethod(invokeCc);
+        FrameMapBuilder frameMapBuilder = gen.getResult().getFrameMapBuilder();
+        CallingConvention invokeCc = frameMapBuilder.getRegisterConfig().getCallingConvention(callTarget.callType(), x.asNode().stamp().javaType(gen.getMetaAccess()), callTarget.signature(), gen);
+        frameMapBuilder.callsMethod(invokeCc);
 
         Value[] parameters = visitInvokeArguments(invokeCc, callTarget.arguments());
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/target/Backend.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/target/Backend.java	Wed Nov 08 16:03:35 2017 -0500
@@ -195,9 +195,12 @@
     public InstalledCode createInstalledCode(DebugContext debug, ResolvedJavaMethod method, CompilationRequest compilationRequest, CompilationResult compilationResult,
                     SpeculationLog speculationLog, InstalledCode predefinedInstalledCode, boolean isDefault, Object[] context) {
         Object[] debugContext = context != null ? context : new Object[]{getProviders().getCodeCache(), method, compilationResult};
-        CodeInstallationTask[] tasks = new CodeInstallationTask[codeInstallationTaskFactories.size()];
-        for (int i = 0; i < codeInstallationTaskFactories.size(); i++) {
-            tasks[i] = codeInstallationTaskFactories.get(i).create();
+        CodeInstallationTask[] tasks;
+        synchronized (this) {
+            tasks = new CodeInstallationTask[codeInstallationTaskFactories.size()];
+            for (int i = 0; i < codeInstallationTaskFactories.size(); i++) {
+                tasks[i] = codeInstallationTaskFactories.get(i).create();
+            }
         }
         try (DebugContext.Scope s2 = debug.scope("CodeInstall", debugContext);
                         DebugContext.Activation a = debug.activate()) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/DebugContext.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/DebugContext.java	Wed Nov 08 16:03:35 2017 -0500
@@ -29,9 +29,11 @@
 import static org.graalvm.compiler.debug.DebugOptions.Dump;
 import static org.graalvm.compiler.debug.DebugOptions.DumpOnError;
 import static org.graalvm.compiler.debug.DebugOptions.DumpOnPhaseChange;
+import static org.graalvm.compiler.debug.DebugOptions.DumpPath;
 import static org.graalvm.compiler.debug.DebugOptions.ListMetrics;
 import static org.graalvm.compiler.debug.DebugOptions.Log;
 import static org.graalvm.compiler.debug.DebugOptions.MemUseTrackers;
+import static org.graalvm.compiler.debug.DebugOptions.ShowDumpFiles;
 import static org.graalvm.compiler.debug.DebugOptions.Time;
 import static org.graalvm.compiler.debug.DebugOptions.Timers;
 import static org.graalvm.compiler.debug.DebugOptions.TrackMemUse;
@@ -56,6 +58,7 @@
 
 import org.graalvm.compiler.options.OptionKey;
 import org.graalvm.compiler.options.OptionValues;
+import org.graalvm.graphio.GraphOutput;
 import org.graalvm.util.EconomicMap;
 import org.graalvm.util.EconomicSet;
 import org.graalvm.util.Pair;
@@ -98,6 +101,8 @@
     CloseableCounter currentMemUseTracker;
     Scope lastClosedScope;
     Throwable lastExceptionThrown;
+    private IgvDumpChannel sharedChannel;
+    private GraphOutput<?, ?> parentOutput;
 
     /**
      * Stores the {@link MetricKey} values.
@@ -111,6 +116,19 @@
         return immutable.scopesEnabled;
     }
 
+    public <G, N, M> GraphOutput<G, M> buildOutput(GraphOutput.Builder<G, N, M> builder) throws IOException {
+        if (parentOutput != null) {
+            return builder.build(parentOutput);
+        } else {
+            if (sharedChannel == null) {
+                sharedChannel = new IgvDumpChannel(() -> getDumpPath(".bgv", false), immutable.options);
+            }
+            final GraphOutput<G, M> output = builder.build(sharedChannel);
+            parentOutput = output;
+            return output;
+        }
+    }
+
     /**
      * The immutable configuration that can be shared between {@link DebugContext} objects.
      */
@@ -323,6 +341,14 @@
             String compilableName = compilable instanceof JavaMethod ? ((JavaMethod) compilable).format("%H.%n(%p)%R") : String.valueOf(compilable);
             return identifier + ":" + compilableName;
         }
+
+        final String getLabel() {
+            if (compilable instanceof JavaMethod) {
+                JavaMethod method = (JavaMethod) compilable;
+                return method.format("%h.%n(%p)%r");
+            }
+            return String.valueOf(compilable);
+        }
     }
 
     private final Description description;
@@ -394,6 +420,20 @@
         }
     }
 
+    public Path getDumpPath(String extension, boolean directory) {
+        try {
+            String id = description == null ? null : description.identifier;
+            String label = description == null ? null : description.getLabel();
+            Path result = PathUtilities.createUnique(immutable.options, DumpPath, id, label, extension, directory);
+            if (ShowDumpFiles.getValue(immutable.options)) {
+                TTY.println("Dumping debug output to %s", result.toAbsolutePath().toString());
+            }
+            return result;
+        } catch (IOException ex) {
+            throw rethrowSilently(RuntimeException.class, ex);
+        }
+    }
+
     /**
      * A special dump level that indicates the dumping machinery is enabled but no dumps will be
      * produced except through other options.
@@ -2043,4 +2083,9 @@
         }
         out.println();
     }
+
+    @SuppressWarnings({"unused", "unchecked"})
+    private static <E extends Exception> E rethrowSilently(Class<E> type, Throwable ex) throws E {
+        throw (E) ex;
+    }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/DebugHandlersFactory.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/DebugHandlersFactory.java	Wed Nov 08 16:03:35 2017 -0500
@@ -35,6 +35,9 @@
 
     /**
      * Creates {@link DebugHandler}s based on {@code options}.
+     *
+     * @param options options to control type and name of the channel
+     * @return list of debug handers that have been created
      */
     List<DebugHandler> createHandlers(OptionValues options);
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/DebugOptions.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/DebugOptions.java	Wed Nov 08 16:03:35 2017 -0500
@@ -128,8 +128,6 @@
     public static final OptionKey<Boolean> PrintGraphProbabilities = new OptionKey<>(false);
     @Option(help = "Enable dumping to the IdealGraphVisualizer.", type = OptionType.Debug)
     public static final OptionKey<Boolean> PrintGraph = new OptionKey<>(true);
-    @Option(help = "Dump graphs in binary format instead of XML format.", type = OptionType.Debug)
-    public static final OptionKey<Boolean> PrintBinaryGraphs = new OptionKey<>(true);
     @Option(help = "Print graphs to files instead of sending them over the network.", type = OptionType.Debug)
     public static final OptionKey<Boolean> PrintGraphFile = new OptionKey<>(false);
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/IgvDumpChannel.java	Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 org.graalvm.compiler.debug;
+
+import java.io.IOException;
+import java.io.InterruptedIOException;
+import java.net.InetSocketAddress;
+import java.nio.ByteBuffer;
+import java.nio.channels.ClosedByInterruptException;
+import java.nio.channels.FileChannel;
+import java.nio.channels.SocketChannel;
+import java.nio.channels.WritableByteChannel;
+import java.nio.file.Path;
+import java.nio.file.StandardOpenOption;
+import java.util.function.Supplier;
+import static org.graalvm.compiler.debug.DebugOptions.PrintBinaryGraphPort;
+import static org.graalvm.compiler.debug.DebugOptions.PrintGraphHost;
+import org.graalvm.compiler.options.OptionValues;
+
+final class IgvDumpChannel implements WritableByteChannel {
+    private final Supplier<Path> pathProvider;
+    private final OptionValues options;
+    private WritableByteChannel sharedChannel;
+    private boolean closed;
+
+    IgvDumpChannel(Supplier<Path> pathProvider, OptionValues options) {
+        this.pathProvider = pathProvider;
+        this.options = options;
+    }
+
+    @Override
+    public int write(ByteBuffer src) throws IOException {
+        return channel().write(src);
+    }
+
+    @Override
+    public boolean isOpen() {
+        return !closed;
+    }
+
+    @Override
+    public void close() throws IOException {
+    }
+
+    void realClose() throws IOException {
+        closed = true;
+        if (sharedChannel != null) {
+            sharedChannel.close();
+            sharedChannel = null;
+        }
+    }
+
+    WritableByteChannel channel() throws IOException {
+        if (closed) {
+            throw new IOException();
+        }
+        if (sharedChannel == null) {
+            if (DebugOptions.PrintGraphFile.getValue(options)) {
+                sharedChannel = createFileChannel(pathProvider);
+            } else {
+                sharedChannel = createNetworkChannel(pathProvider, options);
+            }
+        }
+        return sharedChannel;
+    }
+
+    private static WritableByteChannel createNetworkChannel(Supplier<Path> pathProvider, OptionValues options) throws IOException {
+        String host = PrintGraphHost.getValue(options);
+        int port = PrintBinaryGraphPort.getValue(options);
+        try {
+            WritableByteChannel channel = SocketChannel.open(new InetSocketAddress(host, port));
+            TTY.println("Connected to the IGV on %s:%d", host, port);
+            return channel;
+        } catch (ClosedByInterruptException | InterruptedIOException e) {
+            /*
+             * Interrupts should not count as errors because they may be caused by a cancelled Graal
+             * compilation. ClosedByInterruptException occurs if the SocketChannel could not be
+             * opened. InterruptedIOException occurs if new Socket(..) was interrupted.
+             */
+            return null;
+        } catch (IOException e) {
+            if (!DebugOptions.PrintGraphFile.hasBeenSet(options)) {
+                return createFileChannel(pathProvider);
+            } else {
+                throw new IOException(String.format("Could not connect to the IGV on %s:%d", host, port), e);
+            }
+        }
+    }
+
+    private static WritableByteChannel createFileChannel(Supplier<Path> pathProvider) throws IOException {
+        Path path = pathProvider.get();
+        try {
+            return FileChannel.open(path, StandardOpenOption.WRITE, StandardOpenOption.CREATE);
+        } catch (IOException e) {
+            throw new IOException(String.format("Failed to open %s to dump IGV graphs", path), e);
+        }
+    }
+
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/PathUtilities.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/PathUtilities.java	Wed Nov 08 16:03:35 2017 -0500
@@ -22,12 +22,13 @@
  */
 package org.graalvm.compiler.debug;
 
+import java.io.File;
 import java.io.IOException;
+import java.nio.file.FileAlreadyExistsException;
+import java.nio.file.Files;
 import java.nio.file.InvalidPathException;
 import java.nio.file.Path;
 import java.nio.file.Paths;
-import java.util.HashMap;
-import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicLong;
 
 import org.graalvm.compiler.options.OptionKey;
@@ -39,54 +40,6 @@
 public class PathUtilities {
 
     private static final AtomicLong globalTimeStamp = new AtomicLong();
-    /**
-     * This generates a per thread persistent id to aid mapping related dump files with each other.
-     */
-    private static final ThreadLocal<PerThreadSequence> threadDumpId = new ThreadLocal<>();
-    private static final AtomicInteger dumpId = new AtomicInteger();
-
-    static class PerThreadSequence {
-        final int threadID;
-        HashMap<String, Integer> sequences = new HashMap<>(2);
-
-        PerThreadSequence(int threadID) {
-            this.threadID = threadID;
-        }
-
-        String generateID(String extension) {
-            Integer box = sequences.get(extension);
-            if (box == null) {
-                sequences.put(extension, 1);
-                return Integer.toString(threadID);
-            } else {
-                sequences.put(extension, box + 1);
-                return Integer.toString(threadID) + '-' + box;
-            }
-        }
-    }
-
-    private static String getThreadDumpId(String extension) {
-        PerThreadSequence id = threadDumpId.get();
-        if (id == null) {
-            id = new PerThreadSequence(dumpId.incrementAndGet());
-            threadDumpId.set(id);
-        }
-        return id.generateID(extension);
-    }
-
-    /**
-     * Prepends a period (i.e., {@code '.'}) to an non-null, non-empty string representation a file
-     * extension if the string does not already start with a period.
-     *
-     * @return {@code ext} unmodified if it is null, empty or already starts with a period other
-     *         {@code "." + ext}
-     */
-    public static String formatExtension(String ext) {
-        if (ext == null || ext.length() == 0) {
-            return "";
-        }
-        return "." + ext;
-    }
 
     /**
      * Gets a time stamp for the current process. This method will always return the same value for
@@ -100,43 +53,6 @@
     }
 
     /**
-     * Generates a {@link Path} using the format "%s-%d_%d%s" with the {@code baseNameOption}, a
-     * {@link #getGlobalTimeStamp() global timestamp} , {@link #getThreadDumpId a per thread unique
-     * id} and an optional {@code extension}.
-     *
-     * @return the output file path or null if the flag is null
-     */
-    public static Path getPath(OptionValues options, OptionKey<String> baseNameOption, String extension) throws IOException {
-        return getPath(options, baseNameOption, extension, true);
-    }
-
-    /**
-     * Generate a {@link Path} using the format "%s-%d_%s" with the {@code baseNameOption}, a
-     * {@link #getGlobalTimeStamp() global timestamp} and an optional {@code extension} .
-     *
-     * @return the output file path or null if the flag is null
-     */
-    public static Path getPathGlobal(OptionValues options, OptionKey<String> baseNameOption, String extension) throws IOException {
-        return getPath(options, baseNameOption, extension, false);
-    }
-
-    private static Path getPath(OptionValues options, OptionKey<String> baseNameOption, String extension, boolean includeThreadId) throws IOException {
-        if (baseNameOption.getValue(options) == null) {
-            return null;
-        }
-        String ext = formatExtension(extension);
-        final String name = includeThreadId
-                        ? String.format("%s-%d_%s%s", baseNameOption.getValue(options), getGlobalTimeStamp(), getThreadDumpId(ext), ext)
-                        : String.format("%s-%d%s", baseNameOption.getValue(options), getGlobalTimeStamp(), ext);
-        Path result = Paths.get(name);
-        if (result.isAbsolute()) {
-            return result;
-        }
-        Path dumpDir = DebugOptions.getDumpDirectory(options);
-        return dumpDir.resolve(name).normalize();
-    }
-
-    /**
      * Gets a value based on {@code name} that can be passed to {@link Paths#get(String, String...)}
      * without causing an {@link InvalidPathException}.
      *
@@ -145,21 +61,80 @@
      */
     public static String sanitizeFileName(String name) {
         try {
-            Paths.get(name);
-            return name;
+            Path path = Paths.get(name);
+            if (path.getNameCount() == 0) {
+                return name;
+            }
         } catch (InvalidPathException e) {
             // fall through
         }
         StringBuilder buf = new StringBuilder(name.length());
         for (int i = 0; i < name.length(); i++) {
             char c = name.charAt(i);
-            try {
-                Paths.get(String.valueOf(c));
-            } catch (InvalidPathException e) {
-                buf.append('_');
+            if (c != File.separatorChar && c != ' ' && !Character.isISOControl(c)) {
+                try {
+                    Paths.get(String.valueOf(c));
+                    buf.append(c);
+                    continue;
+                } catch (InvalidPathException e) {
+                }
             }
-            buf.append(c);
+            buf.append('_');
         }
         return buf.toString();
     }
+
+    /**
+     * A maximum file name length supported by most file systems. There is no platform independent
+     * way to get this in Java.
+     */
+    private static final int MAX_FILE_NAME_LENGTH = 255;
+
+    private static final String ELLIPSIS = "...";
+
+    static Path createUnique(OptionValues options, OptionKey<String> baseNameOption, String id, String label, String ext, boolean createDirectory) throws IOException {
+        String uniqueTag = "";
+        int dumpCounter = 1;
+        String prefix;
+        if (id == null) {
+            prefix = baseNameOption.getValue(options);
+            int slash = prefix.lastIndexOf(File.separatorChar);
+            prefix = prefix.substring(slash + 1);
+        } else {
+            prefix = id;
+        }
+        for (;;) {
+            int fileNameLengthWithoutLabel = uniqueTag.length() + ext.length() + prefix.length() + "[]".length();
+            int labelLengthLimit = MAX_FILE_NAME_LENGTH - fileNameLengthWithoutLabel;
+            String fileName;
+            if (labelLengthLimit < ELLIPSIS.length()) {
+                // This means `id` is very long
+                String suffix = uniqueTag + ext;
+                int idLengthLimit = Math.min(MAX_FILE_NAME_LENGTH - suffix.length(), prefix.length());
+                fileName = sanitizeFileName(prefix.substring(0, idLengthLimit) + suffix);
+            } else {
+                if (label == null) {
+                    fileName = sanitizeFileName(prefix + uniqueTag + ext);
+                } else {
+                    String adjustedLabel = label;
+                    if (label.length() > labelLengthLimit) {
+                        adjustedLabel = label.substring(0, labelLengthLimit - ELLIPSIS.length()) + ELLIPSIS;
+                    }
+                    fileName = sanitizeFileName(prefix + '[' + adjustedLabel + ']' + uniqueTag + ext);
+                }
+            }
+            Path dumpDir = DebugOptions.getDumpDirectory(options);
+            Path result = Paths.get(dumpDir.toString(), fileName);
+            try {
+                if (createDirectory) {
+                    return Files.createDirectory(result);
+                } else {
+                    return Files.createFile(result);
+                }
+            } catch (FileAlreadyExistsException e) {
+                uniqueTag = "_" + dumpCounter++;
+            }
+        }
+    }
+
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph.test/src/org/graalvm/compiler/graph/test/graphio/GraphSnippetTest.java	Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 org.graalvm.compiler.graph.test.graphio;
+
+import java.io.File;
+import java.lang.reflect.Method;
+import static org.junit.Assert.assertTrue;
+import org.junit.Assume;
+import org.junit.Test;
+
+public class GraphSnippetTest {
+    @Test
+    public void dumpTheFile() throws Exception {
+        Class<?> snippets = null;
+        try {
+            snippets = Class.forName("org.graalvm.graphio.GraphSnippets");
+        } catch (ClassNotFoundException notFound) {
+            Assume.assumeNoException("The snippets class has to be around", notFound);
+        }
+        Method dump = null;
+        try {
+            dump = snippets.getDeclaredMethod("dump", File.class);
+            dump.setAccessible(true);
+        } catch (RuntimeException ex) {
+            Assume.assumeTrue("Only run the test, if the method is accessible", dump != null && dump.isAccessible());
+        }
+        File diamond = File.createTempFile("diamond", ".bgv");
+        dump.invoke(null, diamond);
+        assertTrue("File .bgv created: " + diamond, diamond.length() > 50);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph.test/src/org/graalvm/compiler/graph/test/graphio/NodeEncodingTest.java	Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,311 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 org.graalvm.compiler.graph.test.graphio;
+
+import java.io.ByteArrayOutputStream;
+import java.nio.channels.Channels;
+import java.nio.channels.WritableByteChannel;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import org.graalvm.graphio.GraphOutput;
+import org.graalvm.graphio.GraphStructure;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import org.junit.Before;
+import org.junit.Test;
+
+public final class NodeEncodingTest {
+
+    private ByteArrayOutputStream out;
+
+    @Before
+    public void initOutput() {
+        out = new ByteArrayOutputStream();
+    }
+
+    @Test
+    public void version40TheNodeIsntDumpedWithItsID() throws Exception {
+        runTheNodeIsntDumpedWithItsID(true);
+    }
+
+    @Test
+    public void defaultVersionTheNodeIsntDumpedWithItsID() throws Exception {
+        runTheNodeIsntDumpedWithItsID(false);
+    }
+
+    private void runTheNodeIsntDumpedWithItsID(boolean explicitVersion) throws Exception {
+        WritableByteChannel w = Channels.newChannel(out);
+        MockGraph graph = new MockGraph();
+        MockNodeClass clazz = new MockNodeClass("clazz");
+        MockNode node = new MockNode(clazz, 33); // random value otherwise not found in the stream
+        try (GraphOutput<MockGraph, ?> dump = explicitVersion ? GraphOutput.newBuilder(new MockStructure()).protocolVersion(4, 0).build(w) : GraphOutput.newBuilder(new MockStructure()).build(w)) {
+            dump.beginGroup(graph, "test1", "t1", null, 0, Collections.singletonMap("node", node));
+            dump.endGroup();
+        }
+
+        assertEquals("Node is always requested", 1, node.nodeRequested);
+        assertEquals("Nobody asks for id of a node in version 4.0", 0, node.idTested);
+        assertByte(false, out.toByteArray(), 33);
+        assertEquals("Node class of the node has been requested", 1, node.nodeClassRequested);
+        assertEquals("Node class template name stored", 1, clazz.nameTemplateQueried);
+        assertFalse("No to string ops", node.toStringRequested);
+    }
+
+    @Test
+    public void dumpingNodeInVersion10() throws Exception {
+        runTheNodeIsTreatedAsString(true);
+    }
+
+    private void runTheNodeIsTreatedAsString(boolean explicitVersion) throws Exception {
+        WritableByteChannel w = Channels.newChannel(out);
+        MockGraph graph = new MockGraph();
+        MockNodeClass clazz = new MockNodeClass("clazz");
+        MockNode node = new MockNode(clazz, 33); // random value otherwise not found in the stream
+        try (GraphOutput<MockGraph, ?> dump = explicitVersion ? GraphOutput.newBuilder(new MockStructure()).protocolVersion(1, 0).build(w) : GraphOutput.newBuilder(new MockStructure()).build(w)) {
+            dump.beginGroup(graph, "test1", "t1", null, 0, Collections.singletonMap("node", node));
+            dump.endGroup();
+        }
+
+        assertEquals("Node is always requested", 1, node.nodeRequested);
+        assertEquals("Nobody asks for id of a node in version 1.0", 0, node.idTested);
+        assertByte(false, out.toByteArray(), 33);
+        assertEquals("Node class was needed to find out it is not a NodeClass instance", 1, node.nodeClassRequested);
+        assertEquals("Node class template name wasn't needed however", 0, clazz.nameTemplateQueried);
+        assertTrue("Node sent as a string version 1.0", node.toStringRequested);
+    }
+
+    @Test
+    public void dumpingNodeInVersion15() throws Exception {
+        runTheNodeIsTreatedPoolEntry(true);
+    }
+
+    private void runTheNodeIsTreatedPoolEntry(boolean explicitVersion) throws Exception {
+        WritableByteChannel w = Channels.newChannel(out);
+        MockGraph graph = new MockGraph();
+        MockNodeClass clazz = new MockNodeClass("clazz");
+        MockNode node = new MockNode(clazz, 33); // random value otherwise not found in the stream
+        try (GraphOutput<MockGraph, ?> dump = explicitVersion ? GraphOutput.newBuilder(new MockStructure()).protocolVersion(5, 0).build(w) : GraphOutput.newBuilder(new MockStructure()).build(w)) {
+            dump.beginGroup(graph, "test1", "t1", null, 0, Collections.singletonMap("node", node));
+            dump.endGroup();
+        }
+
+        assertEquals("Node is always requested", 1, node.nodeRequested);
+        assertEquals("Id of our node is requested in version 5.0", 1, node.idTested);
+        assertByte(true, out.toByteArray(), 33);
+        assertTrue("Node class was needed at least once", 1 <= node.nodeClassRequested);
+        assertEquals("Node class template name sent to server", 1, clazz.nameTemplateQueried);
+        assertFalse("Node.toString() isn't needed", node.toStringRequested);
+    }
+
+    @Test
+    public void dumpingNodeTwiceInVersion4() throws Exception {
+        WritableByteChannel w = Channels.newChannel(out);
+        MockGraph graph = new MockGraph();
+        MockNodeClass clazz = new MockNodeClass("clazz");
+        MockNode node = new MockNode(clazz, 33); // random value otherwise not found in the stream
+        try (GraphOutput<MockGraph, ?> dump = GraphOutput.newBuilder(new MockStructure()).protocolVersion(4, 0).build(w)) {
+            Map<String, Object> props = new LinkedHashMap<>();
+            props.put("node1", node);
+            props.put("node2", node);
+            props.put("node3", node);
+            dump.beginGroup(graph, "test1", "t1", null, 0, props);
+            dump.endGroup();
+        }
+
+        assertEquals("Node requested three times", 3, node.nodeRequested);
+        assertEquals("Nobody asks for id of a node in version 4.0", 0, node.idTested);
+        // check there is no encoded string for object #3
+        assertByte(false, out.toByteArray(), 1, 0, 3);
+        assertEquals("Node class of the node has been requested three times", 3, node.nodeClassRequested);
+        assertEquals("Node class template name stored", 1, clazz.nameTemplateQueried);
+        assertFalse("No to string ops", node.toStringRequested);
+    }
+
+    private static void assertByte(boolean shouldBeFound, byte[] arr, int... value) {
+        boolean found = false;
+        int at = 0;
+        for (int i = 0; i < arr.length; i++) {
+            if (arr[i] == value[at]) {
+                if (++at == value.length) {
+                    found = true;
+                    break;
+                }
+            } else {
+                at = 0;
+            }
+        }
+        if (shouldBeFound == found) {
+            return;
+        }
+        if (shouldBeFound) {
+            fail("Value " + value + " not found in\n" + Arrays.toString(arr));
+        } else {
+            fail("Value " + value + " surprisingly found in\n" + Arrays.toString(arr));
+        }
+    }
+
+    private static final class MockStructure implements GraphStructure<MockGraph, MockNode, MockNodeClass, MockNodeClass> {
+
+        @Override
+        public MockGraph graph(MockGraph currentGraph, Object obj) {
+            return obj instanceof MockGraph ? (MockGraph) obj : null;
+        }
+
+        @Override
+        public Iterable<? extends MockNode> nodes(MockGraph graph) {
+            return Collections.emptyList();
+        }
+
+        @Override
+        public int nodesCount(MockGraph graph) {
+            return 0;
+        }
+
+        @Override
+        public int nodeId(MockNode node) {
+            node.idTested++;
+            return node.id;
+        }
+
+        @Override
+        public boolean nodeHasPredecessor(MockNode node) {
+            return false;
+        }
+
+        @Override
+        public void nodeProperties(MockGraph graph, MockNode node, Map<String, ? super Object> properties) {
+        }
+
+        @Override
+        public MockNode node(Object obj) {
+            if (obj instanceof MockNode) {
+                ((MockNode) obj).nodeRequested++;
+                return (MockNode) obj;
+            }
+            return null;
+        }
+
+        @Override
+        public MockNodeClass nodeClass(Object obj) {
+            if (obj instanceof MockNode) {
+                ((MockNode) obj).nodeClassRequested++;
+            }
+            return obj instanceof MockNodeClass ? (MockNodeClass) obj : null;
+        }
+
+        @Override
+        public MockNodeClass classForNode(MockNode n) {
+            n.nodeClassRequested++;
+            return n.clazz;
+        }
+
+        @Override
+        public String nameTemplate(MockNodeClass nodeClass) {
+            nodeClass.nameTemplateQueried++;
+            return "";
+        }
+
+        @Override
+        public Object nodeClassType(MockNodeClass nodeClass) {
+            return nodeClass.getClass();
+        }
+
+        @Override
+        public MockNodeClass portInputs(MockNodeClass nodeClass) {
+            return nodeClass;
+        }
+
+        @Override
+        public MockNodeClass portOutputs(MockNodeClass nodeClass) {
+            return nodeClass;
+        }
+
+        @Override
+        public int portSize(MockNodeClass port) {
+            return 0;
+        }
+
+        @Override
+        public boolean edgeDirect(MockNodeClass port, int index) {
+            return false;
+        }
+
+        @Override
+        public String edgeName(MockNodeClass port, int index) {
+            return null;
+        }
+
+        @Override
+        public Object edgeType(MockNodeClass port, int index) {
+            return null;
+        }
+
+        @Override
+        public Collection<? extends MockNode> edgeNodes(MockGraph graph, MockNode node, MockNodeClass port, int index) {
+            return null;
+        }
+    }
+
+    private static final class MockGraph {
+
+    }
+
+    private static final class MockNode {
+        final MockNodeClass clazz;
+        final int id;
+        int idTested;
+        int nodeClassRequested;
+        int nodeRequested;
+        boolean toStringRequested;
+
+        MockNode(MockNodeClass clazz, int id) {
+            this.clazz = clazz;
+            this.id = id;
+        }
+
+        @Override
+        public String toString() {
+            this.toStringRequested = true;
+            return "MockNode{" + "id=" + id + ", class=" + clazz + '}';
+        }
+    }
+
+    private static final class MockNodeClass {
+        final String name;
+        int nameTemplateQueried;
+
+        MockNodeClass(String name) {
+            this.name = name;
+        }
+
+        @Override
+        public String toString() {
+            return "MockNodeClass{" + "name=" + name + '}';
+        }
+    }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/Graph.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/Graph.java	Wed Nov 08 16:03:35 2017 -0500
@@ -514,30 +514,61 @@
         /**
          * A node was added to a graph.
          */
-        NODE_ADDED;
+        NODE_ADDED,
+
+        /**
+         * A node was removed from the graph.
+         */
+        NODE_REMOVED;
     }
 
     /**
      * Client interested in one or more node related events.
      */
-    public interface NodeEventListener {
+    public abstract static class NodeEventListener {
 
         /**
-         * Default handler for events.
+         * A method called when a change event occurs.
+         *
+         * This method dispatches the event to user-defined triggers. The methods that change the
+         * graph (typically in Graph and Node) must call this method to dispatch the event.
          *
          * @param e an event
          * @param node the node related to {@code e}
          */
-        default void event(NodeEvent e, Node node) {
+        final void event(NodeEvent e, Node node) {
+            switch (e) {
+                case INPUT_CHANGED:
+                    inputChanged(node);
+                    break;
+                case ZERO_USAGES:
+                    usagesDroppedToZero(node);
+                    break;
+                case NODE_ADDED:
+                    nodeAdded(node);
+                    break;
+                case NODE_REMOVED:
+                    nodeRemoved(node);
+                    break;
+            }
+            changed(e, node);
         }
 
         /**
-         * Notifies this listener of a change in a node's inputs.
+         * Notifies this listener about any change event in the graph.
+         *
+         * @param e an event
+         * @param node the node related to {@code e}
+         */
+        public void changed(NodeEvent e, Node node) {
+        }
+
+        /**
+         * Notifies this listener about a change in a node's inputs.
          *
          * @param node a node who has had one of its inputs changed
          */
-        default void inputChanged(Node node) {
-            event(NodeEvent.INPUT_CHANGED, node);
+        public void inputChanged(Node node) {
         }
 
         /**
@@ -545,8 +576,7 @@
          *
          * @param node a node whose {@link Node#usages()} just became empty
          */
-        default void usagesDroppedToZero(Node node) {
-            event(NodeEvent.ZERO_USAGES, node);
+        public void usagesDroppedToZero(Node node) {
         }
 
         /**
@@ -554,8 +584,15 @@
          *
          * @param node a node that was just added to the graph
          */
-        default void nodeAdded(Node node) {
-            event(NodeEvent.NODE_ADDED, node);
+        public void nodeAdded(Node node) {
+        }
+
+        /**
+         * Notifies this listener of a removed node.
+         *
+         * @param node
+         */
+        public void nodeRemoved(Node node) {
         }
     }
 
@@ -583,7 +620,7 @@
         }
     }
 
-    private static class ChainedNodeEventListener implements NodeEventListener {
+    private static class ChainedNodeEventListener extends NodeEventListener {
 
         NodeEventListener head;
         NodeEventListener next;
@@ -595,20 +632,32 @@
 
         @Override
         public void nodeAdded(Node node) {
-            head.nodeAdded(node);
-            next.nodeAdded(node);
+            head.event(NodeEvent.NODE_ADDED, node);
+            next.event(NodeEvent.NODE_ADDED, node);
         }
 
         @Override
         public void inputChanged(Node node) {
-            head.inputChanged(node);
-            next.inputChanged(node);
+            head.event(NodeEvent.INPUT_CHANGED, node);
+            next.event(NodeEvent.INPUT_CHANGED, node);
         }
 
         @Override
         public void usagesDroppedToZero(Node node) {
-            head.usagesDroppedToZero(node);
-            next.usagesDroppedToZero(node);
+            head.event(NodeEvent.ZERO_USAGES, node);
+            next.event(NodeEvent.ZERO_USAGES, node);
+        }
+
+        @Override
+        public void nodeRemoved(Node node) {
+            head.event(NodeEvent.NODE_REMOVED, node);
+            next.event(NodeEvent.NODE_REMOVED, node);
+        }
+
+        @Override
+        public void changed(NodeEvent e, Node node) {
+            head.event(e, node);
+            next.event(e, node);
         }
     }
 
@@ -1023,7 +1072,7 @@
         updateNodeCaches(node);
 
         if (nodeEventListener != null) {
-            nodeEventListener.nodeAdded(node);
+            nodeEventListener.event(NodeEvent.NODE_ADDED, node);
         }
         afterRegister(node);
     }
@@ -1085,6 +1134,10 @@
         nodes[node.id] = null;
         nodesDeletedSinceLastCompression++;
 
+        if (nodeEventListener != null) {
+            nodeEventListener.event(NodeEvent.NODE_ADDED, node);
+        }
+
         // nodes aren't removed from the type cache here - they will be removed during iteration
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/Node.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/Node.java	Wed Nov 08 16:03:35 2017 -0500
@@ -752,7 +752,7 @@
             assert !graph.isFrozen();
             NodeEventListener listener = graph.nodeEventListener;
             if (listener != null) {
-                listener.inputChanged(node);
+                listener.event(Graph.NodeEvent.INPUT_CHANGED, node);
             }
         }
     }
@@ -762,7 +762,7 @@
             assert !graph.isFrozen();
             NodeEventListener listener = graph.nodeEventListener;
             if (listener != null && node.isAlive()) {
-                listener.usagesDroppedToZero(node);
+                listener.event(Graph.NodeEvent.ZERO_USAGES, node);
             }
         }
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotNodeLIRBuilder.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotNodeLIRBuilder.java	Wed Nov 08 16:03:35 2017 -0500
@@ -183,8 +183,7 @@
             sig[i] = node.arguments().get(i).stamp().javaType(gen.getMetaAccess());
         }
 
-        Value[] parameters = visitInvokeArguments(gen.getResult().getFrameMapBuilder().getRegisterConfig().getCallingConvention(HotSpotCallingConventionType.JavaCall, null, sig, gen),
-                        node.arguments());
+        Value[] parameters = visitInvokeArguments(gen.getRegisterConfig().getCallingConvention(HotSpotCallingConventionType.JavaCall, null, sig, gen), node.arguments());
         append(new AArch64BreakpointOp(parameters));
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotAddressLowering.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotAddressLowering.java	Wed Nov 08 16:03:35 2017 -0500
@@ -32,7 +32,6 @@
 import org.graalvm.compiler.core.amd64.AMD64AddressNode;
 import org.graalvm.compiler.core.common.CompressEncoding;
 import org.graalvm.compiler.core.common.LIRKind;
-import org.graalvm.compiler.core.common.NumUtil;
 import org.graalvm.compiler.core.common.type.ObjectStamp;
 import org.graalvm.compiler.core.common.type.StampFactory;
 import org.graalvm.compiler.debug.CounterKey;
@@ -44,6 +43,7 @@
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.CompressionNode;
 import org.graalvm.compiler.nodes.CompressionNode.CompressionOp;
+import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.FloatingNode;
 import org.graalvm.compiler.nodes.spi.LIRLowerable;
@@ -93,76 +93,76 @@
     }
 
     @Override
-    protected boolean improve(DebugContext debug, AMD64AddressNode addr) {
-
-        boolean result = false;
-
-        while (super.improve(debug, addr)) {
-            result = true;
+    protected boolean improve(StructuredGraph graph, DebugContext debug, AMD64AddressNode addr, boolean isBaseNegated, boolean isIndexNegated) {
+        if (super.improve(graph, debug, addr, isBaseNegated, isIndexNegated)) {
+            return true;
         }
 
         if (addr.getScale() == Scale.Times1) {
             if (addr.getIndex() instanceof CompressionNode) {
-                if (improveUncompression(addr, (CompressionNode) addr.getIndex(), addr.getBase())) {
+                if (improveUncompression(addr, (CompressionNode) addr.getIndex(), addr.getBase(), isBaseNegated, isIndexNegated)) {
                     counterFoldedUncompressDuringAddressLowering.increment(debug);
                     return true;
                 }
             }
 
             if (addr.getBase() instanceof CompressionNode) {
-                if (improveUncompression(addr, (CompressionNode) addr.getBase(), addr.getIndex())) {
+                if (improveUncompression(addr, (CompressionNode) addr.getBase(), addr.getIndex(), isBaseNegated, isIndexNegated)) {
                     counterFoldedUncompressDuringAddressLowering.increment(debug);
                     return true;
                 }
             }
         }
 
-        return result;
+        return false;
+    }
+
+    @Override
+    protected boolean mightBeOptimized(ValueNode value) {
+        return super.mightBeOptimized(value) || value instanceof CompressionNode;
     }
 
-    private boolean improveUncompression(AMD64AddressNode addr, CompressionNode compression, ValueNode other) {
-        if (compression.getOp() == CompressionOp.Uncompress) {
-            CompressEncoding encoding = compression.getEncoding();
-            Scale scale = Scale.fromShift(encoding.getShift());
-            if (scale == null) {
+    private boolean improveUncompression(AMD64AddressNode addr, CompressionNode compression, ValueNode other, boolean isBaseNegated, boolean isIndexNegated) {
+        if (isBaseNegated || isIndexNegated || compression.getOp() != CompressionOp.Uncompress) {
+            return false;
+        }
+
+        CompressEncoding encoding = compression.getEncoding();
+        Scale scale = Scale.fromShift(encoding.getShift());
+        if (scale == null) {
+            return false;
+        }
+
+        if (heapBaseRegister != null && encoding.getBase() == heapBase) {
+            if ((!generatePIC || compression.stamp() instanceof ObjectStamp) && other == null) {
+                // With PIC it is only legal to do for oops since the base value may be
+                // different at runtime.
+                ValueNode base = compression.graph().unique(new HeapBaseNode(heapBaseRegister));
+                addr.setBase(base);
+            } else {
                 return false;
             }
-
-            if (heapBaseRegister != null && encoding.getBase() == heapBase) {
-                if ((!generatePIC || compression.stamp() instanceof ObjectStamp) && other == null) {
-                    // With PIC it is only legal to do for oops since the base value may be
-                    // different at runtime.
-                    ValueNode base = compression.graph().unique(new HeapBaseNode(heapBaseRegister));
+        } else if (encoding.getBase() != 0 || (generatePIC && compression.stamp() instanceof KlassPointerStamp)) {
+            if (generatePIC) {
+                if (other == null) {
+                    ValueNode base = compression.graph().unique(new GraalHotSpotVMConfigNode(config, config.MARKID_NARROW_KLASS_BASE_ADDRESS, JavaKind.Long));
                     addr.setBase(base);
                 } else {
                     return false;
                 }
-            } else if (encoding.getBase() != 0 || (generatePIC && compression.stamp() instanceof KlassPointerStamp)) {
-                if (generatePIC) {
-                    if (other == null) {
-                        ValueNode base = compression.graph().unique(new GraalHotSpotVMConfigNode(config, config.MARKID_NARROW_KLASS_BASE_ADDRESS, JavaKind.Long));
-                        addr.setBase(base);
-                    } else {
-                        return false;
-                    }
+            } else {
+                if (updateDisplacement(addr, encoding.getBase(), isBaseNegated)) {
+                    addr.setBase(other);
                 } else {
-                    long disp = addr.getDisplacement() + encoding.getBase();
-                    if (NumUtil.isInt(disp)) {
-                        addr.setDisplacement((int) disp);
-                        addr.setBase(other);
-                    } else {
-                        return false;
-                    }
+                    return false;
                 }
-            } else {
-                addr.setBase(other);
             }
+        } else {
+            addr.setBase(other);
+        }
 
-            addr.setScale(scale);
-            addr.setIndex(compression.getValue());
-            return true;
-        } else {
-            return false;
-        }
+        addr.setScale(scale);
+        addr.setIndex(compression.getValue());
+        return true;
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Wed Nov 08 16:03:35 2017 -0500
@@ -39,7 +39,6 @@
 import org.graalvm.compiler.asm.amd64.AMD64Address.Scale;
 import org.graalvm.compiler.core.amd64.AMD64ArithmeticLIRGenerator;
 import org.graalvm.compiler.core.amd64.AMD64LIRGenerator;
-import org.graalvm.compiler.core.amd64.AMD64LIRKindTool;
 import org.graalvm.compiler.core.amd64.AMD64MoveFactoryBase.BackupSlotProvider;
 import org.graalvm.compiler.core.common.CompressEncoding;
 import org.graalvm.compiler.core.common.LIRKind;
@@ -116,7 +115,7 @@
     }
 
     private AMD64HotSpotLIRGenerator(HotSpotProviders providers, GraalHotSpotVMConfig config, LIRGenerationResult lirGenRes, BackupSlotProvider backupSlotProvider) {
-        this(new AMD64LIRKindTool(), new AMD64HotSpotArithmeticLIRGenerator(), new AMD64HotSpotMoveFactory(backupSlotProvider), providers, config, lirGenRes);
+        this(new AMD64HotSpotLIRKindTool(), new AMD64HotSpotArithmeticLIRGenerator(), new AMD64HotSpotMoveFactory(backupSlotProvider), providers, config, lirGenRes);
     }
 
     protected AMD64HotSpotLIRGenerator(LIRKindTool lirKindTool, AMD64ArithmeticLIRGenerator arithmeticLIRGen, MoveFactory moveFactory, HotSpotProviders providers, GraalHotSpotVMConfig config,
@@ -363,7 +362,7 @@
         Stub stub = getStub();
         if (destroysRegisters) {
             if (stub != null && stub.preservesRegisters()) {
-                Register[] savedRegisters = getResult().getFrameMapBuilder().getRegisterConfig().getAllocatableRegisters().toArray();
+                Register[] savedRegisters = getRegisterConfig().getAllocatableRegisters().toArray();
                 save = emitSaveAllRegisters(savedRegisters, true);
             }
         }
@@ -567,28 +566,29 @@
     @Override
     public Value emitCompress(Value pointer, CompressEncoding encoding, boolean nonNull) {
         LIRKind inputKind = pointer.getValueKind(LIRKind.class);
-        assert inputKind.getPlatformKind() == AMD64Kind.QWORD;
+        LIRKindTool lirKindTool = getLIRKindTool();
+        assert inputKind.getPlatformKind() == lirKindTool.getObjectKind().getPlatformKind();
         if (inputKind.isReference(0)) {
             // oop
-            Variable result = newVariable(LIRKind.reference(AMD64Kind.DWORD));
-            append(new AMD64HotSpotMove.CompressPointer(result, asAllocatable(pointer), getProviders().getRegisters().getHeapBaseRegister().asValue(), encoding, nonNull));
+            Variable result = newVariable(lirKindTool.getNarrowOopKind());
+            append(new AMD64Move.CompressPointer(result, asAllocatable(pointer), getProviders().getRegisters().getHeapBaseRegister().asValue(), encoding, nonNull, getLIRKindTool()));
             return result;
         } else {
             // metaspace pointer
-            Variable result = newVariable(LIRKind.value(AMD64Kind.DWORD));
+            Variable result = newVariable(lirKindTool.getNarrowPointerKind());
             AllocatableValue base = Value.ILLEGAL;
             OptionValues options = getResult().getLIR().getOptions();
             if (encoding.hasBase() || GeneratePIC.getValue(options)) {
                 if (GeneratePIC.getValue(options)) {
-                    Variable baseAddress = newVariable(LIRKind.value(AMD64Kind.QWORD));
+                    Variable baseAddress = newVariable(lirKindTool.getWordKind());
                     AMD64HotSpotMove.BaseMove move = new AMD64HotSpotMove.BaseMove(baseAddress, config);
                     append(move);
                     base = baseAddress;
                 } else {
-                    base = emitLoadConstant(LIRKind.value(AMD64Kind.QWORD), JavaConstant.forLong(encoding.getBase()));
+                    base = emitLoadConstant(lirKindTool.getWordKind(), JavaConstant.forLong(encoding.getBase()));
                 }
             }
-            append(new AMD64HotSpotMove.CompressPointer(result, asAllocatable(pointer), base, encoding, nonNull));
+            append(new AMD64Move.CompressPointer(result, asAllocatable(pointer), base, encoding, nonNull, getLIRKindTool()));
             return result;
         }
     }
@@ -596,35 +596,37 @@
     @Override
     public Value emitUncompress(Value pointer, CompressEncoding encoding, boolean nonNull) {
         LIRKind inputKind = pointer.getValueKind(LIRKind.class);
-        assert inputKind.getPlatformKind() == AMD64Kind.DWORD;
+        LIRKindTool lirKindTool = getLIRKindTool();
+        assert inputKind.getPlatformKind() == lirKindTool.getNarrowOopKind().getPlatformKind();
         if (inputKind.isReference(0)) {
             // oop
-            Variable result = newVariable(LIRKind.reference(AMD64Kind.QWORD));
-            append(new AMD64HotSpotMove.UncompressPointer(result, asAllocatable(pointer), getProviders().getRegisters().getHeapBaseRegister().asValue(), encoding, nonNull));
+            Variable result = newVariable(lirKindTool.getObjectKind());
+            append(new AMD64Move.UncompressPointer(result, asAllocatable(pointer), getProviders().getRegisters().getHeapBaseRegister().asValue(), encoding, nonNull, lirKindTool));
             return result;
         } else {
             // metaspace pointer
-            Variable result = newVariable(LIRKind.value(AMD64Kind.QWORD));
+            LIRKind uncompressedKind = lirKindTool.getWordKind();
+            Variable result = newVariable(uncompressedKind);
             AllocatableValue base = Value.ILLEGAL;
             OptionValues options = getResult().getLIR().getOptions();
             if (encoding.hasBase() || GeneratePIC.getValue(options)) {
                 if (GeneratePIC.getValue(options)) {
-                    Variable baseAddress = newVariable(LIRKind.value(AMD64Kind.QWORD));
+                    Variable baseAddress = newVariable(uncompressedKind);
                     AMD64HotSpotMove.BaseMove move = new AMD64HotSpotMove.BaseMove(baseAddress, config);
                     append(move);
                     base = baseAddress;
                 } else {
-                    base = emitLoadConstant(LIRKind.value(AMD64Kind.QWORD), JavaConstant.forLong(encoding.getBase()));
+                    base = emitLoadConstant(uncompressedKind, JavaConstant.forLong(encoding.getBase()));
                 }
             }
-            append(new AMD64HotSpotMove.UncompressPointer(result, asAllocatable(pointer), base, encoding, nonNull));
+            append(new AMD64Move.UncompressPointer(result, asAllocatable(pointer), base, encoding, nonNull, lirKindTool));
             return result;
         }
     }
 
     @Override
     public void emitNullCheck(Value address, LIRFrameState state) {
-        if (address.getValueKind().getPlatformKind() == AMD64Kind.DWORD) {
+        if (address.getValueKind().getPlatformKind() == getLIRKindTool().getNarrowOopKind().getPlatformKind()) {
             CompressEncoding encoding = config.getOopEncoding();
             Value uncompressed;
             if (encoding.getShift() <= 3) {
@@ -635,9 +637,9 @@
                 uncompressed = emitUncompress(address, encoding, false);
             }
             append(new AMD64Move.NullCheckOp(asAddressValue(uncompressed), state));
-        } else {
-            super.emitNullCheck(address, state);
+            return;
         }
+        super.emitNullCheck(address, state);
     }
 
     @Override
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotLIRKindTool.java	Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 org.graalvm.compiler.hotspot.amd64;
+
+import jdk.vm.ci.amd64.AMD64Kind;
+import org.graalvm.compiler.core.amd64.AMD64LIRKindTool;
+import org.graalvm.compiler.core.common.LIRKind;
+
+public class AMD64HotSpotLIRKindTool extends AMD64LIRKindTool {
+    @Override
+    public LIRKind getNarrowOopKind() {
+        return LIRKind.reference(AMD64Kind.DWORD);
+    }
+
+    @Override
+    public LIRKind getNarrowPointerKind() {
+        return LIRKind.value(AMD64Kind.DWORD);
+    }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotMove.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotMove.java	Wed Nov 08 16:03:35 2017 -0500
@@ -24,16 +24,13 @@
 
 import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC;
 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.HINT;
-import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.ILLEGAL;
 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG;
 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.STACK;
 import static jdk.vm.ci.code.ValueUtil.asRegister;
 import static jdk.vm.ci.code.ValueUtil.isRegister;
 import static jdk.vm.ci.code.ValueUtil.isStackSlot;
 
-import org.graalvm.compiler.asm.Label;
 import org.graalvm.compiler.asm.amd64.AMD64Address;
-import org.graalvm.compiler.asm.amd64.AMD64Assembler.ConditionFlag;
 import org.graalvm.compiler.core.common.CompressEncoding;
 import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler;
 import org.graalvm.compiler.debug.GraalError;
@@ -41,10 +38,8 @@
 import org.graalvm.compiler.lir.LIRInstructionClass;
 import org.graalvm.compiler.lir.StandardOp.LoadConstantOp;
 import org.graalvm.compiler.lir.amd64.AMD64LIRInstruction;
-import org.graalvm.compiler.lir.amd64.AMD64Move;
 import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
 
-import jdk.vm.ci.amd64.AMD64Kind;
 import jdk.vm.ci.code.Register;
 import jdk.vm.ci.hotspot.HotSpotMetaspaceConstant;
 import jdk.vm.ci.hotspot.HotSpotObjectConstant;
@@ -180,91 +175,6 @@
         }
     }
 
-    public static final class CompressPointer extends AMD64LIRInstruction {
-        public static final LIRInstructionClass<CompressPointer> TYPE = LIRInstructionClass.create(CompressPointer.class);
-
-        private final CompressEncoding encoding;
-        private final boolean nonNull;
-
-        @Def({REG, HINT}) protected AllocatableValue result;
-        @Use({REG}) protected AllocatableValue input;
-        @Alive({REG, ILLEGAL}) protected AllocatableValue baseRegister;
-
-        public CompressPointer(AllocatableValue result, AllocatableValue input, AllocatableValue baseRegister, CompressEncoding encoding, boolean nonNull) {
-            super(TYPE);
-            this.result = result;
-            this.input = input;
-            this.baseRegister = baseRegister;
-            this.encoding = encoding;
-            this.nonNull = nonNull;
-        }
-
-        @Override
-        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
-            AMD64Move.move(AMD64Kind.QWORD, crb, masm, result, input);
-
-            Register resReg = asRegister(result);
-            if (encoding.hasBase() || GeneratePIC.getValue(crb.getOptions())) {
-                Register baseReg = asRegister(baseRegister);
-                if (!nonNull) {
-                    masm.testq(resReg, resReg);
-                    masm.cmovq(ConditionFlag.Equal, resReg, baseReg);
-                }
-                masm.subq(resReg, baseReg);
-            }
-
-            if (encoding.hasShift()) {
-                masm.shrq(resReg, encoding.getShift());
-            }
-        }
-    }
-
-    public static final class UncompressPointer extends AMD64LIRInstruction {
-        public static final LIRInstructionClass<UncompressPointer> TYPE = LIRInstructionClass.create(UncompressPointer.class);
-
-        private final CompressEncoding encoding;
-        private final boolean nonNull;
-
-        @Def({REG, HINT}) protected AllocatableValue result;
-        @Use({REG}) protected AllocatableValue input;
-        @Alive({REG, ILLEGAL}) protected AllocatableValue baseRegister;
-
-        public UncompressPointer(AllocatableValue result, AllocatableValue input, AllocatableValue baseRegister, CompressEncoding encoding, boolean nonNull) {
-            super(TYPE);
-            this.result = result;
-            this.input = input;
-            this.baseRegister = baseRegister;
-            this.encoding = encoding;
-            this.nonNull = nonNull;
-        }
-
-        @Override
-        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
-            AMD64Move.move(AMD64Kind.DWORD, crb, masm, result, input);
-
-            Register resReg = asRegister(result);
-            if (encoding.getShift() != 0) {
-                masm.shlq(resReg, encoding.getShift());
-            }
-
-            if (encoding.hasBase() || GeneratePIC.getValue(crb.getOptions())) {
-                if (nonNull) {
-                    masm.addq(resReg, asRegister(baseRegister));
-                } else {
-                    if (!encoding.hasShift()) {
-                        // if encoding.shift != 0, the flags are already set by the shlq
-                        masm.testq(resReg, resReg);
-                    }
-
-                    Label done = new Label();
-                    masm.jccb(ConditionFlag.Equal, done);
-                    masm.addq(resReg, asRegister(baseRegister));
-                    masm.bind(done);
-                }
-            }
-        }
-    }
-
     public static void decodeKlassPointer(CompilationResultBuilder crb, AMD64MacroAssembler masm, Register register, Register scratch, AMD64Address address, GraalHotSpotVMConfig config) {
         CompressEncoding encoding = config.getKlassEncoding();
         masm.movl(register, address);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotNodeLIRBuilder.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotNodeLIRBuilder.java	Wed Nov 08 16:03:35 2017 -0500
@@ -189,8 +189,7 @@
             sig[i] = node.arguments().get(i).stamp().javaType(gen.getMetaAccess());
         }
 
-        Value[] parameters = visitInvokeArguments(gen.getResult().getFrameMapBuilder().getRegisterConfig().getCallingConvention(HotSpotCallingConventionType.JavaCall, null, sig, gen),
-                        node.arguments());
+        Value[] parameters = visitInvokeArguments(gen.getRegisterConfig().getCallingConvention(HotSpotCallingConventionType.JavaCall, null, sig, gen), node.arguments());
         append(new AMD64BreakpointOp(parameters));
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotMove.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotMove.java	Wed Nov 08 16:03:35 2017 -0500
@@ -113,8 +113,7 @@
                 } else {
                     register = asRegister(result);
                 }
-                int bytes = result.getPlatformKind().getSizeInBytes();
-                loadFromConstantTable(crb, masm, bytes, asRegister(constantTableBase), constant, register, SPARCDelayedControlTransfer.DUMMY);
+                int bytes = loadFromConstantTable(crb, masm, asRegister(constantTableBase), constant, register, SPARCDelayedControlTransfer.DUMMY);
                 if (isStack) {
                     masm.st(register, (SPARCAddress) crb.asAddress(result), bytes);
                 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotNodeLIRBuilder.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotNodeLIRBuilder.java	Wed Nov 08 16:03:35 2017 -0500
@@ -162,8 +162,7 @@
             sig[i] = node.arguments().get(i).stamp().javaType(gen.getMetaAccess());
         }
 
-        Value[] parameters = visitInvokeArguments(gen.getResult().getFrameMapBuilder().getRegisterConfig().getCallingConvention(HotSpotCallingConventionType.JavaCall, null, sig, gen),
-                        node.arguments());
+        Value[] parameters = visitInvokeArguments(gen.getRegisterConfig().getCallingConvention(HotSpotCallingConventionType.JavaCall, null, sig, gen), node.arguments());
         append(new SPARCBreakpointOp(parameters));
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotStrategySwitchOp.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotStrategySwitchOp.java	Wed Nov 08 16:03:35 2017 -0500
@@ -77,8 +77,7 @@
                 boolean canUseShortBranch = masm.hasFeature(CPUFeature.CBCOND) && SPARCControlFlow.isShortBranch(masm, cbCondPosition, hint, target);
 
                 Register scratchRegister = asRegister(scratch);
-                final int byteCount = constant.isCompressed() ? 4 : 8;
-                loadFromConstantTable(crb, masm, byteCount, asRegister(constantTableBase), constant, scratchRegister, SPARCDelayedControlTransfer.DUMMY);
+                loadFromConstantTable(crb, masm, asRegister(constantTableBase), constant, scratchRegister, SPARCDelayedControlTransfer.DUMMY);
 
                 if (canUseShortBranch) {
                     CBCOND.emit(masm, conditionFlag, conditionCode == CC.Xcc, keyRegister, scratchRegister, target);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/ArrayCopyIntrinsificationTest.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/ArrayCopyIntrinsificationTest.java	Wed Nov 08 16:03:35 2017 -0500
@@ -160,7 +160,7 @@
     }
 
     /**
-     * Tests {@link ArrayCopySnippets#checkcastArraycopyWork}.
+     * Tests {@link ArrayCopySnippets#arraycopyCheckcastSnippet}.
      */
     @Test
     public void testArrayStoreException() {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompilationWrapperTest.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompilationWrapperTest.java	Wed Nov 08 16:03:35 2017 -0500
@@ -122,7 +122,7 @@
      * Tests compilation requested by Truffle.
      */
     @Test
-    public void testTruffleCompilation() throws IOException, InterruptedException {
+    public void testTruffleCompilation1() throws IOException, InterruptedException {
         testHelper(Collections.emptyList(),
                         Arrays.asList(
                                         "-Dgraal.CompilationFailureAction=ExitVM",
@@ -130,6 +130,22 @@
                         "org.graalvm.compiler.truffle.test.SLTruffleGraalTestSuite", "test");
     }
 
+    /**
+     * Tests that TruffleCompilationExceptionsAreFatal works as expected.
+     */
+    @Test
+    public void testTruffleCompilation2() throws IOException, InterruptedException {
+        Probe[] probes = {
+                        new Probe("Exiting VM due to TruffleCompilationExceptionsAreFatal=true", 1),
+        };
+        testHelper(Arrays.asList(probes),
+                        Arrays.asList(
+                                        "-Dgraal.CompilationFailureAction=Silent",
+                                        "-Dgraal.TruffleCompilationExceptionsAreFatal=true",
+                                        "-Dgraal.CrashAt=root test1"),
+                        "org.graalvm.compiler.truffle.test.SLTruffleGraalTestSuite", "test");
+    }
+
     private static final boolean VERBOSE = Boolean.getBoolean(CompilationWrapperTest.class.getSimpleName() + ".verbose");
 
     private static void testHelper(List<Probe> initialProbes, List<String> extraVmArgs, String... mainClassAndArgs) throws IOException, InterruptedException {
@@ -149,14 +165,17 @@
         }
 
         List<Probe> probes = new ArrayList<>(initialProbes);
-        Probe diagnosticProbe = new Probe("Graal diagnostic output saved in ", 1);
-        probes.add(diagnosticProbe);
-        probes.add(new Probe("Forced crash after compiling", Integer.MAX_VALUE) {
-            @Override
-            String test() {
-                return actualOccurrences > 0 ? null : "expected at least 1 occurrence";
-            }
-        });
+        Probe diagnosticProbe = null;
+        if (!extraVmArgs.contains("-Dgraal.TruffleCompilationExceptionsAreFatal=true")) {
+            diagnosticProbe = new Probe("Graal diagnostic output saved in ", 1);
+            probes.add(diagnosticProbe);
+            probes.add(new Probe("Forced crash after compiling", Integer.MAX_VALUE) {
+                @Override
+                String test() {
+                    return actualOccurrences > 0 ? null : "expected at least 1 occurrence";
+                }
+            });
+        }
 
         for (String line : proc.output) {
             for (Probe probe : probes) {
@@ -171,38 +190,42 @@
                 Assert.fail(String.format("Did not find expected occurences of '%s' in output of command: %s%n%s", probe.substring, error, proc));
             }
         }
+        if (diagnosticProbe != null) {
+            String line = diagnosticProbe.lastMatchingLine;
+            int substringStart = line.indexOf(diagnosticProbe.substring);
+            int substringLength = diagnosticProbe.substring.length();
+            String diagnosticOutputZip = line.substring(substringStart + substringLength).trim();
 
-        String diagnosticOutputZip = diagnosticProbe.lastMatchingLine.substring(diagnosticProbe.substring.length()).trim();
-
-        List<String> dumpPathEntries = Arrays.asList(dumpPath.list());
+            List<String> dumpPathEntries = Arrays.asList(dumpPath.list());
 
-        File zip = new File(diagnosticOutputZip).getAbsoluteFile();
-        Assert.assertTrue(zip.toString(), zip.exists());
-        Assert.assertTrue(zip + " not in " + dumpPathEntries, dumpPathEntries.contains(zip.getName()));
-        try {
-            int bgv = 0;
-            int cfg = 0;
-            ZipFile dd = new ZipFile(diagnosticOutputZip);
-            List<String> entries = new ArrayList<>();
-            for (Enumeration<? extends ZipEntry> e = dd.entries(); e.hasMoreElements();) {
-                ZipEntry ze = e.nextElement();
-                String name = ze.getName();
-                entries.add(name);
-                if (name.endsWith(".bgv")) {
-                    bgv++;
-                } else if (name.endsWith(".cfg")) {
-                    cfg++;
+            File zip = new File(diagnosticOutputZip).getAbsoluteFile();
+            Assert.assertTrue(zip.toString(), zip.exists());
+            Assert.assertTrue(zip + " not in " + dumpPathEntries, dumpPathEntries.contains(zip.getName()));
+            try {
+                int bgv = 0;
+                int cfg = 0;
+                ZipFile dd = new ZipFile(diagnosticOutputZip);
+                List<String> entries = new ArrayList<>();
+                for (Enumeration<? extends ZipEntry> e = dd.entries(); e.hasMoreElements();) {
+                    ZipEntry ze = e.nextElement();
+                    String name = ze.getName();
+                    entries.add(name);
+                    if (name.endsWith(".bgv")) {
+                        bgv++;
+                    } else if (name.endsWith(".cfg")) {
+                        cfg++;
+                    }
                 }
-            }
-            if (bgv == 0) {
-                Assert.fail(String.format("Expected at least one .bgv file in %s: %s%n%s", diagnosticOutputZip, entries, proc));
+                if (bgv == 0) {
+                    Assert.fail(String.format("Expected at least one .bgv file in %s: %s%n%s", diagnosticOutputZip, entries, proc));
+                }
+                if (cfg == 0) {
+                    Assert.fail(String.format("Expected at least one .cfg file in %s: %s", diagnosticOutputZip, entries));
+                }
+            } finally {
+                zip.delete();
+                dumpPath.delete();
             }
-            if (cfg == 0) {
-                Assert.fail(String.format("Expected at least one .cfg file in %s: %s", diagnosticOutputZip, entries));
-            }
-        } finally {
-            zip.delete();
-            dumpPath.delete();
         }
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/ExplicitExceptionTest.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/ExplicitExceptionTest.java	Wed Nov 08 16:03:35 2017 -0500
@@ -22,23 +22,44 @@
  */
 package org.graalvm.compiler.hotspot.test;
 
-import org.junit.Test;
-
 import org.graalvm.compiler.core.test.GraalCompilerTest;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.extended.ForeignCallNode;
 import org.graalvm.compiler.options.OptionValues;
+import org.junit.Assume;
+import org.junit.Test;
 
 import jdk.vm.ci.code.InstalledCode;
+import jdk.vm.ci.meta.ProfilingInfo;
 import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.meta.TriState;
 
 public class ExplicitExceptionTest extends GraalCompilerTest {
 
     private int expectedForeignCallCount;
 
+    /**
+     * Determines if profiling info for {@code method} indicates an exception was thrown somewhere
+     * in the method. In the case of the {@code -Xcomp} VM option, interpreter execution can be
+     * skipped altogether and other execution engines (e.g., C1) may not record seen exceptions in a
+     * method profile.
+     */
+    private static boolean exceptionWasSeen(ResolvedJavaMethod method) {
+        ProfilingInfo profilingInfo = method.getProfilingInfo();
+        if (profilingInfo != null) {
+            for (int i = 0; i < profilingInfo.getCodeSize(); i++) {
+                if (profilingInfo.getExceptionSeen(i) == TriState.TRUE) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
     @Override
     protected InstalledCode getCode(ResolvedJavaMethod method, StructuredGraph graph, boolean forceCompile, boolean installAsDefault, OptionValues options) {
         InstalledCode installedCode = super.getCode(method, graph, forceCompile, installAsDefault, options);
+        Assume.assumeTrue(exceptionWasSeen(method));
         assertDeepEquals(expectedForeignCallCount, lastCompiledGraph.getNodes().filter(ForeignCallNode.class).count());
         return installedCode;
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/GraalOSRLockTest.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/GraalOSRLockTest.java	Wed Nov 08 16:03:35 2017 -0500
@@ -24,11 +24,13 @@
 
 import java.lang.management.ManagementFactory;
 import java.lang.management.MonitorInfo;
+import java.lang.management.RuntimeMXBean;
 import java.lang.management.ThreadInfo;
 import java.lang.management.ThreadMXBean;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.List;
 
 import org.graalvm.compiler.api.directives.GraalDirectives;
 import org.graalvm.compiler.core.phases.HighTier;
@@ -44,6 +46,7 @@
 
 import jdk.vm.ci.meta.ResolvedJavaMethod;
 import org.junit.Assume;
+import org.junit.BeforeClass;
 
 /**
  * Test on-stack-replacement with locks.
@@ -51,13 +54,28 @@
 public class GraalOSRLockTest extends GraalOSRTestBase {
 
     private static boolean TestInSeparateThread = false;
+    private static final String COMPILE_ONLY_FLAG = "-Xcomp";
 
-    public GraalOSRLockTest() {
+    @BeforeClass
+    public static void checkVMArguments() {
         try {
             Class.forName("java.lang.management.ManagementFactory");
         } catch (ClassNotFoundException ex) {
             Assume.assumeNoException("cannot check for monitors without java.management JDK9 module", ex);
         }
+        /*
+         * Note: The -Xcomp execution mode of the VM will stop most of the OSR test cases from
+         * working as every method is compiled at level3 (followed by level4 on the second
+         * invocation). The tests in this class are written in a way that they expect a method to be
+         * executed at the invocation BCI with the interpreter and then perform an OSR to an
+         * installed nmethod at a given BCI.
+         *
+         */
+        RuntimeMXBean runtimeMxBean = ManagementFactory.getRuntimeMXBean();
+        List<String> arguments = runtimeMxBean.getInputArguments();
+        for (String arg : arguments) {
+            Assume.assumeFalse(arg.equals(COMPILE_ONLY_FLAG));
+        }
     }
 
     // testing only
@@ -438,7 +456,7 @@
             }
             GraalDirectives.controlFlowAnchor();
             if (!GraalDirectives.inCompiledCode()) {
-                throw new Error("Must part of compiled code");
+                throw new Error("Must be part of compiled code");
             }
             return ret;
         }
@@ -449,11 +467,11 @@
         ReturnValue ret = ReturnValue.FAILURE;
         synchronized (lock) {
             synchronized (lock1) {
-                for (int i = 1; i < limit; i++) {
+                for (int i = 1; i < 10 * limit; i++) {
                     GraalDirectives.blackhole(i);
-                    if (i % 1001 == 0) {
+                    if (i % 33 == 0) {
                         ret = ReturnValue.SUCCESS;
-                        if (GraalDirectives.inCompiledCode() && i + 33 > (limit)) {
+                        if (GraalDirectives.inCompiledCode() && i + 33 > (10 * limit)) {
                             GraalDirectives.blackhole(ret);
                             System.gc();
                         }
@@ -462,7 +480,7 @@
             }
             GraalDirectives.controlFlowAnchor();
             if (!GraalDirectives.inCompiledCode()) {
-                throw new Error("Must part of compiled code");
+                throw new Error("Must be part of compiled code already hereeeeee");
             } else {
                 // lock 1 must be free
                 if (isMonitorLockHeld(lock1)) {
@@ -519,7 +537,7 @@
             }
             GraalDirectives.controlFlowAnchor();
             if (!GraalDirectives.inCompiledCode()) {
-                throw new Error("Must part of compiled code");
+                throw new Error("Must be part of compiled code");
             }
             return ret;
         }
@@ -543,7 +561,7 @@
             }
             GraalDirectives.controlFlowAnchor();
             if (!GraalDirectives.inCompiledCode()) {
-                throw new Error("Must part of compiled code");
+                throw new Error("Must be part of compiled code");
             }
             return ret;
         }
@@ -568,7 +586,7 @@
             }
             GraalDirectives.controlFlowAnchor();
             if (!GraalDirectives.inCompiledCode()) {
-                throw new Error("Must part of compiled code");
+                throw new Error("Must be part of compiled code");
             }
             return ret;
         }
@@ -646,7 +664,7 @@
         synchronized (monitor) {
             GraalDirectives.controlFlowAnchor();
             if (!GraalDirectives.inCompiledCode()) {
-                throw new Error("Must part of compiled code");
+                throw new Error("Must be part of compiled code");
             }
         }
         return ret;
@@ -670,7 +688,7 @@
             }
             GraalDirectives.controlFlowAnchor();
             if (!GraalDirectives.inCompiledCode()) {
-                throw new Error("Must part of compiled code");
+                throw new Error("Must be part of compiled code");
             }
             return ret;
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/GraalOSRTestBase.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/GraalOSRTestBase.java	Wed Nov 08 16:03:35 2017 -0500
@@ -35,7 +35,9 @@
 import org.graalvm.compiler.debug.GraalError;
 import org.graalvm.compiler.debug.TTY;
 import org.graalvm.compiler.hotspot.CompilationTask;
+import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
 import org.graalvm.compiler.hotspot.HotSpotGraalCompiler;
+import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider;
 import org.graalvm.compiler.java.BciBlockMapping;
 import org.graalvm.compiler.java.BciBlockMapping.BciBlock;
 import org.graalvm.compiler.nodes.StructuredGraph;
@@ -76,6 +78,13 @@
         HotSpotCompilationRequest request = new HotSpotCompilationRequest((HotSpotResolvedJavaMethod) method, bci, jvmciEnv);
         HotSpotGraalCompiler compiler = (HotSpotGraalCompiler) runtime.getCompiler();
         CompilationTask task = new CompilationTask(runtime, compiler, request, true, true, debug.getOptions());
+        if (method instanceof HotSpotResolvedJavaMethod) {
+            HotSpotGraalRuntimeProvider graalRuntime = compiler.getGraalRuntime();
+            GraalHotSpotVMConfig config = graalRuntime.getVMConfig();
+            if (((HotSpotResolvedJavaMethod) method).hasCodeAtLevel(bci, config.compilationLevelFullOptimization)) {
+                return;
+            }
+        }
         HotSpotCompilationRequestResult result = task.runCompilation(debug);
         if (result.getFailure() != null) {
             throw new GraalError(result.getFailureMessage());
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/WriteBarrierVerificationTest.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/WriteBarrierVerificationTest.java	Wed Nov 08 16:03:35 2017 -0500
@@ -37,7 +37,6 @@
 import org.graalvm.compiler.hotspot.nodes.SerialWriteBarrier;
 import org.graalvm.compiler.hotspot.phases.WriteBarrierAdditionPhase;
 import org.graalvm.compiler.hotspot.phases.WriteBarrierVerificationPhase;
-import org.graalvm.compiler.hotspot.replacements.arraycopy.UnsafeArrayCopyNode;
 import org.graalvm.compiler.nodes.AbstractBeginNode;
 import org.graalvm.compiler.nodes.AbstractMergeNode;
 import org.graalvm.compiler.nodes.FieldLocationIdentity;
@@ -629,12 +628,6 @@
         System.arraycopy(a, 0, b, 0, a.length);
     }
 
-    @Test
-    public void test61() {
-        GraphPredicate checkForUnsafeArrayCopy = graph -> graph.getNodes().filter(UnsafeArrayCopyNode.class).count() > 0 ? 1 : 0;
-        testPredicate("test13Snippet", checkForUnsafeArrayCopy, new int[]{});
-    }
-
     private interface GraphPredicate {
         int apply(StructuredGraph graph);
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfig.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfig.java	Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -280,14 +280,19 @@
         }
         if (offset == -1) {
             try {
-                offset = getFieldOffset(name, Integer.class, "OopHandle");
+                offset = getFieldOffset(name, Integer.class, "jobject");
                 isHandle = true;
             } catch (JVMCIError e) {
-
+                try {
+                    // JDK-8186777
+                    offset = getFieldOffset(name, Integer.class, "OopHandle");
+                    isHandle = true;
+                } catch (JVMCIError e2) {
+                }
             }
         }
         if (offset == -1) {
-            throw new JVMCIError("cannot get offset of field " + name + " with type oop or OopHandle");
+            throw new JVMCIError("cannot get offset of field " + name + " with type oop, jobject or OopHandle");
         }
         classMirrorOffset = offset;
         classMirrorIsHandle = isHandle;
@@ -648,6 +653,8 @@
     public final long heapEndAddress = getFieldValue("CompilerToVM::Data::_heap_end_addr", Long.class, "HeapWord**");
     public final long heapTopAddress = getFieldValue("CompilerToVM::Data::_heap_top_addr", Long.class, isJDK8 ? "HeapWord**" : "HeapWord* volatile*");
 
+    public final boolean cmsIncrementalMode = getFlag("CMSIncrementalMode", Boolean.class, false);
+
     public final long inlineCacheMissStub = getFieldValue("CompilerToVM::Data::SharedRuntime_ic_miss_stub", Long.class, "address");
     public final long handleWrongMethodStub = getFieldValue("CompilerToVM::Data::SharedRuntime_handle_wrong_method_stub", Long.class, "address");
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotBackend.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotBackend.java	Wed Nov 08 16:03:35 2017 -0500
@@ -266,6 +266,8 @@
         unsafeArraycopyStub(HotSpotBackend.UNSAFE_ARRAYCOPY, srcAddr, dstAddr, size);
     }
 
+    public static final ForeignCallDescriptor GENERIC_ARRAYCOPY = new ForeignCallDescriptor("generic_arraycopy", int.class, Word.class, int.class, Word.class, int.class, int.class);
+
     @NodeIntrinsic(ForeignCallNode.class)
     private static native void unsafeArraycopyStub(@ConstantNodeParameter ForeignCallDescriptor descriptor, Word srcAddr, Word dstAddr, Word size);
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompiler.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompiler.java	Wed Nov 08 16:03:35 2017 -0500
@@ -284,7 +284,7 @@
 
     public Object mbean() {
         if (graalRuntime instanceof HotSpotGraalRuntime) {
-            return ((HotSpotGraalRuntime)graalRuntime).mbean();
+            return ((HotSpotGraalRuntime) graalRuntime).getMBean();
         }
         return null;
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompilerFactory.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompilerFactory.java	Wed Nov 08 16:03:35 2017 -0500
@@ -26,6 +26,8 @@
 import static org.graalvm.compiler.hotspot.HotSpotGraalOptionValues.GRAAL_OPTION_PROPERTY_PREFIX;
 
 import java.io.PrintStream;
+import java.util.Map;
+import java.util.Collections;
 
 import org.graalvm.compiler.debug.MethodFilter;
 import org.graalvm.compiler.options.Option;
@@ -190,4 +192,11 @@
         }
         return level;
     }
+
+    public Map<String, Object> mbeans() {
+        HotSpotGraalCompiler compiler = createCompiler(HotSpotJVMCIRuntime.runtime());
+        String name = "org.graalvm.compiler.hotspot:type=Options";
+        Object bean = ((HotSpotGraalRuntime) compiler.getGraalRuntime()).getMBean();
+        return Collections.singletonMap(name, bean);
+    }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalMBean.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalMBean.java	Wed Nov 08 16:03:35 2017 -0500
@@ -283,10 +283,8 @@
     @Override
     public javax.management.MBeanInfo getMBeanInfo() {
         List<javax.management.MBeanAttributeInfo> attrs = new ArrayList<>();
-        if (registered != null) {
-            for (OptionDescriptor descr : allOptionDescriptors()) {
-                attrs.add(new javax.management.MBeanAttributeInfo(descr.getName(), descr.getType().getName(), descr.getHelp(), true, true, false));
-            }
+        for (OptionDescriptor descr : allOptionDescriptors()) {
+            attrs.add(new javax.management.MBeanAttributeInfo(descr.getName(), descr.getType().getName(), descr.getHelp(), true, true, false));
         }
         javax.management.MBeanOperationInfo[] ops = {
                         new javax.management.MBeanOperationInfo("dumpMethod", "Enable IGV dumps for provided method", new javax.management.MBeanParameterInfo[]{
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntime.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntime.java	Wed Nov 08 16:03:35 2017 -0500
@@ -317,7 +317,7 @@
         return compilationProblemsPerAction;
     }
 
-    final Object mbean() {
+    Object getMBean() {
         return mBean;
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/DefaultHotSpotLoweringProvider.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/DefaultHotSpotLoweringProvider.java	Wed Nov 08 16:03:35 2017 -0500
@@ -28,8 +28,8 @@
 import static org.graalvm.compiler.core.common.GraalOptions.OmitHotExceptionStacktrace;
 import static org.graalvm.compiler.hotspot.meta.HotSpotForeignCallsProviderImpl.OSR_MIGRATION_END;
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.CLASS_KLASS_LOCATION;
+import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.CLASS_MIRROR_HANDLE_LOCATION;
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.CLASS_MIRROR_LOCATION;
-import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.CLASS_MIRROR_HANDLE_LOCATION;
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.COMPRESSED_HUB_LOCATION;
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.DISPLACED_MARK_WORD_LOCATION;
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.HUB_LOCATION;
@@ -41,6 +41,7 @@
 import java.lang.ref.Reference;
 
 import org.graalvm.compiler.api.directives.GraalDirectives;
+import org.graalvm.compiler.core.common.CompressEncoding;
 import org.graalvm.compiler.core.common.GraalOptions;
 import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
 import org.graalvm.compiler.core.common.spi.ForeignCallsProvider;
@@ -90,10 +91,8 @@
 import org.graalvm.compiler.hotspot.replacements.WriteBarrierSnippets;
 import org.graalvm.compiler.hotspot.replacements.aot.ResolveConstantSnippets;
 import org.graalvm.compiler.hotspot.replacements.arraycopy.ArrayCopyNode;
-import org.graalvm.compiler.hotspot.replacements.arraycopy.ArrayCopySlowPathNode;
+import org.graalvm.compiler.hotspot.replacements.arraycopy.ArrayCopyWithSlowPathNode;
 import org.graalvm.compiler.hotspot.replacements.arraycopy.ArrayCopySnippets;
-import org.graalvm.compiler.hotspot.replacements.arraycopy.ArrayCopyUnrollNode;
-import org.graalvm.compiler.hotspot.replacements.arraycopy.UnsafeArrayCopySnippets;
 import org.graalvm.compiler.hotspot.replacements.profiling.ProfileSnippets;
 import org.graalvm.compiler.hotspot.word.KlassPointer;
 import org.graalvm.compiler.nodes.AbstractBeginNode;
@@ -193,7 +192,7 @@
 
     public DefaultHotSpotLoweringProvider(HotSpotGraalRuntimeProvider runtime, MetaAccessProvider metaAccess, ForeignCallsProvider foreignCalls, HotSpotRegistersProvider registers,
                     HotSpotConstantReflectionProvider constantReflection, TargetDescription target) {
-        super(metaAccess, foreignCalls, target);
+        super(metaAccess, foreignCalls, target, runtime.getVMConfig().useCompressedOops);
         this.runtime = runtime;
         this.registers = registers;
         this.constantReflection = constantReflection;
@@ -216,7 +215,6 @@
         hashCodeSnippets = new HashCodeSnippets.Templates(options, factories, providers, target);
         resolveConstantSnippets = new ResolveConstantSnippets.Templates(options, factories, providers, target);
         profileSnippets = new ProfileSnippets.Templates(options, factories, providers, target);
-        providers.getReplacements().registerSnippetTemplateCache(new UnsafeArrayCopySnippets.Templates(options, factories, providers, target));
     }
 
     public MonitorSnippets.Templates getMonitorSnippets() {
@@ -315,10 +313,8 @@
             }
         } else if (n instanceof ArrayCopyNode) {
             arraycopySnippets.lower((ArrayCopyNode) n, tool);
-        } else if (n instanceof ArrayCopySlowPathNode) {
-            arraycopySnippets.lower((ArrayCopySlowPathNode) n, tool);
-        } else if (n instanceof ArrayCopyUnrollNode) {
-            arraycopySnippets.lower((ArrayCopyUnrollNode) n, tool);
+        } else if (n instanceof ArrayCopyWithSlowPathNode) {
+            arraycopySnippets.lower((ArrayCopyWithSlowPathNode) n, tool);
         } else if (n instanceof G1PreWriteBarrier) {
             writeBarrierSnippets.lower((G1PreWriteBarrier) n, registers, tool);
         } else if (n instanceof G1PostWriteBarrier) {
@@ -495,20 +491,18 @@
         }
     }
 
-    @Override
-    protected Stamp loadStamp(Stamp stamp, JavaKind kind, boolean compressible) {
-        if (kind == JavaKind.Object && compressible && runtime.getVMConfig().useCompressedOops) {
-            return HotSpotNarrowOopStamp.compressed((ObjectStamp) stamp, runtime.getVMConfig().getOopEncoding());
-        }
-        return super.loadStamp(stamp, kind, compressible);
+    private CompressEncoding getOopEncoding() {
+        return runtime.getVMConfig().getOopEncoding();
     }
 
     @Override
-    protected ValueNode implicitLoadConvert(JavaKind kind, ValueNode value, boolean compressible) {
-        if (kind == JavaKind.Object && compressible && runtime.getVMConfig().useCompressedOops) {
-            return new HotSpotCompressionNode(CompressionOp.Uncompress, value, runtime.getVMConfig().getOopEncoding());
-        }
-        return super.implicitLoadConvert(kind, value, compressible);
+    protected Stamp loadCompressedStamp(ObjectStamp stamp) {
+        return HotSpotNarrowOopStamp.compressed(stamp, getOopEncoding());
+    }
+
+    @Override
+    protected ValueNode newCompressionNode(CompressionOp op, ValueNode value) {
+        return new HotSpotCompressionNode(op, value, getOopEncoding());
     }
 
     @Override
@@ -519,14 +513,6 @@
     }
 
     @Override
-    protected ValueNode implicitStoreConvert(JavaKind kind, ValueNode value, boolean compressible) {
-        if (kind == JavaKind.Object && compressible && runtime.getVMConfig().useCompressedOops) {
-            return new HotSpotCompressionNode(CompressionOp.Compress, value, runtime.getVMConfig().getOopEncoding());
-        }
-        return super.implicitStoreConvert(kind, value, compressible);
-    }
-
-    @Override
     protected ValueNode createReadArrayComponentHub(StructuredGraph graph, ValueNode arrayHub, FixedNode anchor) {
         /*
          * Anchor the read of the element klass to the cfg, because it is only valid when arrayClass
@@ -800,4 +786,9 @@
     public int arrayLengthOffset() {
         return runtime.getVMConfig().arrayOopDescLengthOffset();
     }
+
+    @Override
+    protected final JavaKind getStorageKind(ResolvedJavaField field) {
+        return field.getJavaKind();
+    }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java	Wed Nov 08 16:03:35 2017 -0500
@@ -39,6 +39,7 @@
 import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
 import org.graalvm.compiler.bytecode.BytecodeProvider;
 import org.graalvm.compiler.core.common.spi.ForeignCallsProvider;
+import org.graalvm.compiler.core.common.type.StampFactory;
 import org.graalvm.compiler.debug.GraalError;
 import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
 import org.graalvm.compiler.hotspot.nodes.CurrentJavaThreadNode;
@@ -68,6 +69,7 @@
 import org.graalvm.compiler.nodes.PiNode;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.AddNode;
+import org.graalvm.compiler.nodes.calc.IntegerConvertNode;
 import org.graalvm.compiler.nodes.calc.LeftShiftNode;
 import org.graalvm.compiler.nodes.graphbuilderconf.ForeignCallPlugin;
 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins;
@@ -316,8 +318,8 @@
     private static boolean readMetaspaceConstantPoolElement(GraphBuilderContext b, ValueNode constantPoolOop, ValueNode index, JavaKind elementKind, WordTypes wordTypes, GraalHotSpotVMConfig config) {
         ValueNode constants = getMetaspaceConstantPool(b, constantPoolOop, wordTypes, config);
         int shift = CodeUtil.log2(wordTypes.getWordKind().getByteCount());
-        ValueNode scaledIndex = b.add(new LeftShiftNode(index, b.add(ConstantNode.forInt(shift))));
-        ValueNode offset = b.add(new AddNode(scaledIndex, b.add(ConstantNode.forInt(config.constantPoolSize))));
+        ValueNode scaledIndex = b.add(new LeftShiftNode(IntegerConvertNode.convert(index, StampFactory.forKind(JavaKind.Long)), b.add(ConstantNode.forInt(shift))));
+        ValueNode offset = b.add(new AddNode(scaledIndex, b.add(ConstantNode.forLong(config.constantPoolSize))));
         AddressNode elementAddress = b.add(new OffsetAddressNode(constants, offset));
         boolean notCompressible = false;
         ValueNode elementValue = WordOperationPlugin.readOp(b, elementKind, elementAddress, NamedLocationIdentity.getArrayLocation(elementKind), BarrierType.NONE, notCompressible);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotHostForeignCallsProvider.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotHostForeignCallsProvider.java	Wed Nov 08 16:03:35 2017 -0500
@@ -34,6 +34,7 @@
 import static org.graalvm.compiler.hotspot.HotSpotBackend.ENCRYPT;
 import static org.graalvm.compiler.hotspot.HotSpotBackend.ENCRYPT_BLOCK;
 import static org.graalvm.compiler.hotspot.HotSpotBackend.EXCEPTION_HANDLER;
+import static org.graalvm.compiler.hotspot.HotSpotBackend.GENERIC_ARRAYCOPY;
 import static org.graalvm.compiler.hotspot.HotSpotBackend.IC_MISS_HANDLER;
 import static org.graalvm.compiler.hotspot.HotSpotBackend.INITIALIZE_KLASS_BY_SYMBOL;
 import static org.graalvm.compiler.hotspot.HotSpotBackend.INVOCATION_EVENT;
@@ -85,7 +86,6 @@
 import static org.graalvm.compiler.hotspot.stubs.NewInstanceStub.NEW_INSTANCE_C;
 import static org.graalvm.compiler.hotspot.stubs.StubUtil.VM_MESSAGE_C;
 import static org.graalvm.compiler.hotspot.stubs.UnwindExceptionToCallerStub.EXCEPTION_HANDLER_FOR_RETURN_ADDRESS;
-import static org.graalvm.compiler.nodes.NamedLocationIdentity.any;
 import static org.graalvm.compiler.nodes.java.ForeignCallDescriptors.REGISTER_FINALIZER;
 import static org.graalvm.compiler.replacements.Log.LOG_OBJECT;
 import static org.graalvm.compiler.replacements.Log.LOG_PRIMITIVE;
@@ -97,6 +97,7 @@
 import static org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.LOG10;
 import static org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.SIN;
 import static org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.TAN;
+import static org.graalvm.word.LocationIdentity.any;
 
 import java.util.EnumMap;
 
@@ -213,7 +214,7 @@
         // c_rarg4 - oop ckval (super_klass)
         // return: 0 = success, n = number of copied elements xor'd with -1.
         ForeignCallDescriptor desc = new ForeignCallDescriptor(name, int.class, Word.class, Word.class, Word.class, Word.class, Word.class);
-        LocationIdentity killed = NamedLocationIdentity.getArrayLocation(JavaKind.Object);
+        LocationIdentity killed = NamedLocationIdentity.any();
         registerForeignCall(desc, routine, NativeCall, DESTROYS_REGISTERS, LEAF_NOFP, NOT_REEXECUTABLE, killed);
         checkcastArraycopyDescriptors[uninit ? 1 : 0] = desc;
     }
@@ -333,6 +334,7 @@
         registerCheckcastArraycopyDescriptor(true, c.checkcastArraycopyUninit);
         registerCheckcastArraycopyDescriptor(false, c.checkcastArraycopy);
 
+        registerForeignCall(GENERIC_ARRAYCOPY, c.genericArraycopy, NativeCall, DESTROYS_REGISTERS, LEAF_NOFP, NOT_REEXECUTABLE, NamedLocationIdentity.any());
         registerForeignCall(UNSAFE_ARRAYCOPY, c.unsafeArraycopy, NativeCall, DESTROYS_REGISTERS, LEAF_NOFP, NOT_REEXECUTABLE, NamedLocationIdentity.any());
 
         if (c.useMultiplyToLenIntrinsic()) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/ResolveDynamicConstantNode.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/ResolveDynamicConstantNode.java	Wed Nov 08 16:03:35 2017 -0500
@@ -28,6 +28,7 @@
 import org.graalvm.word.LocationIdentity;
 import org.graalvm.compiler.core.common.type.Stamp;
 import org.graalvm.compiler.graph.NodeClass;
+import org.graalvm.compiler.nodeinfo.InputType;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.DeoptimizingFixedWithNextNode;
 import org.graalvm.compiler.nodes.ValueNode;
@@ -35,7 +36,7 @@
 import org.graalvm.compiler.nodes.spi.Lowerable;
 import org.graalvm.compiler.nodes.spi.LoweringTool;
 
-@NodeInfo(cycles = CYCLES_4, size = SIZE_16)
+@NodeInfo(cycles = CYCLES_4, size = SIZE_16, allowedUsageTypes = {InputType.Memory})
 public class ResolveDynamicConstantNode extends DeoptimizingFixedWithNextNode implements Lowerable, MemoryCheckpoint.Single {
     public static final NodeClass<ResolveDynamicConstantNode> TYPE = NodeClass.create(ResolveDynamicConstantNode.class);
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/profiling/ProfileBranchNode.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/profiling/ProfileBranchNode.java	Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -71,6 +71,15 @@
         return branchCondition != null;
     }
 
+    @Override
+    protected boolean canBeMergedWith(ProfileNode p) {
+        if (p instanceof ProfileBranchNode) {
+            ProfileBranchNode that = (ProfileBranchNode) p;
+            return this.method.equals(that.method) && this.bci == that.bci;
+        }
+        return false;
+    }
+
     /**
      * Gathers all the {@link ProfileBranchNode}s that are inputs to the
      * {@linkplain StructuredGraph#getNodes() live nodes} in a given graph.
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/profiling/ProfileInvokeNode.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/profiling/ProfileInvokeNode.java	Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -37,6 +37,15 @@
         super(TYPE, method, freqLog, probabilityLog);
     }
 
+    @Override
+    protected boolean canBeMergedWith(ProfileNode p) {
+        if (p instanceof ProfileInvokeNode) {
+            ProfileInvokeNode that = (ProfileInvokeNode) p;
+            return this.method.equals(that.method);
+        }
+        return false;
+    }
+
     /**
      * Gathers all the {@link ProfileInvokeNode}s that are inputs to the
      * {@linkplain StructuredGraph#getNodes() live nodes} in a given graph.
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/profiling/ProfileNode.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/profiling/ProfileNode.java	Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,11 +24,17 @@
 
 import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_IGNORED;
 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_IGNORED;
+import static org.graalvm.compiler.nodes.util.GraphUtil.removeFixedWithUnusedInputs;
 
 import org.graalvm.compiler.core.common.type.StampFactory;
+import org.graalvm.compiler.graph.Node;
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.graph.iterators.NodeIterable;
+import org.graalvm.compiler.graph.spi.Simplifiable;
+import org.graalvm.compiler.graph.spi.SimplifierTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.AbstractMergeNode;
+import org.graalvm.compiler.nodes.ControlSplitNode;
 import org.graalvm.compiler.nodes.DeoptimizingFixedWithNextNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
@@ -41,7 +47,7 @@
 import jdk.vm.ci.meta.ResolvedJavaMethod;
 
 @NodeInfo(cycles = CYCLES_IGNORED, cyclesRationale = "profiling should be ignored", size = SIZE_IGNORED, sizeRationale = "profiling should be ignored")
-public class ProfileNode extends DeoptimizingFixedWithNextNode implements Lowerable {
+public abstract class ProfileNode extends DeoptimizingFixedWithNextNode implements Simplifiable, Lowerable {
     public static class Options {
         @Option(help = "Control probabilistic profiling on AMD64", type = OptionType.Expert)//
         public static final OptionKey<Boolean> ProbabilisticProfiling = new OptionKey<>(true);
@@ -54,19 +60,21 @@
     // Only used if ProbabilisticProfiling == true and may be ignored by lowerer.
     @OptionalInput protected ValueNode random;
 
-    // logarithm base 2 of the profile probability
+    // Logarithm base 2 of the profile probability.
     protected int probabilityLog;
 
+    // Step value to add to the profile counter.
+    protected int step;
+
     protected ProfileNode(NodeClass<? extends DeoptimizingFixedWithNextNode> c, ResolvedJavaMethod method, int probabilityLog) {
         super(c, StampFactory.forVoid());
         this.method = method;
         this.probabilityLog = probabilityLog;
+        this.step = 1;
     }
 
     public ProfileNode(ResolvedJavaMethod method, int probabilityLog) {
-        super(TYPE, StampFactory.forVoid());
-        this.method = method;
-        this.probabilityLog = probabilityLog;
+        this(TYPE, method, probabilityLog);
     }
 
     @Override
@@ -92,6 +100,14 @@
         this.random = r;
     }
 
+    public int getStep() {
+        return step;
+    }
+
+    public void setStep(int s) {
+        step = s;
+    }
+
     /**
      * Get the logarithm base 2 of the profile probability.
      */
@@ -106,4 +122,25 @@
     public static NodeIterable<ProfileNode> getProfileNodes(StructuredGraph graph) {
         return graph.getNodes().filter(ProfileNode.class);
     }
+
+    protected abstract boolean canBeMergedWith(ProfileNode p);
+
+    @Override
+    public void simplify(SimplifierTool tool) {
+        for (Node p = predecessor(); p != null; p = p.predecessor()) {
+            // Terminate search when we hit a control split or merge.
+            if (p instanceof ControlSplitNode || p instanceof AbstractMergeNode) {
+                break;
+            }
+            if (p instanceof ProfileNode) {
+                ProfileNode that = (ProfileNode) p;
+                if (this.canBeMergedWith(that)) {
+                    that.setStep(this.getStep() + that.getStep());
+                    removeFixedWithUnusedInputs(this);
+                    tool.addToWorkList(that);
+                    break;
+                }
+            }
+        }
+    }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/profiling/ProfileWithNotificationNode.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/profiling/ProfileWithNotificationNode.java	Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,7 +28,7 @@
 import jdk.vm.ci.meta.ResolvedJavaMethod;
 
 @NodeInfo
-public class ProfileWithNotificationNode extends ProfileNode {
+public abstract class ProfileWithNotificationNode extends ProfileNode {
     public static final NodeClass<ProfileWithNotificationNode> TYPE = NodeClass.create(ProfileWithNotificationNode.class);
 
     protected int freqLog;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/OnStackReplacementPhase.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/OnStackReplacementPhase.java	Wed Nov 08 16:03:35 2017 -0500
@@ -22,10 +22,16 @@
  */
 package org.graalvm.compiler.hotspot.phases;
 
+import static jdk.vm.ci.meta.SpeculationLog.SpeculationReason;
 import static org.graalvm.compiler.phases.common.DeadCodeEliminationPhase.Optionality.Required;
 
+import jdk.vm.ci.meta.DeoptimizationAction;
+import jdk.vm.ci.meta.DeoptimizationReason;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.JavaKind;
 import org.graalvm.compiler.core.common.PermanentBailoutException;
 import org.graalvm.compiler.core.common.cfg.Loop;
+import org.graalvm.compiler.core.common.type.ObjectStamp;
 import org.graalvm.compiler.core.common.type.Stamp;
 import org.graalvm.compiler.debug.CounterKey;
 import org.graalvm.compiler.debug.DebugContext;
@@ -37,13 +43,15 @@
 import org.graalvm.compiler.nodeinfo.InputType;
 import org.graalvm.compiler.nodeinfo.Verbosity;
 import org.graalvm.compiler.nodes.AbstractBeginNode;
-import org.graalvm.compiler.nodes.AbstractLocalNode;
 import org.graalvm.compiler.nodes.EntryMarkerNode;
 import org.graalvm.compiler.nodes.EntryProxyNode;
+import org.graalvm.compiler.nodes.FixedGuardNode;
 import org.graalvm.compiler.nodes.FixedNode;
 import org.graalvm.compiler.nodes.FrameState;
+import org.graalvm.compiler.nodes.LogicNode;
 import org.graalvm.compiler.nodes.LoopBeginNode;
 import org.graalvm.compiler.nodes.ParameterNode;
+import org.graalvm.compiler.nodes.PiNode;
 import org.graalvm.compiler.nodes.StartNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
@@ -53,6 +61,7 @@
 import org.graalvm.compiler.nodes.extended.OSRMonitorEnterNode;
 import org.graalvm.compiler.nodes.extended.OSRStartNode;
 import org.graalvm.compiler.nodes.java.AccessMonitorNode;
+import org.graalvm.compiler.nodes.java.InstanceOfNode;
 import org.graalvm.compiler.nodes.java.MonitorEnterNode;
 import org.graalvm.compiler.nodes.java.MonitorExitNode;
 import org.graalvm.compiler.nodes.java.MonitorIdNode;
@@ -172,15 +181,32 @@
             if (value instanceof EntryProxyNode) {
                 EntryProxyNode proxy = (EntryProxyNode) value;
                 /*
-                 * we need to drop the stamp since the types we see during OSR may be too precise
-                 * (if a branch was not parsed for example).
+                 * We need to drop the stamp since the types we see during OSR may be too precise
+                 * (if a branch was not parsed for example). In cases when this is possible, we
+                 * insert a guard and narrow the OSRLocal stamp at its usages.
                  */
-                Stamp s = proxy.stamp().unrestricted();
-                AbstractLocalNode osrLocal = null;
+                Stamp narrowedStamp = proxy.value().stamp();
+                Stamp unrestrictedStamp = proxy.stamp().unrestricted();
+                ValueNode osrLocal;
                 if (i >= localsSize) {
-                    osrLocal = graph.addOrUnique(new OSRLockNode(i - localsSize, s));
+                    osrLocal = graph.addOrUnique(new OSRLockNode(i - localsSize, unrestrictedStamp));
                 } else {
-                    osrLocal = graph.addOrUnique(new OSRLocalNode(i, s));
+                    osrLocal = graph.addOrUnique(new OSRLocalNode(i, unrestrictedStamp));
+                }
+                // Speculate on the OSRLocal stamps that could be more precise.
+                OSRLocalSpeculationReason reason = new OSRLocalSpeculationReason(osrState.bci, narrowedStamp, i);
+                if (graph.getSpeculationLog().maySpeculate(reason) && osrLocal instanceof OSRLocalNode && value.getStackKind().equals(JavaKind.Object) && !narrowedStamp.isUnrestricted()) {
+                    // Add guard.
+                    LogicNode check = graph.addOrUniqueWithInputs(InstanceOfNode.createHelper((ObjectStamp) narrowedStamp, osrLocal, null, null));
+                    JavaConstant constant = graph.getSpeculationLog().speculate(reason);
+                    FixedGuardNode guard = graph.add(new FixedGuardNode(check, DeoptimizationReason.OptimizedTypeCheckViolated, DeoptimizationAction.InvalidateRecompile, constant, false));
+                    graph.addAfterFixed(osrStart, guard);
+
+                    // Replace with a more specific type at usages.
+                    // We know that we are at the root,
+                    // so we need to replace the proxy in the state.
+                    proxy.replaceAtMatchingUsages(osrLocal, n -> n == osrState);
+                    osrLocal = graph.addOrUnique(new PiNode(osrLocal, narrowedStamp, guard));
                 }
                 proxy.replaceAndDelete(osrLocal);
             } else {
@@ -268,4 +294,30 @@
     public float codeSizeIncrease() {
         return 5.0f;
     }
+
+    private static class OSRLocalSpeculationReason implements SpeculationReason {
+        private int bci;
+        private Stamp speculatedStamp;
+        private int localIndex;
+
+        OSRLocalSpeculationReason(int bci, Stamp speculatedStamp, int localIndex) {
+            this.bci = bci;
+            this.speculatedStamp = speculatedStamp;
+            this.localIndex = localIndex;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj instanceof OSRLocalSpeculationReason) {
+                OSRLocalSpeculationReason that = (OSRLocalSpeculationReason) obj;
+                return this.bci == that.bci && this.speculatedStamp.equals(that.speculatedStamp) && this.localIndex == that.localIndex;
+            }
+            return false;
+        }
+
+        @Override
+        public int hashCode() {
+            return (bci << 16) ^ speculatedStamp.hashCode() ^ localIndex;
+        }
+    }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/HotSpotReplacementsUtil.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/HotSpotReplacementsUtil.java	Wed Nov 08 16:03:35 2017 -0500
@@ -670,6 +670,11 @@
     }
 
     @Fold
+    public static boolean useCMSIncrementalMode(@InjectedParameter GraalHotSpotVMConfig config) {
+        return config.cmsIncrementalMode;
+    }
+
+    @Fold
     public static boolean useCompressedOops(@InjectedParameter GraalHotSpotVMConfig config) {
         return config.useCompressedOops;
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/HubGetClassNode.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/HubGetClassNode.java	Wed Nov 08 16:03:35 2017 -0500
@@ -71,7 +71,7 @@
             return null;
         } else {
             MetaAccessProvider metaAccess = tool.getMetaAccess();
-            if (metaAccess != null && hub.isConstant() && !GraalOptions.ImmutableCode.getValue(graph().getOptions())) {
+            if (metaAccess != null && hub.isConstant() && !GraalOptions.ImmutableCode.getValue(tool.getOptions())) {
                 ResolvedJavaType exactType = tool.getConstantReflection().asJavaType(hub.asConstant());
                 if (exactType != null) {
                     return ConstantNode.forConstant(tool.getConstantReflection().asJavaClass(exactType), metaAccess);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/IdentityHashCodeNode.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/IdentityHashCodeNode.java	Wed Nov 08 16:03:35 2017 -0500
@@ -67,7 +67,7 @@
         if (object.isConstant()) {
             assert object.stamp() instanceof AbstractObjectStamp;
             JavaConstant c = (JavaConstant) object.asConstant();
-            if (ImmutableCode.getValue(getOptions())) {
+            if (ImmutableCode.getValue(tool.getOptions())) {
                 return this;
             }
             JavaConstant identityHashCode = null;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/ArrayCopySlowPathNode.java	Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,97 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package org.graalvm.compiler.hotspot.replacements.arraycopy;
-
-import jdk.vm.ci.code.BytecodeFrame;
-import jdk.vm.ci.meta.JavaKind;
-
-import static org.graalvm.word.LocationIdentity.any;
-
-import org.graalvm.compiler.graph.NodeClass;
-import org.graalvm.compiler.hotspot.word.KlassPointer;
-import org.graalvm.compiler.nodeinfo.InputType;
-import org.graalvm.compiler.nodeinfo.NodeInfo;
-import org.graalvm.compiler.nodes.NamedLocationIdentity;
-import org.graalvm.compiler.nodes.ValueNode;
-import org.graalvm.compiler.nodes.type.StampTool;
-import org.graalvm.compiler.replacements.SnippetTemplate;
-import org.graalvm.compiler.replacements.nodes.BasicArrayCopyNode;
-import org.graalvm.word.LocationIdentity;
-
-@NodeInfo(allowedUsageTypes = InputType.Memory)
-public final class ArrayCopySlowPathNode extends BasicArrayCopyNode {
-
-    public static final NodeClass<ArrayCopySlowPathNode> TYPE = NodeClass.create(ArrayCopySlowPathNode.class);
-
-    private final SnippetTemplate.SnippetInfo snippet;
-
-    /**
-     * Extra context for the slow path snippet.
-     */
-    private final Object argument;
-
-    /**
-     * AOT compilation requires klass constants to be exposed after the first lowering to be handled
-     * automatically. Lowering for {@link ArrayCopySlowPathNode}, with snippet ==
-     * {@link ArrayCopySnippets#arraycopyPredictedObjectWork}, requires a klass of Object[]. For
-     * other snippets {@link #predictedKlass} is a null constant.
-     */
-    @Input protected ValueNode predictedKlass;
-
-    public ArrayCopySlowPathNode(ValueNode src, ValueNode srcPos, ValueNode dest, ValueNode destPos, ValueNode length, ValueNode predictedKlass, JavaKind elementKind,
-                    SnippetTemplate.SnippetInfo snippet, Object argument) {
-        super(TYPE, src, srcPos, dest, destPos, length, elementKind, BytecodeFrame.INVALID_FRAMESTATE_BCI);
-        assert StampTool.isPointerNonNull(src) && StampTool.isPointerNonNull(dest) : "must have been null checked";
-        this.snippet = snippet;
-        this.argument = argument;
-        this.predictedKlass = predictedKlass;
-    }
-
-    @NodeIntrinsic
-    public static native void arraycopy(Object nonNullSrc, int srcPos, Object nonNullDest, int destPos, int length, KlassPointer predictedKlass,
-                    @ConstantNodeParameter JavaKind elementKind, @ConstantNodeParameter SnippetTemplate.SnippetInfo snippet, @ConstantNodeParameter Object argument);
-
-    public SnippetTemplate.SnippetInfo getSnippet() {
-        return snippet;
-    }
-
-    public Object getArgument() {
-        return argument;
-    }
-
-    @Override
-    public LocationIdentity getLocationIdentity() {
-        if (elementKind != null) {
-            return NamedLocationIdentity.getArrayLocation(elementKind);
-        }
-        return any();
-    }
-
-    public void setBci(int bci) {
-        this.bci = bci;
-    }
-
-    public ValueNode getPredictedKlass() {
-        return predictedKlass;
-    }
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/ArrayCopySnippets.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/ArrayCopySnippets.java	Wed Nov 08 16:03:35 2017 -0500
@@ -28,11 +28,12 @@
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.arrayBaseOffset;
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.arrayClassElementOffset;
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.arrayIndexScale;
-import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.layoutHelperElementTypePrimitiveInPlace;
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.loadHub;
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.readLayoutHelper;
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.superCheckOffsetOffset;
-import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.FAST_PATH_PROBABILITY;
+import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.FREQUENT_PROBABILITY;
+import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.LIKELY_PROBABILITY;
+import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.NOT_FREQUENT_PROBABILITY;
 import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.SLOW_PATH_PROBABILITY;
 import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.probability;
 
@@ -47,10 +48,8 @@
 import org.graalvm.compiler.debug.GraalError;
 import org.graalvm.compiler.graph.Node;
 import org.graalvm.compiler.hotspot.meta.HotSpotProviders;
-import org.graalvm.compiler.hotspot.nodes.type.KlassPointerStamp;
 import org.graalvm.compiler.hotspot.word.KlassPointer;
 import org.graalvm.compiler.nodes.CallTargetNode;
-import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.nodes.DeoptimizeNode;
 import org.graalvm.compiler.nodes.Invoke;
 import org.graalvm.compiler.nodes.InvokeNode;
@@ -65,8 +64,10 @@
 import org.graalvm.compiler.nodes.type.StampTool;
 import org.graalvm.compiler.nodes.util.GraphUtil;
 import org.graalvm.compiler.options.OptionValues;
+import org.graalvm.compiler.replacements.ReplacementsUtil;
 import org.graalvm.compiler.replacements.SnippetCounter;
 import org.graalvm.compiler.replacements.SnippetCounter.Group;
+import org.graalvm.compiler.replacements.SnippetIntegerHistogram;
 import org.graalvm.compiler.replacements.SnippetTemplate;
 import org.graalvm.compiler.replacements.SnippetTemplate.Arguments;
 import org.graalvm.compiler.replacements.SnippetTemplate.SnippetInfo;
@@ -79,16 +80,208 @@
 import org.graalvm.word.WordFactory;
 
 import jdk.vm.ci.code.TargetDescription;
-import jdk.vm.ci.hotspot.HotSpotResolvedObjectType;
 import jdk.vm.ci.meta.DeoptimizationAction;
 import jdk.vm.ci.meta.DeoptimizationReason;
-import jdk.vm.ci.meta.JavaConstant;
 import jdk.vm.ci.meta.JavaKind;
 import jdk.vm.ci.meta.ResolvedJavaMethod;
 import jdk.vm.ci.meta.ResolvedJavaType;
 
 public class ArrayCopySnippets implements Snippets {
 
+    private enum ArrayCopyTypeCheck {
+        UNDEFINED_ARRAY_TYPE_CHECK,
+        // we know that both objects are arrays and have the same type
+        NO_ARRAY_TYPE_CHECK,
+        // can be used when we know that one of the objects is a primitive array
+        HUB_BASED_ARRAY_TYPE_CHECK,
+        // must be used when we don't have sufficient information to use one of the others
+        LAYOUT_HELPER_BASED_ARRAY_TYPE_CHECK
+    }
+
+    @Snippet
+    public static void arraycopyZeroLengthSnippet(Object src, int srcPos, Object dest, int destPos, int length, @ConstantParameter ArrayCopyTypeCheck arrayTypeCheck,
+                    @ConstantParameter Counters counters) {
+        Object nonNullSrc = GraalDirectives.guardingNonNull(src);
+        Object nonNullDest = GraalDirectives.guardingNonNull(dest);
+        checkArrayTypes(nonNullSrc, nonNullDest, arrayTypeCheck);
+        checkLimits(nonNullSrc, srcPos, nonNullDest, destPos, length, counters);
+        counters.zeroLengthStaticCounter.inc();
+    }
+
+    @Snippet
+    public static void arraycopyExactSnippet(Object src, int srcPos, Object dest, int destPos, int length, @ConstantParameter ArrayCopyTypeCheck arrayTypeCheck,
+                    @ConstantParameter JavaKind elementKind, @ConstantParameter SnippetCounter elementKindCounter, @ConstantParameter SnippetCounter elementKindCopiedCounter,
+                    @ConstantParameter Counters counters) {
+        Object nonNullSrc = GraalDirectives.guardingNonNull(src);
+        Object nonNullDest = GraalDirectives.guardingNonNull(dest);
+        checkArrayTypes(nonNullSrc, nonNullDest, arrayTypeCheck);
+        checkLimits(nonNullSrc, srcPos, nonNullDest, destPos, length, counters);
+        incrementLengthCounter(length, counters);
+
+        elementKindCounter.inc();
+        elementKindCopiedCounter.add(length);
+        ArrayCopyCallNode.arraycopy(nonNullSrc, srcPos, nonNullDest, destPos, length, elementKind);
+    }
+
+    @Snippet
+    public static void arraycopyUnrolledSnippet(Object src, int srcPos, Object dest, int destPos, int length, @ConstantParameter ArrayCopyTypeCheck arrayTypeCheck,
+                    @ConstantParameter JavaKind elementKind, @ConstantParameter int unrolledLength, @ConstantParameter Counters counters) {
+        Object nonNullSrc = GraalDirectives.guardingNonNull(src);
+        Object nonNullDest = GraalDirectives.guardingNonNull(dest);
+        checkArrayTypes(nonNullSrc, nonNullDest, arrayTypeCheck);
+        checkLimits(nonNullSrc, srcPos, nonNullDest, destPos, length, counters);
+        incrementLengthCounter(length, counters);
+
+        unrolledArraycopyWork(nonNullSrc, srcPos, nonNullDest, destPos, unrolledLength, elementKind);
+    }
+
+    @Snippet
+    public static void arraycopyCheckcastSnippet(Object src, int srcPos, Object dest, int destPos, int length, @ConstantParameter ArrayCopyTypeCheck arrayTypeCheck,
+                    @ConstantParameter Counters counters, @ConstantParameter SnippetInfo workSnippet, @ConstantParameter JavaKind elementKind) {
+        Object nonNullSrc = GraalDirectives.guardingNonNull(src);
+        Object nonNullDest = GraalDirectives.guardingNonNull(dest);
+        checkArrayTypes(nonNullSrc, nonNullDest, arrayTypeCheck);
+        checkLimits(nonNullSrc, srcPos, nonNullDest, destPos, length, counters);
+        incrementLengthCounter(length, counters);
+
+        ArrayCopyWithSlowPathNode.arraycopy(nonNullSrc, srcPos, nonNullDest, destPos, length, workSnippet, elementKind);
+    }
+
+    @Snippet
+    public static void arraycopyGenericSnippet(Object src, int srcPos, Object dest, int destPos, int length, @ConstantParameter ArrayCopyTypeCheck arrayTypeCheck, @ConstantParameter Counters counters,
+                    @ConstantParameter SnippetInfo workSnippet, @ConstantParameter JavaKind elementKind) {
+        Object nonNullSrc = GraalDirectives.guardingNonNull(src);
+        Object nonNullDest = GraalDirectives.guardingNonNull(dest);
+        checkArrayTypes(nonNullSrc, nonNullDest, arrayTypeCheck);
+        checkLimits(nonNullSrc, srcPos, nonNullDest, destPos, length, counters);
+        incrementLengthCounter(length, counters);
+
+        ArrayCopyWithSlowPathNode.arraycopy(nonNullSrc, srcPos, nonNullDest, destPos, length, workSnippet, elementKind);
+    }
+
+    @Snippet
+    public static void arraycopyNativeSnippet(Object src, int srcPos, Object dest, int destPos, int length, @ConstantParameter Counters counters) {
+        // all checks are done in the native method, so no need to emit additional checks here
+        incrementLengthCounter(length, counters);
+        counters.systemArraycopyCounter.inc();
+        counters.systemArraycopyCopiedCounter.add(length);
+
+        System.arraycopy(src, srcPos, dest, destPos, length);
+    }
+
+    @Fold
+    static LocationIdentity getArrayLocation(JavaKind kind) {
+        return NamedLocationIdentity.getArrayLocation(kind);
+    }
+
+    private static void unrolledArraycopyWork(Object nonNullSrc, int srcPos, Object nonNullDest, int destPos, int length, JavaKind elementKind) {
+        int scale = arrayIndexScale(elementKind);
+        int arrayBaseOffset = arrayBaseOffset(elementKind);
+        LocationIdentity arrayLocation = getArrayLocation(elementKind);
+
+        long sourceOffset = arrayBaseOffset + (long) srcPos * scale;
+        long destOffset = arrayBaseOffset + (long) destPos * scale;
+        long position = 0;
+        long delta = scale;
+        if (probability(NOT_FREQUENT_PROBABILITY, nonNullSrc == nonNullDest && srcPos < destPos)) {
+            // bad aliased case so we need to copy the array from back to front
+            position = (long) (length - 1) * scale;
+            delta = -delta;
+        }
+
+        // the length was already checked before - we can emit unconditional instructions
+        ExplodeLoopNode.explodeLoop();
+        for (int iteration = 0; iteration < length; iteration++) {
+            Object value = RawLoadNode.load(nonNullSrc, sourceOffset + position, elementKind, arrayLocation);
+            RawStoreNode.storeObject(nonNullDest, destOffset + position, value, elementKind, arrayLocation, false);
+            position += delta;
+        }
+    }
+
+    @Snippet(allowPartialIntrinsicArgumentMismatch = true)
+    public static void checkcastArraycopyWithSlowPathWork(Object src, int srcPos, Object dest, int destPos, int length, @ConstantParameter Counters counters) {
+        if (probability(FREQUENT_PROBABILITY, length > 0)) {
+            Object nonNullSrc = PiNode.asNonNullObject(src);
+            Object nonNullDest = PiNode.asNonNullObject(dest);
+            KlassPointer srcKlass = loadHub(nonNullSrc);
+            KlassPointer destKlass = loadHub(nonNullDest);
+            if (probability(LIKELY_PROBABILITY, srcKlass == destKlass)) {
+                // no storecheck required.
+                counters.objectCheckcastSameTypeCounter.inc();
+                counters.objectCheckcastSameTypeCopiedCounter.add(length);
+                ArrayCopyCallNode.arraycopyObjectKillsAny(nonNullSrc, srcPos, nonNullDest, destPos, length);
+            } else {
+                KlassPointer destElemKlass = destKlass.readKlassPointer(arrayClassElementOffset(INJECTED_VMCONFIG), OBJ_ARRAY_KLASS_ELEMENT_KLASS_LOCATION);
+                Word superCheckOffset = WordFactory.signed(destElemKlass.readInt(superCheckOffsetOffset(INJECTED_VMCONFIG), KLASS_SUPER_CHECK_OFFSET_LOCATION));
+
+                counters.objectCheckcastDifferentTypeCounter.inc();
+                counters.objectCheckcastDifferentTypeCopiedCounter.add(length);
+
+                int copiedElements = CheckcastArrayCopyCallNode.checkcastArraycopy(nonNullSrc, srcPos, nonNullDest, destPos, length, superCheckOffset, destElemKlass, false);
+                if (probability(SLOW_PATH_PROBABILITY, copiedElements != 0)) {
+                    /*
+                     * the stub doesn't throw the ArrayStoreException, but returns the number of
+                     * copied elements (xor'd with -1).
+                     */
+                    copiedElements ^= -1;
+                    System.arraycopy(nonNullSrc, srcPos + copiedElements, nonNullDest, destPos + copiedElements, length - copiedElements);
+                }
+            }
+        }
+    }
+
+    @Snippet(allowPartialIntrinsicArgumentMismatch = true)
+    public static void genericArraycopyWithSlowPathWork(Object src, int srcPos, Object dest, int destPos, int length, @ConstantParameter Counters counters) {
+        if (probability(FREQUENT_PROBABILITY, length > 0)) {
+            counters.genericArraycopyDifferentTypeCounter.inc();
+            counters.genericArraycopyDifferentTypeCopiedCounter.add(length);
+            int copiedElements = GenericArrayCopyCallNode.genericArraycopy(src, srcPos, dest, destPos, length);
+            if (probability(SLOW_PATH_PROBABILITY, copiedElements != 0)) {
+                /*
+                 * the stub doesn't throw the ArrayStoreException, but returns the number of copied
+                 * elements (xor'd with -1).
+                 */
+                copiedElements ^= -1;
+                System.arraycopy(src, srcPos + copiedElements, dest, destPos + copiedElements, length - copiedElements);
+            }
+        }
+    }
+
+    private static void incrementLengthCounter(int length, Counters counters) {
+        counters.lengthHistogram.inc(length);
+    }
+
+    private static void checkLimits(Object src, int srcPos, Object dest, int destPos, int length, Counters counters) {
+        if (probability(SLOW_PATH_PROBABILITY, srcPos < 0) ||
+                        probability(SLOW_PATH_PROBABILITY, destPos < 0) ||
+                        probability(SLOW_PATH_PROBABILITY, length < 0) ||
+                        probability(SLOW_PATH_PROBABILITY, srcPos > ArrayLengthNode.arrayLength(src) - length) ||
+                        probability(SLOW_PATH_PROBABILITY, destPos > ArrayLengthNode.arrayLength(dest) - length)) {
+            counters.checkAIOOBECounter.inc();
+            DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
+        }
+        counters.checkSuccessCounter.inc();
+    }
+
+    private static void checkArrayTypes(Object nonNullSrc, Object nonNullDest, ArrayCopyTypeCheck arrayTypeCheck) {
+        if (arrayTypeCheck == ArrayCopyTypeCheck.NO_ARRAY_TYPE_CHECK) {
+            // nothing to do
+        } else if (arrayTypeCheck == ArrayCopyTypeCheck.HUB_BASED_ARRAY_TYPE_CHECK) {
+            KlassPointer srcHub = loadHub(nonNullSrc);
+            KlassPointer destHub = loadHub(nonNullDest);
+            if (probability(SLOW_PATH_PROBABILITY, srcHub != destHub)) {
+                DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
+            }
+        } else if (arrayTypeCheck == ArrayCopyTypeCheck.LAYOUT_HELPER_BASED_ARRAY_TYPE_CHECK) {
+            KlassPointer srcHub = loadHub(nonNullSrc);
+            KlassPointer destHub = loadHub(nonNullDest);
+            checkArrayType(srcHub);
+            checkArrayType(destHub);
+        } else {
+            ReplacementsUtil.staticAssert(false, "unknown array type check");
+        }
+    }
+
     private static int checkArrayType(KlassPointer nonNullHub) {
         int layoutHelper = readLayoutHelper(nonNullHub);
         if (probability(SLOW_PATH_PROBABILITY, layoutHelper >= 0)) {
@@ -97,528 +290,228 @@
         return layoutHelper;
     }
 
-    private static void checkLimits(Object src, int srcPos, Object dest, int destPos, int length, Counters counters) {
-        if (probability(SLOW_PATH_PROBABILITY, srcPos < 0)) {
-            counters.checkAIOOBECounter.inc();
-            DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
-        }
-        if (probability(SLOW_PATH_PROBABILITY, destPos < 0)) {
-            counters.checkAIOOBECounter.inc();
-            DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
-        }
-        if (probability(SLOW_PATH_PROBABILITY, length < 0)) {
-            counters.checkAIOOBECounter.inc();
-            DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
-        }
-        if (probability(SLOW_PATH_PROBABILITY, srcPos > ArrayLengthNode.arrayLength(src) - length)) {
-            counters.checkAIOOBECounter.inc();
-            DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
-        }
-        if (probability(SLOW_PATH_PROBABILITY, destPos > ArrayLengthNode.arrayLength(dest) - length)) {
-            counters.checkAIOOBECounter.inc();
-            DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
-        }
-        counters.checkSuccessCounter.inc();
-    }
-
-    @Snippet
-    public static void arraycopyZeroLengthIntrinsic(Object src, int srcPos, Object dest, int destPos, int length, @ConstantParameter Counters counters) {
-        Object nonNullSrc = GraalDirectives.guardingNonNull(src);
-        Object nonNullDest = GraalDirectives.guardingNonNull(dest);
-        KlassPointer srcHub = loadHub(nonNullSrc);
-        KlassPointer destHub = loadHub(nonNullDest);
-        checkArrayType(srcHub);
-        checkArrayType(destHub);
-        checkLimits(nonNullSrc, srcPos, nonNullDest, destPos, length, counters);
-        counters.zeroLengthStaticCounter.inc();
-    }
-
-    @Snippet
-    public static void arraycopyExactIntrinsic(Object src, int srcPos, Object dest, int destPos, int length, @ConstantParameter JavaKind elementKind, @ConstantParameter SnippetCounter counter,
-                    @ConstantParameter SnippetCounter copiedCounter, @ConstantParameter Counters counters) {
-        Object nonNullSrc = GraalDirectives.guardingNonNull(src);
-        Object nonNullDest = GraalDirectives.guardingNonNull(dest);
-        checkLimits(nonNullSrc, srcPos, nonNullDest, destPos, length, counters);
-        counter.inc();
-        copiedCounter.add(length);
-        ArrayCopyCallNode.arraycopy(nonNullSrc, srcPos, nonNullDest, destPos, length, elementKind);
-        if (length == 0) {
-            counters.zeroLengthDynamicCounter.inc();
-        } else {
-            counters.nonZeroLengthDynamicCounter.inc();
-            counters.nonZeroLengthDynamicCopiedCounter.add(length);
-        }
-    }
-
-    /**
-     * This intrinsic is useful for the case where we know something statically about one of the
-     * inputs but not the other.
-     */
-    @Snippet
-    public static void arraycopyPredictedExactIntrinsic(Object src, int srcPos, Object dest, int destPos, int length, @ConstantParameter JavaKind elementKind,
-                    @ConstantParameter SnippetCounter counter, @ConstantParameter SnippetCounter copiedCounter, @ConstantParameter Counters counters) {
-        Object nonNullSrc = GraalDirectives.guardingNonNull(src);
-        Object nonNullDest = GraalDirectives.guardingNonNull(dest);
-        KlassPointer srcHub = loadHub(nonNullSrc);
-        KlassPointer destHub = loadHub(nonNullDest);
-        if (probability(SLOW_PATH_PROBABILITY, srcHub != destHub)) {
-            DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
-        }
-        checkLimits(nonNullSrc, srcPos, nonNullDest, destPos, length, counters);
-        counter.inc();
-        copiedCounter.add(length);
-        ArrayCopyCallNode.arraycopy(nonNullSrc, srcPos, nonNullDest, destPos, length, elementKind);
-        if (length == 0) {
-            counters.zeroLengthDynamicCounter.inc();
-        } else {
-            counters.nonZeroLengthDynamicCounter.inc();
-            counters.nonZeroLengthDynamicCopiedCounter.add(length);
-        }
-    }
-
-    @Snippet
-    public static void arraycopyPredictedObjectWork(Object nonNullSrc, int srcPos, Object nonNullDest, int destPos, int length, KlassPointer objectArrayKlass,
-                    @ConstantParameter SnippetCounter counter, @ConstantParameter SnippetCounter copiedCounter, @ConstantParameter Counters counters) {
-        if (length > 0) {
-            KlassPointer srcHub = loadHub(PiNode.asNonNullObject(nonNullSrc));
-            KlassPointer destHub = loadHub(PiNode.asNonNullObject(nonNullDest));
-            if (probability(FAST_PATH_PROBABILITY, srcHub == destHub || destHub == objectArrayKlass)) {
-                counter.inc();
-                copiedCounter.add(length);
-                counters.predictedObjectArrayCopyFastPathCounter.inc();
-                counters.predictedObjectArrayCopyFastPathCopiedCounter.add(length);
-                ArrayCopyCallNode.arraycopyObjectKillsAny(nonNullSrc, srcPos, nonNullDest, destPos, length);
-            } else {
-                counters.predictedObjectArrayCopySlowPathCounter.inc();
-                counters.predictedObjectArrayCopySlowPathCopiedCounter.add(length);
-                System.arraycopy(nonNullSrc, srcPos, nonNullDest, destPos, length);
-            }
-        }
-    }
-
-    /**
-     * This is the basic template for the full arraycopy checks, including a check that the
-     * underlying type is really an array type.
-     */
-    @Snippet
-    public static void arraycopySlowPathIntrinsic(Object src, int srcPos, Object dest, int destPos, int length, KlassPointer predictedKlass, @ConstantParameter JavaKind elementKind,
-                    @ConstantParameter SnippetInfo slowPath, @ConstantParameter Object slowPathArgument, @ConstantParameter Counters counters) {
-        Object nonNullSrc = GraalDirectives.guardingNonNull(src);
-        Object nonNullDest = GraalDirectives.guardingNonNull(dest);
-        KlassPointer srcHub = loadHub(nonNullSrc);
-        KlassPointer destHub = loadHub(nonNullDest);
-        checkArrayType(srcHub);
-        checkArrayType(destHub);
-        checkLimits(nonNullSrc, srcPos, nonNullDest, destPos, length, counters);
-        if (length == 0) {
-            counters.zeroLengthDynamicCounter.inc();
-        } else {
-            counters.nonZeroLengthDynamicCounter.inc();
-            counters.nonZeroLengthDynamicCopiedCounter.add(length);
-        }
-        ArrayCopySlowPathNode.arraycopy(nonNullSrc, srcPos, nonNullDest, destPos, length, predictedKlass, elementKind, slowPath, slowPathArgument);
-    }
-
-    /**
-     * Snippet for unrolled arraycopy.
-     */
-    @Snippet
-    public static void arraycopyUnrolledIntrinsic(Object src, int srcPos, Object dest, int destPos, int length, @ConstantParameter int unrolledLength, @ConstantParameter JavaKind elementKind,
-                    @ConstantParameter Counters counters) {
-        Object nonNullSrc = GraalDirectives.guardingNonNull(src);
-        Object nonNullDest = GraalDirectives.guardingNonNull(dest);
-        checkLimits(nonNullSrc, srcPos, nonNullDest, destPos, length, counters);
-        if (length == 0) {
-            counters.zeroLengthDynamicCounter.inc();
-        } else {
-            counters.nonZeroLengthDynamicCounter.inc();
-            counters.nonZeroLengthDynamicCopiedCounter.add(length);
-        }
-        ArrayCopyUnrollNode.arraycopy(nonNullSrc, srcPos, nonNullDest, destPos, length, unrolledLength, elementKind);
-    }
-
-    @Snippet
-    public static void checkcastArraycopyWork(Object nonNullSrc, int srcPos, Object nonNullDest, int destPos, int length, @ConstantParameter Counters counters) {
-        if (length > 0) {
-            KlassPointer destKlass = loadHub(nonNullDest);
-            KlassPointer srcKlass = loadHub(nonNullSrc);
-            if (probability(SLOW_PATH_PROBABILITY, srcKlass == destKlass)) {
-                // no storecheck required.
-                counters.objectCheckcastSameTypeCounter.inc();
-                counters.objectCheckcastSameTypeCopiedCounter.add(length);
-                ArrayCopyCallNode.arraycopyObjectKillsAny(nonNullSrc, srcPos, nonNullDest, destPos, length);
-            } else {
-                KlassPointer destElemKlass = destKlass.readKlassPointer(arrayClassElementOffset(INJECTED_VMCONFIG), OBJ_ARRAY_KLASS_ELEMENT_KLASS_LOCATION);
-                Word superCheckOffset = WordFactory.signed(destElemKlass.readInt(superCheckOffsetOffset(INJECTED_VMCONFIG), KLASS_SUPER_CHECK_OFFSET_LOCATION));
-                counters.objectCheckcastCounter.inc();
-                counters.objectCheckcastCopiedCounter.add(length);
-                int copiedElements = CheckcastArrayCopyCallNode.checkcastArraycopy(nonNullSrc, srcPos, nonNullDest, destPos, length, superCheckOffset, destElemKlass, false);
-                if (copiedElements != 0) {
-                    /*
-                     * the checkcast stub doesn't throw the ArrayStoreException, but returns the
-                     * number of copied elements (xor'd with -1).
-                     */
-                    copiedElements ^= -1;
-                    System.arraycopy(nonNullSrc, srcPos + copiedElements, nonNullDest, destPos + copiedElements, length - copiedElements);
-                }
-            }
-        }
-    }
-
-    @Snippet
-    public static void arraycopyGeneric(Object src, int srcPos, Object dest, int destPos, int length, @ConstantParameter Counters counters) {
-        Object nonNullSrc = GraalDirectives.guardingNonNull(src);
-        Object nonNullDest = GraalDirectives.guardingNonNull(dest);
-        KlassPointer srcHub = loadHub(nonNullSrc);
-        KlassPointer destHub = loadHub(nonNullDest);
-        if (probability(FAST_PATH_PROBABILITY, srcHub.equal(destHub)) && probability(FAST_PATH_PROBABILITY, nonNullSrc != nonNullDest)) {
-            int layoutHelper = checkArrayType(srcHub);
-            final boolean isObjectArray = ((layoutHelper & layoutHelperElementTypePrimitiveInPlace(INJECTED_VMCONFIG)) == 0);
-            checkLimits(nonNullSrc, srcPos, nonNullDest, destPos, length, counters);
-            if (probability(FAST_PATH_PROBABILITY, isObjectArray)) {
-                counters.genericObjectExactCallCounter.inc();
-                counters.genericObjectExactCallCopiedCounter.add(length);
-                ArrayCopyCallNode.disjointArraycopy(nonNullSrc, srcPos, nonNullDest, destPos, length, JavaKind.Object);
-            } else {
-                counters.genericPrimitiveCallCounter.inc();
-                counters.genericPrimitiveCallCopiedCounter.add(length);
-                UnsafeArrayCopyNode.arraycopyPrimitive(nonNullSrc, srcPos, nonNullDest, destPos, length, layoutHelper);
-            }
-        } else {
-            counters.systemArraycopyCounter.inc();
-            counters.systemArraycopyCopiedCounter.add(length);
-            System.arraycopy(nonNullSrc, srcPos, nonNullDest, destPos, length);
-        }
-    }
-
-    @Fold
-    static LocationIdentity getArrayLocation(JavaKind kind) {
-        return NamedLocationIdentity.getArrayLocation(kind);
-    }
-
-    @Snippet
-    public static void arraycopyUnrolledWork(Object nonNullSrc, int srcPos, Object nonNullDest, int destPos, @ConstantParameter int length, @ConstantParameter JavaKind elementKind) {
-        final int scale = arrayIndexScale(elementKind);
-        int arrayBaseOffset = arrayBaseOffset(elementKind);
-        LocationIdentity arrayLocation = getArrayLocation(elementKind);
-        if (nonNullSrc == nonNullDest && srcPos < destPos) { // bad aliased case
-            long start = (long) (length - 1) * scale;
-            long i = start;
-            ExplodeLoopNode.explodeLoop();
-            for (int iteration = 0; iteration < length; iteration++) {
-                if (i >= 0) {
-                    Object a = RawLoadNode.load(nonNullSrc, arrayBaseOffset + i + (long) srcPos * scale, elementKind, arrayLocation);
-                    RawStoreNode.storeObject(nonNullDest, arrayBaseOffset + i + (long) destPos * scale, a, elementKind, arrayLocation, false);
-                    i -= scale;
-                }
-            }
-        } else {
-            long end = (long) length * scale;
-            long i = 0;
-            ExplodeLoopNode.explodeLoop();
-            for (int iteration = 0; iteration < length; iteration++) {
-                if (i < end) {
-                    Object a = RawLoadNode.load(nonNullSrc, arrayBaseOffset + i + (long) srcPos * scale, elementKind, arrayLocation);
-                    RawStoreNode.storeObject(nonNullDest, arrayBaseOffset + i + (long) destPos * scale, a, elementKind, arrayLocation, false);
-                    i += scale;
-                }
-            }
-        }
-    }
-
     static class Counters {
         final SnippetCounter checkSuccessCounter;
         final SnippetCounter checkAIOOBECounter;
 
-        final SnippetCounter objectCheckcastCounter;
-        final SnippetCounter objectCheckcastSameTypeCounter;
-        final SnippetCounter predictedObjectArrayCopySlowPathCounter;
-        final SnippetCounter predictedObjectArrayCopyFastPathCounter;
+        final SnippetCounter zeroLengthStaticCounter;
+        final SnippetIntegerHistogram lengthHistogram;
 
-        final SnippetCounter genericPrimitiveCallCounter;
-        final SnippetCounter genericObjectExactCallCounter;
         final SnippetCounter systemArraycopyCounter;
-
-        final SnippetCounter zeroLengthStaticCounter;
-        final SnippetCounter zeroLengthDynamicCounter;
-        final SnippetCounter nonZeroLengthDynamicCounter;
-
-        final SnippetCounter nonZeroLengthDynamicCopiedCounter;
-        final SnippetCounter genericPrimitiveCallCopiedCounter;
-        final SnippetCounter genericObjectExactCallCopiedCounter;
         final SnippetCounter systemArraycopyCopiedCounter;
 
-        final SnippetCounter objectCheckcastCopiedCounter;
+        final SnippetCounter genericArraycopyDifferentTypeCopiedCounter;
+        final SnippetCounter genericArraycopyDifferentTypeCounter;
+
         final SnippetCounter objectCheckcastSameTypeCopiedCounter;
-        final SnippetCounter predictedObjectArrayCopySlowPathCopiedCounter;
-        final SnippetCounter predictedObjectArrayCopyFastPathCopiedCounter;
+        final SnippetCounter objectCheckcastSameTypeCounter;
+        final SnippetCounter objectCheckcastDifferentTypeCopiedCounter;
+        final SnippetCounter objectCheckcastDifferentTypeCounter;
 
         final EnumMap<JavaKind, SnippetCounter> arraycopyCallCounters = new EnumMap<>(JavaKind.class);
-        final EnumMap<JavaKind, SnippetCounter> arraycopyCounters = new EnumMap<>(JavaKind.class);
-
         final EnumMap<JavaKind, SnippetCounter> arraycopyCallCopiedCounters = new EnumMap<>(JavaKind.class);
-        final EnumMap<JavaKind, SnippetCounter> arraycopyCopiedCounters = new EnumMap<>(JavaKind.class);
 
         Counters(SnippetCounter.Group.Factory factory) {
             final Group checkCounters = factory.createSnippetCounterGroup("System.arraycopy checkInputs");
-            final Group counters = factory.createSnippetCounterGroup("System.arraycopy");
-            final Group copiedCounters = factory.createSnippetCounterGroup("System.arraycopy copied elements");
-            final Group lengthCounters = factory.createSnippetCounterGroup("System.arraycopy 0-length checks");
+            final Group callCounters = factory.createSnippetCounterGroup("System.arraycopy calls");
+            final Group copiedElementsCounters = factory.createSnippetCounterGroup("System.arraycopy copied elements");
+            final Group lengthCounters = factory.createSnippetCounterGroup("System.arraycopy with 0-length");
 
             checkSuccessCounter = new SnippetCounter(checkCounters, "checkSuccess", "checkSuccess");
             checkAIOOBECounter = new SnippetCounter(checkCounters, "checkAIOOBE", "checkAIOOBE");
 
-            objectCheckcastCounter = new SnippetCounter(counters, "Object[]{non-exact}", "arraycopy for non-exact Object[] arrays");
-            objectCheckcastSameTypeCounter = new SnippetCounter(counters, "Object[]{same-type}", "arraycopy call for src.klass == dest.klass Object[] arrays");
-            predictedObjectArrayCopySlowPathCounter = new SnippetCounter(counters, "Object[]{slow-path}", "used System.arraycopy slow path for predicted Object[] arrays");
-            predictedObjectArrayCopyFastPathCounter = new SnippetCounter(counters, "Object[]{fast-path}", "used oop_arraycopy for predicted Object[] arrays");
-            genericPrimitiveCallCounter = new SnippetCounter(counters, "genericPrimitive", "generic arraycopy snippet for primitive arrays");
-            genericObjectExactCallCounter = new SnippetCounter(counters, "genericObjectExact", "generic arraycopy snippet for special object arrays");
-            systemArraycopyCounter = new SnippetCounter(counters, "genericObject", "call to System.arraycopy");
+            zeroLengthStaticCounter = new SnippetCounter(lengthCounters, "0-length copy static", "calls where the length is statically 0");
+            lengthHistogram = new SnippetIntegerHistogram(lengthCounters, 2, "length", "length");
 
-            zeroLengthStaticCounter = new SnippetCounter(lengthCounters, "0-lengthcopy static", "arraycopy where the length is statically 0");
-            zeroLengthDynamicCounter = new SnippetCounter(lengthCounters, "0-lengthcopy dynamically", "arraycopy where the length is dynamically 0");
-            nonZeroLengthDynamicCounter = new SnippetCounter(lengthCounters, "non-0-lengthcopy dynamically", "arraycopy where the length is dynamically not zero");
+            systemArraycopyCounter = new SnippetCounter(callCounters, "native System.arraycopy", "JNI-based System.arraycopy call");
+            systemArraycopyCopiedCounter = new SnippetCounter(copiedElementsCounters, "native System.arraycopy", "JNI-based System.arraycopy call");
+
+            genericArraycopyDifferentTypeCounter = new SnippetCounter(callCounters, "generic[] stub", "generic arraycopy stub");
+            genericArraycopyDifferentTypeCopiedCounter = new SnippetCounter(copiedElementsCounters, "generic[] stub", "generic arraycopy stub");
 
-            nonZeroLengthDynamicCopiedCounter = new SnippetCounter(copiedCounters, "non-0-lengthcopy dynamically", "arraycopy where the length is dynamically not zero");
-            genericPrimitiveCallCopiedCounter = new SnippetCounter(copiedCounters, "genericPrimitive", "generic arraycopy snippet for primitive arrays");
-            genericObjectExactCallCopiedCounter = new SnippetCounter(copiedCounters, "genericObjectExact", "generic arraycopy snippet for special object arrays");
-            systemArraycopyCopiedCounter = new SnippetCounter(copiedCounters, "genericObject", "call to System.arraycopy");
+            objectCheckcastSameTypeCounter = new SnippetCounter(callCounters, "checkcast object[] (same-type)", "checkcast object[] stub but src.klass == dest.klass Object[] arrays");
+            objectCheckcastSameTypeCopiedCounter = new SnippetCounter(copiedElementsCounters, "checkcast object[] (same-type)", "checkcast object[] stub but src.klass == dest.klass Object[] arrays");
+            objectCheckcastDifferentTypeCounter = new SnippetCounter(callCounters, "checkcast object[] (store-check)", "checkcast object[] stub with store check");
+            objectCheckcastDifferentTypeCopiedCounter = new SnippetCounter(copiedElementsCounters, "checkcast object[] (store-check)", "checkcast object[] stub with store check");
 
-            objectCheckcastCopiedCounter = new SnippetCounter(copiedCounters, "Object[]{non-exact}", "arraycopy for non-exact Object[] arrays");
-            objectCheckcastSameTypeCopiedCounter = new SnippetCounter(copiedCounters, "Object[]{same-type}", "arraycopy call for src.klass == dest.klass Object[] arrays");
-            predictedObjectArrayCopySlowPathCopiedCounter = new SnippetCounter(copiedCounters, "Object[]{slow-path}",
-                            "used System.arraycopy slow path for predicted Object[] arrays");
-            predictedObjectArrayCopyFastPathCopiedCounter = new SnippetCounter(copiedCounters, "Object[]{fast-path}", "used oop_arraycopy for predicted Object[] arrays");
-            createArraycopyCounter(JavaKind.Byte, counters, copiedCounters);
-            createArraycopyCounter(JavaKind.Boolean, counters, copiedCounters);
-            createArraycopyCounter(JavaKind.Char, counters, copiedCounters);
-            createArraycopyCounter(JavaKind.Short, counters, copiedCounters);
-            createArraycopyCounter(JavaKind.Int, counters, copiedCounters);
-            createArraycopyCounter(JavaKind.Long, counters, copiedCounters);
-            createArraycopyCounter(JavaKind.Float, counters, copiedCounters);
-            createArraycopyCounter(JavaKind.Double, counters, copiedCounters);
-            createArraycopyCounter(JavaKind.Object, counters, copiedCounters);
+            createArraycopyCounter(JavaKind.Byte, callCounters, copiedElementsCounters);
+            createArraycopyCounter(JavaKind.Boolean, callCounters, copiedElementsCounters);
+            createArraycopyCounter(JavaKind.Char, callCounters, copiedElementsCounters);
+            createArraycopyCounter(JavaKind.Short, callCounters, copiedElementsCounters);
+            createArraycopyCounter(JavaKind.Int, callCounters, copiedElementsCounters);
+            createArraycopyCounter(JavaKind.Long, callCounters, copiedElementsCounters);
+            createArraycopyCounter(JavaKind.Float, callCounters, copiedElementsCounters);
+            createArraycopyCounter(JavaKind.Double, callCounters, copiedElementsCounters);
+            createArraycopyCounter(JavaKind.Object, callCounters, copiedElementsCounters);
         }
 
         void createArraycopyCounter(JavaKind kind, Group counters, Group copiedCounters) {
-            arraycopyCallCounters.put(kind, new SnippetCounter(counters, kind + "[]{stub}", "arraycopy call for " + kind + "[] arrays"));
-            arraycopyCounters.put(kind, new SnippetCounter(counters, kind + "[]{inline}", "inline arraycopy for " + kind + "[] arrays"));
-
-            arraycopyCallCopiedCounters.put(kind, new SnippetCounter(copiedCounters, kind + "[]{stub}", "arraycopy call for " + kind + "[] arrays"));
-            arraycopyCopiedCounters.put(kind, new SnippetCounter(copiedCounters, kind + "[]{inline}", "inline arraycopy for " + kind + "[] arrays"));
+            arraycopyCallCounters.put(kind, new SnippetCounter(counters, kind + "[] stub", "arraycopy call for " + kind + "[] arrays"));
+            arraycopyCallCopiedCounters.put(kind, new SnippetCounter(copiedCounters, kind + "[] stub", "arraycopy call for " + kind + "[] arrays"));
         }
     }
 
     public static class Templates extends SnippetTemplate.AbstractTemplates {
+        private final SnippetInfo arraycopyGenericSnippet = snippet("arraycopyGenericSnippet");
+        private final SnippetInfo arraycopyUnrolledSnippet = snippet("arraycopyUnrolledSnippet");
+        private final SnippetInfo arraycopyExactSnippet = snippet("arraycopyExactSnippet");
+        private final SnippetInfo arraycopyZeroLengthSnippet = snippet("arraycopyZeroLengthSnippet");
+        private final SnippetInfo arraycopyCheckcastSnippet = snippet("arraycopyCheckcastSnippet");
+        private final SnippetInfo arraycopyNativeSnippet = snippet("arraycopyNativeSnippet");
+
+        private final SnippetInfo checkcastArraycopyWithSlowPathWork = snippet("checkcastArraycopyWithSlowPathWork");
+        private final SnippetInfo genericArraycopyWithSlowPathWork = snippet("genericArraycopyWithSlowPathWork");
+
+        private ResolvedJavaMethod originalArraycopy;
+        private final Counters counters;
 
         public Templates(OptionValues options, Iterable<DebugHandlersFactory> factories, SnippetCounter.Group.Factory factory, HotSpotProviders providers, TargetDescription target) {
             super(options, factories, providers, providers.getSnippetReflection(), target);
             this.counters = new Counters(factory);
         }
 
-        private ResolvedJavaMethod originalArraycopy() throws GraalError {
-            if (originalArraycopy == null) {
-                Method method;
-                try {
-                    method = System.class.getDeclaredMethod("arraycopy", Object.class, int.class, Object.class, int.class, int.class);
-                } catch (NoSuchMethodException | SecurityException e) {
-                    throw new GraalError(e);
-                }
-                originalArraycopy = providers.getMetaAccess().lookupJavaMethod(method);
-            }
-            return originalArraycopy;
-        }
-
-        private ResolvedJavaMethod originalArraycopy;
-
-        private final SnippetInfo checkcastArraycopyWorkSnippet = snippet("checkcastArraycopyWork");
-        private final SnippetInfo arraycopyGenericSnippet = snippet("arraycopyGeneric");
-
-        private final SnippetInfo arraycopySlowPathIntrinsicSnippet = snippet("arraycopySlowPathIntrinsic");
-        private final SnippetInfo arraycopyUnrolledIntrinsicSnippet = snippet("arraycopyUnrolledIntrinsic");
-        private final SnippetInfo arraycopyExactIntrinsicSnippet = snippet("arraycopyExactIntrinsic");
-        private final SnippetInfo arraycopyZeroLengthIntrinsicSnippet = snippet("arraycopyZeroLengthIntrinsic");
-        private final SnippetInfo arraycopyPredictedExactIntrinsicSnippet = snippet("arraycopyPredictedExactIntrinsic");
-        private final SnippetInfo arraycopyPredictedObjectWorkSnippet = snippet("arraycopyPredictedObjectWork");
-
-        private final SnippetInfo arraycopyUnrolledWorkSnippet = snippet("arraycopyUnrolledWork");
-
-        private final Counters counters;
-
         protected SnippetInfo snippet(String methodName) {
             SnippetInfo info = snippet(ArrayCopySnippets.class, methodName, LocationIdentity.any());
             info.setOriginalMethod(originalArraycopy());
             return info;
         }
 
-        public static JavaKind selectComponentKind(BasicArrayCopyNode arraycopy) {
-            return selectComponentKind(arraycopy, true);
-        }
+        public void lower(ArrayCopyNode arraycopy, LoweringTool tool) {
+            JavaKind elementKind = selectComponentKind(arraycopy);
+            SnippetInfo snippetInfo;
+            ArrayCopyTypeCheck arrayTypeCheck;
 
-        public static JavaKind selectComponentKind(BasicArrayCopyNode arraycopy, boolean exact) {
             ResolvedJavaType srcType = StampTool.typeOrNull(arraycopy.getSource().stamp());
             ResolvedJavaType destType = StampTool.typeOrNull(arraycopy.getDestination().stamp());
+            if (!canBeArray(srcType) || !canBeArray(destType)) {
+                // at least one of the objects is definitely not an array - use the native call
+                // right away as the copying will fail anyways
+                snippetInfo = arraycopyNativeSnippet;
+                arrayTypeCheck = ArrayCopyTypeCheck.UNDEFINED_ARRAY_TYPE_CHECK;
+            } else {
+                ResolvedJavaType srcComponentType = srcType == null ? null : srcType.getComponentType();
+                ResolvedJavaType destComponentType = destType == null ? null : destType.getComponentType();
 
-            if (srcType == null || !srcType.isArray() || destType == null || !destType.isArray()) {
-                if (!exact) {
-                    JavaKind component = getComponentKind(srcType);
-                    if (component != null) {
-                        return component;
+                if (arraycopy.isExact()) {
+                    // there is a sufficient type match - we don't need any additional type checks
+                    snippetInfo = arraycopyExactSnippet;
+                    arrayTypeCheck = ArrayCopyTypeCheck.NO_ARRAY_TYPE_CHECK;
+                } else if (srcComponentType == null && destComponentType == null) {
+                    // we don't know anything about the types - use the generic copying
+                    snippetInfo = arraycopyGenericSnippet;
+                    arrayTypeCheck = ArrayCopyTypeCheck.LAYOUT_HELPER_BASED_ARRAY_TYPE_CHECK;
+                } else if (srcComponentType != null && destComponentType != null) {
+                    if (!srcComponentType.isPrimitive() && !destComponentType.isPrimitive()) {
+                        // it depends on the array content if the copy succeeds - we need
+                        // a type check for every store
+                        snippetInfo = arraycopyCheckcastSnippet;
+                        arrayTypeCheck = ArrayCopyTypeCheck.NO_ARRAY_TYPE_CHECK;
+                    } else {
+                        // one object is an object array, the other one is a primitive array.
+                        // this copy will always fail - use the native call right away
+                        assert !srcComponentType.equals(destComponentType) : "must be handled by arraycopy.isExact()";
+                        snippetInfo = arraycopyNativeSnippet;
+                        arrayTypeCheck = ArrayCopyTypeCheck.UNDEFINED_ARRAY_TYPE_CHECK;
                     }
-                    return getComponentKind(destType);
-                }
-                return null;
-            }
-            if (exact) {
-                if (!destType.getComponentType().isAssignableFrom(srcType.getComponentType())) {
-                    return null;
-                }
-                if (!arraycopy.isExact()) {
-                    return null;
+                } else {
+                    ResolvedJavaType nonNullComponentType = srcComponentType != null ? srcComponentType : destComponentType;
+                    if (nonNullComponentType.isPrimitive()) {
+                        // one involved object is a primitive array - we can safely assume that we
+                        // are copying primitive arrays
+                        snippetInfo = arraycopyExactSnippet;
+                        arrayTypeCheck = ArrayCopyTypeCheck.HUB_BASED_ARRAY_TYPE_CHECK;
+                        elementKind = nonNullComponentType.getJavaKind();
+                    } else {
+                        // one involved object is an object array - we can safely assume that we are
+                        // copying object arrays that might require a store check
+                        snippetInfo = arraycopyCheckcastSnippet;
+                        arrayTypeCheck = ArrayCopyTypeCheck.LAYOUT_HELPER_BASED_ARRAY_TYPE_CHECK;
+                    }
                 }
             }
-            return srcType.getComponentType().getJavaKind();
-        }
 
-        private static JavaKind getComponentKind(ResolvedJavaType type) {
-            if (type != null && type.isArray()) {
-                return type.getComponentType().getJavaKind();
-            }
-            return null;
-        }
-
-        private static boolean shouldUnroll(ValueNode length) {
-            return length.isConstant() && length.asJavaConstant().asInt() <= 8 && length.asJavaConstant().asInt() != 0;
-        }
-
-        public void lower(ArrayCopyNode arraycopy, LoweringTool tool) {
-            JavaKind componentKind = selectComponentKind(arraycopy);
-            SnippetInfo snippetInfo = null;
-            SnippetInfo slowPathSnippetInfo = null;
-            Object slowPathArgument = null;
-
+            // a few special cases that are easier to handle when all other variables already have a
+            // value
             if (arraycopy.getLength().isConstant() && arraycopy.getLength().asJavaConstant().asLong() == 0) {
-                snippetInfo = arraycopyZeroLengthIntrinsicSnippet;
-            } else if (arraycopy.isExact()) {
-                snippetInfo = arraycopyExactIntrinsicSnippet;
-                if (shouldUnroll(arraycopy.getLength())) {
-                    snippetInfo = arraycopyUnrolledIntrinsicSnippet;
-                }
-            } else {
-                if (componentKind == JavaKind.Object) {
-                    ResolvedJavaType srcType = StampTool.typeOrNull(arraycopy.getSource().stamp());
-                    ResolvedJavaType destType = StampTool.typeOrNull(arraycopy.getDestination().stamp());
-                    ResolvedJavaType srcComponentType = srcType == null ? null : srcType.getComponentType();
-                    ResolvedJavaType destComponentType = destType == null ? null : destType.getComponentType();
-                    if (srcComponentType != null && destComponentType != null && !srcComponentType.isPrimitive() && !destComponentType.isPrimitive()) {
-                        snippetInfo = arraycopySlowPathIntrinsicSnippet;
-                        slowPathSnippetInfo = checkcastArraycopyWorkSnippet;
-                        slowPathArgument = LocationIdentity.any();
-                        /*
-                         * Because this snippet has to use Sysytem.arraycopy as a slow path, we must
-                         * pretend to kill any() so clear the componentKind.
-                         */
-                        componentKind = null;
-                    }
-                }
-                if (componentKind == null && snippetInfo == null) {
-                    JavaKind predictedKind = selectComponentKind(arraycopy, false);
-                    if (predictedKind != null) {
-                        /*
-                         * At least one array is of a known type requiring no store checks, so
-                         * assume the other is of the same type. Generally this is working around
-                         * deficiencies in our propagation of type information.
-                         */
-                        componentKind = predictedKind;
-                        if (predictedKind == JavaKind.Object) {
-                            snippetInfo = arraycopySlowPathIntrinsicSnippet;
-                            slowPathSnippetInfo = arraycopyPredictedObjectWorkSnippet;
-                            slowPathArgument = predictedKind;
-                            componentKind = null;
-                        } else {
-                            snippetInfo = arraycopyPredictedExactIntrinsicSnippet;
-                        }
-                    }
-                }
-                if (snippetInfo == null) {
-                    snippetInfo = arraycopyGenericSnippet;
-                }
+                snippetInfo = arraycopyZeroLengthSnippet;
+            } else if (snippetInfo == arraycopyExactSnippet && shouldUnroll(arraycopy.getLength())) {
+                snippetInfo = arraycopyUnrolledSnippet;
             }
+
+            // create the snippet
             Arguments args = new Arguments(snippetInfo, arraycopy.graph().getGuardsStage(), tool.getLoweringStage());
             args.add("src", arraycopy.getSource());
             args.add("srcPos", arraycopy.getSourcePosition());
             args.add("dest", arraycopy.getDestination());
             args.add("destPos", arraycopy.getDestinationPosition());
             args.add("length", arraycopy.getLength());
-            if (snippetInfo == arraycopyUnrolledIntrinsicSnippet) {
+            if (snippetInfo != arraycopyNativeSnippet) {
+                assert arrayTypeCheck != ArrayCopyTypeCheck.UNDEFINED_ARRAY_TYPE_CHECK;
+                args.addConst("arrayTypeCheck", arrayTypeCheck);
+            }
+            if (snippetInfo == arraycopyUnrolledSnippet) {
+                args.addConst("elementKind", elementKind != null ? elementKind : JavaKind.Illegal);
                 args.addConst("unrolledLength", arraycopy.getLength().asJavaConstant().asInt());
-                args.addConst("elementKind", componentKind != null ? componentKind : JavaKind.Illegal);
-            } else if (snippetInfo == arraycopySlowPathIntrinsicSnippet) {
-                ValueNode predictedKlass = null;
-                if (slowPathArgument == arraycopyPredictedObjectWorkSnippet) {
-                    HotSpotResolvedObjectType arrayClass = (HotSpotResolvedObjectType) tool.getMetaAccess().lookupJavaType(Object[].class);
-                    predictedKlass = ConstantNode.forConstant(KlassPointerStamp.klassNonNull(), arrayClass.klass(), tool.getMetaAccess(), arraycopy.graph());
-                } else {
-                    predictedKlass = ConstantNode.forConstant(KlassPointerStamp.klassAlwaysNull(), JavaConstant.NULL_POINTER, tool.getMetaAccess(), arraycopy.graph());
-                }
-                args.add("predictedKlass", predictedKlass);
-                args.addConst("elementKind", componentKind != null ? componentKind : JavaKind.Illegal);
-                args.addConst("slowPath", slowPathSnippetInfo);
-                assert slowPathArgument != null;
-                args.addConst("slowPathArgument", slowPathArgument);
-            } else if (snippetInfo == arraycopyExactIntrinsicSnippet || snippetInfo == arraycopyPredictedExactIntrinsicSnippet) {
-                assert componentKind != null;
-                args.addConst("elementKind", componentKind);
-                args.addConst("counter", counters.arraycopyCallCounters.get(componentKind));
-                args.addConst("copiedCounter", counters.arraycopyCallCopiedCounters.get(componentKind));
+            }
+            if (snippetInfo == arraycopyExactSnippet) {
+                assert elementKind != null;
+                args.addConst("elementKind", elementKind);
+                args.addConst("elementKindCounter", counters.arraycopyCallCounters.get(elementKind));
+                args.addConst("elementKindCopiedCounter", counters.arraycopyCallCopiedCounters.get(elementKind));
+            }
+            args.addConst("counters", counters);
+            if (snippetInfo == arraycopyCheckcastSnippet) {
+                args.addConst("workSnippet", checkcastArraycopyWithSlowPathWork);
+                args.addConst("elementKind", JavaKind.Illegal);
+            }
+            if (snippetInfo == arraycopyGenericSnippet) {
+                args.addConst("workSnippet", genericArraycopyWithSlowPathWork);
+                args.addConst("elementKind", JavaKind.Illegal);
             }
+
+            instantiate(args, arraycopy);
+        }
+
+        public void lower(ArrayCopyWithSlowPathNode arraycopy, LoweringTool tool) {
+            StructuredGraph graph = arraycopy.graph();
+            if (!graph.getGuardsStage().areFrameStatesAtDeopts()) {
+                // if an arraycopy contains a slow path, we can't lower it right away
+                return;
+            }
+
+            SnippetInfo snippetInfo = arraycopy.getSnippet();
+            Arguments args = new Arguments(snippetInfo, graph.getGuardsStage(), tool.getLoweringStage());
+            args.add("src", arraycopy.getSource());
+            args.add("srcPos", arraycopy.getSourcePosition());
+            args.add("dest", arraycopy.getDestination());
+            args.add("destPos", arraycopy.getDestinationPosition());
+            args.add("length", arraycopy.getLength());
             args.addConst("counters", counters);
             instantiate(args, arraycopy);
         }
 
-        public void lower(ArrayCopySlowPathNode arraycopy, LoweringTool tool) {
-            StructuredGraph graph = arraycopy.graph();
-            if (!graph.getGuardsStage().areFrameStatesAtDeopts()) {
-                // Can't be lowered yet
-                return;
-            }
-            SnippetInfo snippetInfo = arraycopy.getSnippet();
-            Arguments args = new Arguments(snippetInfo, graph.getGuardsStage(), tool.getLoweringStage());
-            args.add("nonNullSrc", arraycopy.getSource());
-            args.add("srcPos", arraycopy.getSourcePosition());
-            args.add("nonNullDest", arraycopy.getDestination());
-            args.add("destPos", arraycopy.getDestinationPosition());
-            if (snippetInfo == arraycopyUnrolledWorkSnippet) {
-                args.addConst("length", ((Integer) arraycopy.getArgument()).intValue());
-                args.addConst("elementKind", arraycopy.getElementKind());
-            } else {
-                args.add("length", arraycopy.getLength());
-            }
-            if (snippetInfo == arraycopyPredictedObjectWorkSnippet) {
-                args.add("objectArrayKlass", arraycopy.getPredictedKlass());
-                args.addConst("counter", counters.arraycopyCallCounters.get(JavaKind.Object));
-                args.addConst("copiedCounter", counters.arraycopyCallCopiedCounters.get(JavaKind.Object));
-                args.addConst("counters", counters);
-            }
-            instantiate(args, arraycopy);
+        private static boolean canBeArray(ResolvedJavaType type) {
+            return type == null || type.isJavaLangObject() || type.isArray();
         }
 
-        public void lower(ArrayCopyUnrollNode arraycopy, LoweringTool tool) {
-            StructuredGraph graph = arraycopy.graph();
-            if (!graph.getGuardsStage().areFrameStatesAtDeopts()) {
-                // Can't be lowered yet
-                return;
+        public static JavaKind selectComponentKind(BasicArrayCopyNode arraycopy) {
+            ResolvedJavaType srcType = StampTool.typeOrNull(arraycopy.getSource().stamp());
+            ResolvedJavaType destType = StampTool.typeOrNull(arraycopy.getDestination().stamp());
+
+            if (srcType == null || !srcType.isArray() || destType == null || !destType.isArray()) {
+                return null;
             }
-            SnippetInfo snippetInfo = arraycopyUnrolledWorkSnippet;
-            Arguments args = new Arguments(snippetInfo, graph.getGuardsStage(), tool.getLoweringStage());
-            args.add("nonNullSrc", arraycopy.getSource());
-            args.add("srcPos", arraycopy.getSourcePosition());
-            args.add("nonNullDest", arraycopy.getDestination());
-            args.add("destPos", arraycopy.getDestinationPosition());
-            args.addConst("length", arraycopy.getUnrollLength());
-            args.addConst("elementKind", arraycopy.getElementKind());
-            template(graph.getDebug(), args).instantiate(providers.getMetaAccess(), arraycopy, SnippetTemplate.DEFAULT_REPLACER, args);
+            if (!destType.getComponentType().isAssignableFrom(srcType.getComponentType())) {
+                return null;
+            }
+            if (!arraycopy.isExact()) {
+                return null;
+            }
+            return srcType.getComponentType().getJavaKind();
+        }
+
+        private static boolean shouldUnroll(ValueNode length) {
+            return length.isConstant() && length.asJavaConstant().asInt() <= 8 && length.asJavaConstant().asInt() != 0;
         }
 
         /**
@@ -650,8 +543,8 @@
                         newInvoke.setStateAfter(arraycopy.stateAfter());
                     }
                     graph.replaceFixedWithFixed((InvokeNode) invoke.asNode(), newInvoke);
-                } else if (originalNode instanceof ArrayCopySlowPathNode) {
-                    ArrayCopySlowPathNode slowPath = (ArrayCopySlowPathNode) replacements.get(originalNode);
+                } else if (originalNode instanceof ArrayCopyWithSlowPathNode) {
+                    ArrayCopyWithSlowPathNode slowPath = (ArrayCopyWithSlowPathNode) replacements.get(originalNode);
                     assert arraycopy.stateAfter() != null : arraycopy;
                     assert slowPath.stateAfter() == arraycopy.stateAfter();
                     slowPath.setBci(arraycopy.getBci());
@@ -659,5 +552,18 @@
             }
             GraphUtil.killCFG(arraycopy);
         }
+
+        private ResolvedJavaMethod originalArraycopy() throws GraalError {
+            if (originalArraycopy == null) {
+                Method method;
+                try {
+                    method = System.class.getDeclaredMethod("arraycopy", Object.class, int.class, Object.class, int.class, int.class);
+                } catch (NoSuchMethodException | SecurityException e) {
+                    throw new GraalError(e);
+                }
+                originalArraycopy = providers.getMetaAccess().lookupJavaMethod(method);
+            }
+            return originalArraycopy;
+        }
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/ArrayCopyUnrollNode.java	Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,148 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package org.graalvm.compiler.hotspot.replacements.arraycopy;
-
-import jdk.vm.ci.meta.JavaKind;
-
-import static org.graalvm.word.LocationIdentity.any;
-
-import org.graalvm.compiler.core.common.type.StampFactory;
-import org.graalvm.compiler.graph.NodeClass;
-import org.graalvm.compiler.nodeinfo.InputType;
-import org.graalvm.compiler.nodeinfo.NodeInfo;
-import org.graalvm.compiler.nodes.NamedLocationIdentity;
-import org.graalvm.compiler.nodes.ValueNode;
-import org.graalvm.compiler.nodes.extended.ArrayRangeWriteNode;
-import org.graalvm.compiler.nodes.memory.MemoryAccess;
-import org.graalvm.compiler.nodes.memory.MemoryCheckpoint;
-import org.graalvm.compiler.nodes.memory.MemoryNode;
-import org.graalvm.compiler.nodes.spi.Lowerable;
-import org.graalvm.compiler.nodes.spi.LoweringTool;
-import org.graalvm.word.LocationIdentity;
-
-@NodeInfo(allowedUsageTypes = InputType.Memory)
-public class ArrayCopyUnrollNode extends ArrayRangeWriteNode implements MemoryCheckpoint.Single, Lowerable, MemoryAccess {
-
-    public static final NodeClass<ArrayCopyUnrollNode> TYPE = NodeClass.create(ArrayCopyUnrollNode.class);
-
-    @Input protected ValueNode src;
-    @Input protected ValueNode srcPos;
-    @Input protected ValueNode dest;
-    @Input protected ValueNode destPos;
-    @Input protected ValueNode length;
-
-    private JavaKind elementKind;
-
-    private int unrolledLength;
-
-    @OptionalInput(InputType.Memory) private MemoryNode lastLocationAccess;
-
-    public ArrayCopyUnrollNode(ValueNode src, ValueNode srcPos, ValueNode dest, ValueNode destPos, ValueNode length, int unrolledLength, JavaKind elementKind) {
-        super(TYPE, StampFactory.forKind(JavaKind.Void));
-        this.src = src;
-        this.srcPos = srcPos;
-        this.dest = dest;
-        this.destPos = destPos;
-        this.length = length;
-        this.unrolledLength = unrolledLength;
-        assert elementKind != null && elementKind != JavaKind.Illegal;
-        this.elementKind = elementKind;
-    }
-
-    public ValueNode getSource() {
-        return src;
-    }
-
-    public ValueNode getSourcePosition() {
-        return srcPos;
-    }
-
-    public ValueNode getDestination() {
-        return dest;
-    }
-
-    public ValueNode getDestinationPosition() {
-        return destPos;
-    }
-
-    @Override
-    public ValueNode getLength() {
-        return length;
-    }
-
-    @Override
-    public ValueNode getArray() {
-        return dest;
-    }
-
-    @Override
-    public ValueNode getIndex() {
-        return destPos;
-    }
-
-    @Override
-    public boolean isObjectArray() {
-        return elementKind == JavaKind.Object;
-    }
-
-    @Override
-    public boolean isInitialization() {
-        return false;
-    }
-
-    @NodeIntrinsic
-    public static native void arraycopy(Object nonNullSrc, int srcPos, Object nonNullDest, int destPos, int length, @ConstantNodeParameter int unrolledLength,
-                    @ConstantNodeParameter JavaKind elementKind);
-
-    public int getUnrollLength() {
-        return unrolledLength;
-    }
-
-    public JavaKind getElementKind() {
-        return elementKind;
-    }
-
-    @Override
-    public LocationIdentity getLocationIdentity() {
-        if (elementKind != null) {
-            return NamedLocationIdentity.getArrayLocation(elementKind);
-        }
-        return any();
-    }
-
-    @Override
-    public void lower(LoweringTool tool) {
-        tool.getLowerer().lower(this, tool);
-    }
-
-    @Override
-    public MemoryNode getLastLocationAccess() {
-        return lastLocationAccess;
-    }
-
-    @Override
-    public void setLastLocationAccess(MemoryNode lla) {
-        updateUsagesInterface(lastLocationAccess, lla);
-        lastLocationAccess = lla;
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/ArrayCopyWithSlowPathNode.java	Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.graalvm.compiler.hotspot.replacements.arraycopy;
+
+import org.graalvm.compiler.graph.NodeClass;
+import org.graalvm.compiler.nodeinfo.InputType;
+import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.ValueNode;
+import org.graalvm.compiler.nodes.type.StampTool;
+import org.graalvm.compiler.replacements.SnippetTemplate;
+import org.graalvm.compiler.replacements.nodes.BasicArrayCopyNode;
+
+import jdk.vm.ci.code.BytecodeFrame;
+import jdk.vm.ci.meta.JavaKind;
+
+@NodeInfo(allowedUsageTypes = InputType.Memory)
+public final class ArrayCopyWithSlowPathNode extends BasicArrayCopyNode {
+
+    public static final NodeClass<ArrayCopyWithSlowPathNode> TYPE = NodeClass.create(ArrayCopyWithSlowPathNode.class);
+
+    private final SnippetTemplate.SnippetInfo snippet;
+
+    public ArrayCopyWithSlowPathNode(ValueNode src, ValueNode srcPos, ValueNode dest, ValueNode destPos, ValueNode length, SnippetTemplate.SnippetInfo snippet, JavaKind elementKind) {
+        super(TYPE, src, srcPos, dest, destPos, length, elementKind, BytecodeFrame.INVALID_FRAMESTATE_BCI);
+        assert StampTool.isPointerNonNull(src) && StampTool.isPointerNonNull(dest) : "must have been null checked";
+        this.snippet = snippet;
+    }
+
+    @NodeIntrinsic
+    public static native void arraycopy(Object nonNullSrc, int srcPos, Object nonNullDest, int destPos, int length, @ConstantNodeParameter SnippetTemplate.SnippetInfo snippet,
+                    @ConstantNodeParameter JavaKind elementKind);
+
+    public SnippetTemplate.SnippetInfo getSnippet() {
+        return snippet;
+    }
+
+    public void setBci(int bci) {
+        this.bci = bci;
+    }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/CheckcastArrayCopyCallNode.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/CheckcastArrayCopyCallNode.java	Wed Nov 08 16:03:35 2017 -0500
@@ -23,12 +23,13 @@
 //JaCoCo Exclude
 package org.graalvm.compiler.hotspot.replacements.arraycopy;
 
+import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntimeProvider.getArrayBaseOffset;
+import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntimeProvider.getArrayIndexScale;
 import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_UNKNOWN;
 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_UNKNOWN;
-import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntimeProvider.getArrayBaseOffset;
-import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntimeProvider.getArrayIndexScale;
 
 import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
+import org.graalvm.compiler.core.common.type.PrimitiveStamp;
 import org.graalvm.compiler.core.common.type.StampFactory;
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider;
@@ -114,8 +115,9 @@
         graph().addBeforeFixed(this, basePtr);
 
         int shift = CodeUtil.log2(getArrayIndexScale(JavaKind.Object));
-        ValueNode scaledIndex = graph().unique(new LeftShiftNode(pos, ConstantNode.forInt(shift, graph())));
-        ValueNode offset = graph().unique(new AddNode(scaledIndex, ConstantNode.forInt(getArrayBaseOffset(JavaKind.Object), graph())));
+        ValueNode extendedPos = IntegerConvertNode.convert(pos, StampFactory.forKind(runtime.getTarget().wordJavaKind), graph());
+        ValueNode scaledIndex = graph().unique(new LeftShiftNode(extendedPos, ConstantNode.forInt(shift, graph())));
+        ValueNode offset = graph().unique(new AddNode(scaledIndex, ConstantNode.forIntegerBits(PrimitiveStamp.getBits(scaledIndex.stamp()), getArrayBaseOffset(JavaKind.Object), graph())));
         return graph().unique(new OffsetAddressNode(basePtr, offset));
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/GenericArrayCopyCallNode.java	Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+//JaCoCo Exclude
+package org.graalvm.compiler.hotspot.replacements.arraycopy;
+
+import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_UNKNOWN;
+import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_UNKNOWN;
+
+import org.graalvm.compiler.core.common.type.StampFactory;
+import org.graalvm.compiler.graph.NodeClass;
+import org.graalvm.compiler.hotspot.HotSpotBackend;
+import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider;
+import org.graalvm.compiler.hotspot.nodes.GetObjectAddressNode;
+import org.graalvm.compiler.nodeinfo.InputType;
+import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.ValueNode;
+import org.graalvm.compiler.nodes.calc.IntegerConvertNode;
+import org.graalvm.compiler.nodes.extended.ForeignCallNode;
+import org.graalvm.compiler.nodes.memory.AbstractMemoryCheckpoint;
+import org.graalvm.compiler.nodes.memory.MemoryCheckpoint;
+import org.graalvm.compiler.nodes.spi.Lowerable;
+import org.graalvm.compiler.nodes.spi.LoweringTool;
+import org.graalvm.word.LocationIdentity;
+
+import jdk.vm.ci.meta.JavaKind;
+
+@NodeInfo(allowedUsageTypes = {InputType.Memory, InputType.Value}, cycles = CYCLES_UNKNOWN, size = SIZE_UNKNOWN)
+public final class GenericArrayCopyCallNode extends AbstractMemoryCheckpoint implements Lowerable, MemoryCheckpoint.Single {
+
+    public static final NodeClass<GenericArrayCopyCallNode> TYPE = NodeClass.create(GenericArrayCopyCallNode.class);
+    @Input ValueNode src;
+    @Input ValueNode srcPos;
+    @Input ValueNode dest;
+    @Input ValueNode destPos;
+    @Input ValueNode length;
+
+    protected final HotSpotGraalRuntimeProvider runtime;
+
+    protected GenericArrayCopyCallNode(@InjectedNodeParameter HotSpotGraalRuntimeProvider runtime, ValueNode src, ValueNode srcPos, ValueNode dest, ValueNode destPos, ValueNode length) {
+        super(TYPE, StampFactory.forKind(JavaKind.Int));
+        this.src = src;
+        this.srcPos = srcPos;
+        this.dest = dest;
+        this.destPos = destPos;
+        this.length = length;
+        this.runtime = runtime;
+    }
+
+    public ValueNode getSource() {
+        return src;
+    }
+
+    public ValueNode getSourcePosition() {
+        return srcPos;
+    }
+
+    public ValueNode getDestination() {
+        return dest;
+    }
+
+    public ValueNode getDestinationPosition() {
+        return destPos;
+    }
+
+    public ValueNode getLength() {
+        return length;
+    }
+
+    @Override
+    public void lower(LoweringTool tool) {
+        if (graph().getGuardsStage().areFrameStatesAtDeopts()) {
+            StructuredGraph graph = graph();
+            ValueNode srcAddr = objectAddress(getSource());
+            ValueNode destAddr = objectAddress(getDestination());
+            ForeignCallNode call = graph.add(new ForeignCallNode(runtime.getHostBackend().getForeignCalls(), HotSpotBackend.GENERIC_ARRAYCOPY, srcAddr, srcPos, destAddr, destPos, length));
+            call.setStateAfter(stateAfter());
+            graph.replaceFixedWithFixed(this, call);
+        }
+    }
+
+    private ValueNode objectAddress(ValueNode obj) {
+        GetObjectAddressNode result = graph().add(new GetObjectAddressNode(obj));
+        graph().addBeforeFixed(this, result);
+        return result;
+    }
+
+    private ValueNode wordValue(ValueNode value) {
+        if (value.stamp().getStackKind() != runtime.getTarget().wordJavaKind) {
+            return IntegerConvertNode.convert(value, StampFactory.forKind(runtime.getTarget().wordJavaKind), graph());
+        }
+        return value;
+    }
+
+    @Override
+    public LocationIdentity getLocationIdentity() {
+        return LocationIdentity.any();
+    }
+
+    @NodeIntrinsic
+    public static native int genericArraycopy(Object src, int srcPos, Object dest, int destPos, int length);
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/UnsafeArrayCopyNode.java	Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,153 +0,0 @@
-/*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * 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 org.graalvm.compiler.hotspot.replacements.arraycopy;
-
-import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_256;
-import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_64;
-import static org.graalvm.word.LocationIdentity.any;
-
-import org.graalvm.compiler.core.common.type.StampFactory;
-import org.graalvm.compiler.graph.NodeClass;
-import org.graalvm.compiler.nodeinfo.InputType;
-import org.graalvm.compiler.nodeinfo.NodeInfo;
-import org.graalvm.compiler.nodes.NamedLocationIdentity;
-import org.graalvm.compiler.nodes.ValueNode;
-import org.graalvm.compiler.nodes.extended.ArrayRangeWriteNode;
-import org.graalvm.compiler.nodes.memory.MemoryAccess;
-import org.graalvm.compiler.nodes.memory.MemoryCheckpoint;
-import org.graalvm.compiler.nodes.memory.MemoryNode;
-import org.graalvm.compiler.nodes.spi.Lowerable;
-import org.graalvm.compiler.nodes.spi.LoweringTool;
-import org.graalvm.compiler.replacements.SnippetTemplate.Arguments;
-import org.graalvm.word.LocationIdentity;
-
-import jdk.vm.ci.meta.JavaKind;
-
-@NodeInfo(allowedUsageTypes = {InputType.Memory}, cycles = CYCLES_256, size = SIZE_64)
-public final class UnsafeArrayCopyNode extends ArrayRangeWriteNode implements Lowerable, MemoryCheckpoint.Single, MemoryAccess {
-
-    public static final NodeClass<UnsafeArrayCopyNode> TYPE = NodeClass.create(UnsafeArrayCopyNode.class);
-    @Input ValueNode src;
-    @Input ValueNode srcPos;
-    @Input ValueNode dest;
-    @Input ValueNode destPos;
-    @Input ValueNode length;
-    @OptionalInput ValueNode layoutHelper;
-
-    @OptionalInput(InputType.Memory) MemoryNode lastLocationAccess;
-
-    protected JavaKind elementKind;
-
-    public UnsafeArrayCopyNode(ValueNode src, ValueNode srcPos, ValueNode dest, ValueNode destPos, ValueNode length, ValueNode layoutHelper, JavaKind elementKind) {
-        super(TYPE, StampFactory.forVoid());
-        assert layoutHelper == null || elementKind == null;
-        this.src = src;
-        this.srcPos = srcPos;
-        this.dest = dest;
-        this.destPos = destPos;
-        this.length = length;
-        this.layoutHelper = layoutHelper;
-        this.elementKind = elementKind;
-    }
-
-    public UnsafeArrayCopyNode(ValueNode src, ValueNode srcPos, ValueNode dest, ValueNode destPos, ValueNode length, JavaKind elementKind) {
-        this(src, srcPos, dest, destPos, length, null, elementKind);
-    }
-
-    public UnsafeArrayCopyNode(ValueNode src, ValueNode srcPos, ValueNode dest, ValueNode destPos, ValueNode length, ValueNode layoutHelper) {
-        this(src, srcPos, dest, destPos, length, layoutHelper, null);
-    }
-
-    @Override
-    public ValueNode getArray() {
-        return dest;
-    }
-
-    @Override
-    public ValueNode getIndex() {
-        return destPos;
-    }
-
-    @Override
-    public ValueNode getLength() {
-        return length;
-    }
-
-    @Override
-    public boolean isObjectArray() {
-        return elementKind == JavaKind.Object;
-    }
-
-    @Override
-    public boolean isInitialization() {
-        return false;
-    }
-
-    public JavaKind getElementKind() {
-        return elementKind;
-    }
-
-    @Override
-    public void lower(LoweringTool tool) {
-        if (graph().getGuardsStage().areFrameStatesAtDeopts()) {
-            UnsafeArrayCopySnippets.Templates templates = tool.getReplacements().getSnippetTemplateCache(UnsafeArrayCopySnippets.Templates.class);
-            templates.lower(this, tool);
-        }
-    }
-
-    public void addSnippetArguments(Arguments args) {
-        args.add("src", src);
-        args.add("srcPos", srcPos);
-        args.add("dest", dest);
-        args.add("destPos", destPos);
-        args.add("length", length);
-        if (layoutHelper != null) {
-            args.add("layoutHelper", layoutHelper);
-        }
-    }
-
-    @Override
-    public LocationIdentity getLocationIdentity() {
-        if (elementKind != null) {
-            return NamedLocationIdentity.getArrayLocation(elementKind);
-        }
-        return any();
-    }
-
-    @Override
-    public MemoryNode getLastLocationAccess() {
-        return lastLocationAccess;
-    }
-
-    @Override
-    public void setLastLocationAccess(MemoryNode lla) {
-        updateUsagesInterface(lastLocationAccess, lla);
-        lastLocationAccess = lla;
-    }
-
-    @NodeIntrinsic
-    public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length, @ConstantNodeParameter JavaKind elementKind);
-
-    @NodeIntrinsic
-    public static native void arraycopyPrimitive(Object src, int srcPos, Object dest, int destPos, int length, int layoutHelper);
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/UnsafeArrayCopySnippets.java	Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,324 +0,0 @@
-/*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * 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 org.graalvm.compiler.hotspot.replacements.arraycopy;
-
-import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntimeProvider.getArrayIndexScale;
-import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfig.INJECTED_VMCONFIG;
-import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.arrayBaseOffset;
-import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.arrayIndexScale;
-import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.layoutHelperHeaderSizeMask;
-import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.layoutHelperHeaderSizeShift;
-import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.layoutHelperLog2ElementSizeMask;
-import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.layoutHelperLog2ElementSizeShift;
-import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.runtime;
-import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.wordSize;
-import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.NOT_FREQUENT_PROBABILITY;
-import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.probability;
-import static org.graalvm.compiler.replacements.SnippetTemplate.DEFAULT_REPLACER;
-import static org.graalvm.word.LocationIdentity.any;
-
-import org.graalvm.compiler.api.replacements.Fold;
-import org.graalvm.compiler.api.replacements.Snippet;
-import org.graalvm.compiler.core.common.NumUtil;
-import org.graalvm.compiler.debug.DebugHandlersFactory;
-import org.graalvm.compiler.hotspot.meta.HotSpotProviders;
-import org.graalvm.compiler.hotspot.phases.WriteBarrierAdditionPhase;
-import org.graalvm.compiler.nodes.NamedLocationIdentity;
-import org.graalvm.compiler.nodes.extended.RawLoadNode;
-import org.graalvm.compiler.nodes.extended.RawStoreNode;
-import org.graalvm.compiler.nodes.extended.UnsafeCopyNode;
-import org.graalvm.compiler.nodes.spi.LoweringTool;
-import org.graalvm.compiler.options.OptionValues;
-import org.graalvm.compiler.replacements.SnippetTemplate;
-import org.graalvm.compiler.replacements.SnippetTemplate.AbstractTemplates;
-import org.graalvm.compiler.replacements.SnippetTemplate.Arguments;
-import org.graalvm.compiler.replacements.SnippetTemplate.SnippetInfo;
-import org.graalvm.compiler.replacements.Snippets;
-import org.graalvm.compiler.word.ObjectAccess;
-import org.graalvm.word.LocationIdentity;
-import org.graalvm.word.UnsignedWord;
-import org.graalvm.word.WordFactory;
-
-import jdk.vm.ci.code.TargetDescription;
-import jdk.vm.ci.meta.JavaKind;
-
-/**
- * As opposed to {@link ArrayCopySnippets}, these Snippets do <b>not</b> perform store checks.
- */
-public class UnsafeArrayCopySnippets implements Snippets {
-
-    private static final boolean supportsUnalignedMemoryAccess = runtime().getHostJVMCIBackend().getTarget().arch.supportsUnalignedMemoryAccess();
-
-    private static final JavaKind VECTOR_KIND = JavaKind.Long;
-    private static final long VECTOR_SIZE = getArrayIndexScale(VECTOR_KIND);
-
-    private static void vectorizedCopy(Object src, int srcPos, Object dest, int destPos, int length, JavaKind baseKind, LocationIdentity locationIdentity) {
-        int arrayBaseOffset = arrayBaseOffset(baseKind);
-        int elementSize = arrayIndexScale(baseKind);
-        long byteLength = (long) length * elementSize;
-        long srcOffset = (long) srcPos * elementSize;
-        long destOffset = (long) destPos * elementSize;
-
-        long preLoopBytes;
-        long mainLoopBytes;
-        long postLoopBytes;
-
-        // We can easily vectorize the loop if both offsets have the same alignment.
-        if (byteLength >= VECTOR_SIZE && (srcOffset % VECTOR_SIZE) == (destOffset % VECTOR_SIZE)) {
-            preLoopBytes = NumUtil.roundUp(arrayBaseOffset + srcOffset, VECTOR_SIZE) - (arrayBaseOffset + srcOffset);
-            postLoopBytes = (byteLength - preLoopBytes) % VECTOR_SIZE;
-            mainLoopBytes = byteLength - preLoopBytes - postLoopBytes;
-        } else {
-            // Does the architecture support unaligned memory accesses?
-            if (supportsUnalignedMemoryAccess) {
-                preLoopBytes = byteLength % VECTOR_SIZE;
-                mainLoopBytes = byteLength - preLoopBytes;
-                postLoopBytes = 0;
-            } else {
-                // No. Let's do element-wise copying.
-                preLoopBytes = byteLength;
-                mainLoopBytes = 0;
-                postLoopBytes = 0;
-            }
-        }
-
-        if (probability(NOT_FREQUENT_PROBABILITY, src == dest) && probability(NOT_FREQUENT_PROBABILITY, srcPos < destPos)) {
-            // bad aliased case
-            srcOffset += byteLength;
-            destOffset += byteLength;
-
-            // Post-loop
-            for (long i = 0; i < postLoopBytes; i += elementSize) {
-                srcOffset -= elementSize;
-                destOffset -= elementSize;
-                UnsafeCopyNode.copy(src, arrayBaseOffset + srcOffset, dest, arrayBaseOffset + destOffset, baseKind, locationIdentity);
-            }
-            // Main-loop
-            for (long i = 0; i < mainLoopBytes; i += VECTOR_SIZE) {
-                srcOffset -= VECTOR_SIZE;
-                destOffset -= VECTOR_SIZE;
-                UnsafeCopyNode.copy(src, arrayBaseOffset + srcOffset, dest, arrayBaseOffset + destOffset, VECTOR_KIND, locationIdentity);
-            }
-            // Pre-loop
-            for (long i = 0; i < preLoopBytes; i += elementSize) {
-                srcOffset -= elementSize;
-                destOffset -= elementSize;
-                UnsafeCopyNode.copy(src, arrayBaseOffset + srcOffset, dest, arrayBaseOffset + destOffset, baseKind, locationIdentity);
-            }
-        } else {
-            // Pre-loop
-            for (long i = 0; i < preLoopBytes; i += elementSize) {
-                UnsafeCopyNode.copy(src, arrayBaseOffset + srcOffset, dest, arrayBaseOffset + destOffset, baseKind, locationIdentity);
-                srcOffset += elementSize;
-                destOffset += elementSize;
-            }
-            // Main-loop
-            for (long i = 0; i < mainLoopBytes; i += VECTOR_SIZE) {
-                UnsafeCopyNode.copy(src, arrayBaseOffset + srcOffset, dest, arrayBaseOffset + destOffset, VECTOR_KIND, locationIdentity);
-                srcOffset += VECTOR_SIZE;
-                destOffset += VECTOR_SIZE;
-            }
-            // Post-loop
-            for (long i = 0; i < postLoopBytes; i += elementSize) {
-                UnsafeCopyNode.copy(src, arrayBaseOffset + srcOffset, dest, arrayBaseOffset + destOffset, baseKind, locationIdentity);
-                srcOffset += elementSize;
-                destOffset += elementSize;
-            }
-        }
-    }
-
-    @Fold
-    static LocationIdentity getArrayLocation(JavaKind kind) {
-        return NamedLocationIdentity.getArrayLocation(kind);
-    }
-
-    @Snippet
-    public static void arraycopyByte(byte[] src, int srcPos, byte[] dest, int destPos, int length) {
-        JavaKind kind = JavaKind.Byte;
-        vectorizedCopy(src, srcPos, dest, destPos, length, kind, getArrayLocation(kind));
-    }
-
-    @Snippet
-    public static void arraycopyBoolean(boolean[] src, int srcPos, boolean[] dest, int destPos, int length) {
-        JavaKind kind = JavaKind.Boolean;
-        vectorizedCopy(src, srcPos, dest, destPos, length, kind, getArrayLocation(kind));
-    }
-
-    @Snippet
-    public static void arraycopyChar(char[] src, int srcPos, char[] dest, int destPos, int length) {
-        JavaKind kind = JavaKind.Char;
-        vectorizedCopy(src, srcPos, dest, destPos, length, kind, getArrayLocation(kind));
-    }
-
-    @Snippet
-    public static void arraycopyShort(short[] src, int srcPos, short[] dest, int destPos, int length) {
-        JavaKind kind = JavaKind.Short;
-        vectorizedCopy(src, srcPos, dest, destPos, length, kind, getArrayLocation(kind));
-    }
-
-    @Snippet
-    public static void arraycopyInt(int[] src, int srcPos, int[] dest, int destPos, int length) {
-        JavaKind kind = JavaKind.Int;
-        vectorizedCopy(src, srcPos, dest, destPos, length, kind, getArrayLocation(kind));
-    }
-
-    @Snippet
-    public static void arraycopyFloat(float[] src, int srcPos, float[] dest, int destPos, int length) {
-        JavaKind kind = JavaKind.Float;
-        vectorizedCopy(src, srcPos, dest, destPos, length, kind, getArrayLocation(kind));
-    }
-
-    @Snippet
-    public static void arraycopyLong(long[] src, int srcPos, long[] dest, int destPos, int length) {
-        JavaKind kind = JavaKind.Long;
-        vectorizedCopy(src, srcPos, dest, destPos, length, kind, getArrayLocation(kind));
-    }
-
-    @Snippet
-    public static void arraycopyDouble(double[] src, int srcPos, double[] dest, int destPos, int length) {
-        JavaKind kind = JavaKind.Double;
-        /*
-         * TODO atomicity problem on 32-bit architectures: The JVM spec requires double values to be
-         * copied atomically, but not long values. For example, on Intel 32-bit this code is not
-         * atomic as long as the vector kind remains Kind.Long.
-         */
-        vectorizedCopy(src, srcPos, dest, destPos, length, kind, getArrayLocation(kind));
-    }
-
-    /**
-     * For this kind, Object, we want to avoid write barriers between writes, but instead have them
-     * at the end of the snippet. This is done by using {@link RawStoreNode}, and rely on
-     * {@link WriteBarrierAdditionPhase} to put write barriers after the {@link UnsafeArrayCopyNode}
-     * with kind Object.
-     */
-    @Snippet
-    public static void arraycopyObject(Object[] src, int srcPos, Object[] dest, int destPos, int length) {
-        JavaKind kind = JavaKind.Object;
-        final int scale = arrayIndexScale(kind);
-        int arrayBaseOffset = arrayBaseOffset(kind);
-        LocationIdentity arrayLocation = getArrayLocation(kind);
-        if (src == dest && srcPos < destPos) { // bad aliased case
-            long start = (long) (length - 1) * scale;
-            for (long i = start; i >= 0; i -= scale) {
-                Object a = RawLoadNode.load(src, arrayBaseOffset + i + (long) srcPos * scale, kind, arrayLocation);
-                RawStoreNode.storeObject(dest, arrayBaseOffset + i + (long) destPos * scale, a, kind, getArrayLocation(kind), false);
-            }
-        } else {
-            long end = (long) length * scale;
-            for (long i = 0; i < end; i += scale) {
-                Object a = RawLoadNode.load(src, arrayBaseOffset + i + (long) srcPos * scale, kind, arrayLocation);
-                RawStoreNode.storeObject(dest, arrayBaseOffset + i + (long) destPos * scale, a, kind, getArrayLocation(kind), false);
-            }
-        }
-    }
-
-    @Snippet
-    public static void arraycopyPrimitive(Object src, int srcPos, Object dest, int destPos, int length, int layoutHelper) {
-        int log2ElementSize = (layoutHelper >> layoutHelperLog2ElementSizeShift(INJECTED_VMCONFIG)) & layoutHelperLog2ElementSizeMask(INJECTED_VMCONFIG);
-        int headerSize = (layoutHelper >> layoutHelperHeaderSizeShift(INJECTED_VMCONFIG)) & layoutHelperHeaderSizeMask(INJECTED_VMCONFIG);
-
-        UnsignedWord vectorSize = WordFactory.unsigned(VECTOR_SIZE);
-        UnsignedWord srcOffset = WordFactory.unsigned(srcPos).shiftLeft(log2ElementSize).add(headerSize);
-        UnsignedWord destOffset = WordFactory.unsigned(destPos).shiftLeft(log2ElementSize).add(headerSize);
-        UnsignedWord destStart = destOffset;
-        UnsignedWord destEnd = destOffset.add(WordFactory.unsigned(length).shiftLeft(log2ElementSize));
-
-        UnsignedWord destVectorEnd = null;
-        UnsignedWord nonVectorBytes = null;
-        UnsignedWord sizeInBytes = WordFactory.unsigned(length).shiftLeft(log2ElementSize);
-        if (supportsUnalignedMemoryAccess) {
-            nonVectorBytes = sizeInBytes.unsignedRemainder(vectorSize);
-            destVectorEnd = destEnd;
-        } else {
-            boolean inPhase = srcOffset.and((int) VECTOR_SIZE - 1).equal(destOffset.and((int) VECTOR_SIZE - 1));
-            boolean hasAtLeastOneVector = sizeInBytes.aboveOrEqual(vectorSize);
-            // We must have at least one full vector, otherwise we must copy each byte separately
-            if (hasAtLeastOneVector && inPhase) { // If in phase, we can vectorize
-                nonVectorBytes = vectorSize.subtract(destStart.unsignedRemainder(vectorSize));
-            } else { // fallback is byte-wise
-                nonVectorBytes = sizeInBytes;
-            }
-            destVectorEnd = destEnd.subtract(destEnd.unsignedRemainder(vectorSize));
-        }
-
-        UnsignedWord destNonVectorEnd = destStart.add(nonVectorBytes);
-        while (destOffset.belowThan(destNonVectorEnd)) {
-            ObjectAccess.writeByte(dest, destOffset, ObjectAccess.readByte(src, srcOffset, any()), any());
-            destOffset = destOffset.add(1);
-            srcOffset = srcOffset.add(1);
-        }
-        // Unsigned destVectorEnd = destEnd.subtract(destEnd.unsignedRemainder(8));
-        while (destOffset.belowThan(destVectorEnd)) {
-            ObjectAccess.writeWord(dest, destOffset, ObjectAccess.readWord(src, srcOffset, any()), any());
-            destOffset = destOffset.add(wordSize());
-            srcOffset = srcOffset.add(wordSize());
-        }
-        // Do the last bytes each when it is required to have absolute alignment.
-        while (!supportsUnalignedMemoryAccess && destOffset.belowThan(destEnd)) {
-            ObjectAccess.writeByte(dest, destOffset, ObjectAccess.readByte(src, srcOffset, any()), any());
-            destOffset = destOffset.add(1);
-            srcOffset = srcOffset.add(1);
-        }
-    }
-
-    public static class Templates extends AbstractTemplates {
-
-        private final SnippetInfo[] arraycopySnippets;
-        private final SnippetInfo genericPrimitiveSnippet;
-
-        public Templates(OptionValues options, Iterable<DebugHandlersFactory> factories, HotSpotProviders providers, TargetDescription target) {
-            super(options, factories, providers, providers.getSnippetReflection(), target);
-
-            arraycopySnippets = new SnippetInfo[JavaKind.values().length];
-            arraycopySnippets[JavaKind.Boolean.ordinal()] = snippet(UnsafeArrayCopySnippets.class, "arraycopyBoolean");
-            arraycopySnippets[JavaKind.Byte.ordinal()] = snippet(UnsafeArrayCopySnippets.class, "arraycopyByte");
-            arraycopySnippets[JavaKind.Short.ordinal()] = snippet(UnsafeArrayCopySnippets.class, "arraycopyShort");
-            arraycopySnippets[JavaKind.Char.ordinal()] = snippet(UnsafeArrayCopySnippets.class, "arraycopyChar");
-            arraycopySnippets[JavaKind.Int.ordinal()] = snippet(UnsafeArrayCopySnippets.class, "arraycopyInt");
-            arraycopySnippets[JavaKind.Long.ordinal()] = snippet(UnsafeArrayCopySnippets.class, "arraycopyLong");
-            arraycopySnippets[JavaKind.Float.ordinal()] = snippet(UnsafeArrayCopySnippets.class, "arraycopyFloat");
-            arraycopySnippets[JavaKind.Double.ordinal()] = snippet(UnsafeArrayCopySnippets.class, "arraycopyDouble");
-            arraycopySnippets[JavaKind.Object.ordinal()] = snippet(UnsafeArrayCopySnippets.class, "arraycopyObject");
-
-            genericPrimitiveSnippet = snippet(UnsafeArrayCopySnippets.class, "arraycopyPrimitive");
-        }
-
-        public void lower(UnsafeArrayCopyNode node, LoweringTool tool) {
-            JavaKind elementKind = node.getElementKind();
-            SnippetInfo snippet;
-            if (elementKind == null) {
-                // primitive array of unknown kind
-                snippet = genericPrimitiveSnippet;
-            } else {
-                snippet = arraycopySnippets[elementKind.ordinal()];
-                assert snippet != null : "arraycopy snippet for " + elementKind.name() + " not found";
-            }
-
-            Arguments args = new Arguments(snippet, node.graph().getGuardsStage(), tool.getLoweringStage());
-            node.addSnippetArguments(args);
-
-            SnippetTemplate template = template(node.getDebug(), args);
-            template.instantiate(providers.getMetaAccess(), node, DEFAULT_REPLACER, args);
-        }
-    }
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/profiling/ProbabilisticProfileSnippets.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/profiling/ProbabilisticProfileSnippets.java	Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -54,6 +54,7 @@
 import org.graalvm.compiler.replacements.SnippetTemplate.SnippetInfo;
 import org.graalvm.compiler.replacements.Snippets;
 
+import jdk.vm.ci.code.CodeUtil;
 import jdk.vm.ci.code.TargetDescription;
 
 public class ProbabilisticProfileSnippets implements Snippets {
@@ -64,22 +65,22 @@
     }
 
     @Snippet
-    public static int notificationMask(int freqLog, int probLog) {
-        int probabilityMask = (1 << probLog) - 1;
+    public static int notificationMask(int freqLog, int probLog, int stepLog) {
         int frequencyMask = (1 << freqLog) - 1;
-        return frequencyMask & ~probabilityMask;
+        int stepMask = (1 << (stepLog + probLog)) - 1;
+        return frequencyMask & ~stepMask;
     }
 
     @NodeIntrinsic(ForeignCallNode.class)
     public static native void methodInvocationEvent(@ConstantNodeParameter ForeignCallDescriptor descriptor, MethodCountersPointer counters);
 
     @Snippet
-    public static void profileMethodEntryWithProbability(MethodCountersPointer counters, int random, @ConstantParameter int freqLog, @ConstantParameter int probLog) {
+    public static void profileMethodEntryWithProbability(MethodCountersPointer counters, int random, int step, int stepLog, @ConstantParameter int freqLog, @ConstantParameter int probLog) {
         if (probability(1.0 / (1 << probLog), shouldProfile(probLog, random))) {
-            int counterValue = counters.readInt(config(INJECTED_VMCONFIG).invocationCounterOffset) + (config(INJECTED_VMCONFIG).invocationCounterIncrement << probLog);
+            int counterValue = counters.readInt(config(INJECTED_VMCONFIG).invocationCounterOffset) + ((config(INJECTED_VMCONFIG).invocationCounterIncrement * step) << probLog);
             counters.writeInt(config(INJECTED_VMCONFIG).invocationCounterOffset, counterValue);
             if (freqLog >= 0) {
-                int mask = notificationMask(freqLog, probLog);
+                int mask = notificationMask(freqLog, probLog, stepLog);
                 if (probability(SLOW_PATH_PROBABILITY, (counterValue & (mask << config(INJECTED_VMCONFIG).invocationCounterShift)) == 0)) {
                     methodInvocationEvent(HotSpotBackend.INVOCATION_EVENT, counters);
                 }
@@ -91,11 +92,12 @@
     public static native void methodBackedgeEvent(@ConstantNodeParameter ForeignCallDescriptor descriptor, MethodCountersPointer counters, int bci, int targetBci);
 
     @Snippet
-    public static void profileBackedgeWithProbability(MethodCountersPointer counters, int random, @ConstantParameter int freqLog, @ConstantParameter int probLog, int bci, int targetBci) {
+    public static void profileBackedgeWithProbability(MethodCountersPointer counters, int random, int step, int stepLog, @ConstantParameter int freqLog, @ConstantParameter int probLog, int bci,
+                    int targetBci) {
         if (probability(1.0 / (1 << probLog), shouldProfile(probLog, random))) {
-            int counterValue = counters.readInt(config(INJECTED_VMCONFIG).backedgeCounterOffset) + (config(INJECTED_VMCONFIG).invocationCounterIncrement << probLog);
+            int counterValue = counters.readInt(config(INJECTED_VMCONFIG).backedgeCounterOffset) + ((config(INJECTED_VMCONFIG).invocationCounterIncrement * step) << probLog);
             counters.writeInt(config(INJECTED_VMCONFIG).backedgeCounterOffset, counterValue);
-            int mask = notificationMask(freqLog, probLog);
+            int mask = notificationMask(freqLog, probLog, stepLog);
             if (probability(SLOW_PATH_PROBABILITY, (counterValue & (mask << config(INJECTED_VMCONFIG).invocationCounterShift)) == 0)) {
                 methodBackedgeEvent(HotSpotBackend.BACKEDGE_EVENT, counters, bci, targetBci);
             }
@@ -103,10 +105,11 @@
     }
 
     @Snippet
-    public static void profileConditionalBackedgeWithProbability(MethodCountersPointer counters, int random, @ConstantParameter int freqLog, @ConstantParameter int probLog, boolean branchCondition,
+    public static void profileConditionalBackedgeWithProbability(MethodCountersPointer counters, int random, int step, int stepLog, @ConstantParameter int freqLog,
+                    @ConstantParameter int probLog, boolean branchCondition,
                     int bci, int targetBci) {
         if (branchCondition) {
-            profileBackedgeWithProbability(counters, random, freqLog, probLog, bci, targetBci);
+            profileBackedgeWithProbability(counters, random, step, stepLog, freqLog, probLog, bci, targetBci);
         }
     }
 
@@ -124,6 +127,8 @@
 
             StructuredGraph graph = profileNode.graph();
             LoadMethodCountersNode counters = graph.unique(new LoadMethodCountersNode(profileNode.getProfiledMethod()));
+            ConstantNode step = ConstantNode.forInt(profileNode.getStep(), graph);
+            ConstantNode stepLog = ConstantNode.forInt(CodeUtil.log2(profileNode.getStep()), graph);
 
             if (profileNode instanceof ProfileBranchNode) {
                 // Backedge event
@@ -132,8 +137,11 @@
                 Arguments args = new Arguments(snippet, graph.getGuardsStage(), tool.getLoweringStage());
                 ConstantNode bci = ConstantNode.forInt(profileBranchNode.bci(), graph);
                 ConstantNode targetBci = ConstantNode.forInt(profileBranchNode.targetBci(), graph);
+
                 args.add("counters", counters);
                 args.add("random", profileBranchNode.getRandom());
+                args.add("step", step);
+                args.add("stepLog", stepLog);
                 args.addConst("freqLog", profileBranchNode.getNotificationFreqLog());
                 args.addConst("probLog", profileBranchNode.getProbabilityLog());
                 if (profileBranchNode.hasCondition()) {
@@ -148,8 +156,11 @@
                 ProfileInvokeNode profileInvokeNode = (ProfileInvokeNode) profileNode;
                 // Method invocation event
                 Arguments args = new Arguments(profileMethodEntryWithProbability, graph.getGuardsStage(), tool.getLoweringStage());
+
                 args.add("counters", counters);
                 args.add("random", profileInvokeNode.getRandom());
+                args.add("step", step);
+                args.add("stepLog", stepLog);
                 args.addConst("freqLog", profileInvokeNode.getNotificationFreqLog());
                 args.addConst("probLog", profileInvokeNode.getProbabilityLog());
                 SnippetTemplate template = template(graph.getDebug(), args);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/profiling/ProfileSnippets.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/profiling/ProfileSnippets.java	Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -54,6 +54,7 @@
 import org.graalvm.compiler.replacements.SnippetTemplate.SnippetInfo;
 import org.graalvm.compiler.replacements.Snippets;
 
+import jdk.vm.ci.code.CodeUtil;
 import jdk.vm.ci.code.TargetDescription;
 
 public class ProfileSnippets implements Snippets {
@@ -61,12 +62,19 @@
     public static native void methodInvocationEvent(@ConstantNodeParameter ForeignCallDescriptor descriptor, MethodCountersPointer counters);
 
     @Snippet
-    public static void profileMethodEntry(MethodCountersPointer counters, @ConstantParameter int freqLog) {
-        int counterValue = counters.readInt(config(INJECTED_VMCONFIG).invocationCounterOffset) + config(INJECTED_VMCONFIG).invocationCounterIncrement;
+    protected static int notificationMask(int freqLog, int stepLog) {
+        int stepMask = (1 << stepLog) - 1;
+        int frequencyMask = (1 << freqLog) - 1;
+        return frequencyMask & ~stepMask;
+    }
+
+    @Snippet
+    public static void profileMethodEntry(MethodCountersPointer counters, int step, int stepLog, @ConstantParameter int freqLog) {
+        int counterValue = counters.readInt(config(INJECTED_VMCONFIG).invocationCounterOffset) + config(INJECTED_VMCONFIG).invocationCounterIncrement * step;
         counters.writeInt(config(INJECTED_VMCONFIG).invocationCounterOffset, counterValue);
         if (freqLog >= 0) {
-            final int frequencyMask = (1 << freqLog) - 1;
-            if (probability(SLOW_PATH_PROBABILITY, (counterValue & (frequencyMask << config(INJECTED_VMCONFIG).invocationCounterShift)) == 0)) {
+            final int mask = notificationMask(freqLog, stepLog);
+            if (probability(SLOW_PATH_PROBABILITY, (counterValue & (mask << config(INJECTED_VMCONFIG).invocationCounterShift)) == 0)) {
                 methodInvocationEvent(HotSpotBackend.INVOCATION_EVENT, counters);
             }
         }
@@ -76,19 +84,19 @@
     public static native void methodBackedgeEvent(@ConstantNodeParameter ForeignCallDescriptor descriptor, MethodCountersPointer counters, int bci, int targetBci);
 
     @Snippet
-    public static void profileBackedge(MethodCountersPointer counters, @ConstantParameter int freqLog, int bci, int targetBci) {
-        int counterValue = counters.readInt(config(INJECTED_VMCONFIG).backedgeCounterOffset) + config(INJECTED_VMCONFIG).invocationCounterIncrement;
+    public static void profileBackedge(MethodCountersPointer counters, int step, int stepLog, @ConstantParameter int freqLog, int bci, int targetBci) {
+        int counterValue = counters.readInt(config(INJECTED_VMCONFIG).backedgeCounterOffset) + config(INJECTED_VMCONFIG).invocationCounterIncrement * step;
         counters.writeInt(config(INJECTED_VMCONFIG).backedgeCounterOffset, counterValue);
-        final int frequencyMask = (1 << freqLog) - 1;
-        if (probability(SLOW_PATH_PROBABILITY, (counterValue & (frequencyMask << config(INJECTED_VMCONFIG).invocationCounterShift)) == 0)) {
+        final int mask = notificationMask(freqLog, stepLog);
+        if (probability(SLOW_PATH_PROBABILITY, (counterValue & (mask << config(INJECTED_VMCONFIG).invocationCounterShift)) == 0)) {
             methodBackedgeEvent(HotSpotBackend.BACKEDGE_EVENT, counters, bci, targetBci);
         }
     }
 
     @Snippet
-    public static void profileConditionalBackedge(MethodCountersPointer counters, @ConstantParameter int freqLog, boolean branchCondition, int bci, int targetBci) {
+    public static void profileConditionalBackedge(MethodCountersPointer counters, int step, int stepLog, @ConstantParameter int freqLog, boolean branchCondition, int bci, int targetBci) {
         if (branchCondition) {
-            profileBackedge(counters, freqLog, bci, targetBci);
+            profileBackedge(counters, step, stepLog, freqLog, bci, targetBci);
         }
     }
 
@@ -104,6 +112,8 @@
         public void lower(ProfileNode profileNode, LoweringTool tool) {
             StructuredGraph graph = profileNode.graph();
             LoadMethodCountersNode counters = graph.unique(new LoadMethodCountersNode(profileNode.getProfiledMethod()));
+            ConstantNode step = ConstantNode.forInt(profileNode.getStep(), graph);
+            ConstantNode stepLog = ConstantNode.forInt(CodeUtil.log2(profileNode.getStep()), graph);
 
             if (profileNode instanceof ProfileBranchNode) {
                 // Backedge event
@@ -113,6 +123,8 @@
                 ConstantNode bci = ConstantNode.forInt(profileBranchNode.bci(), graph);
                 ConstantNode targetBci = ConstantNode.forInt(profileBranchNode.targetBci(), graph);
                 args.add("counters", counters);
+                args.add("step", step);
+                args.add("stepLog", stepLog);
                 args.addConst("freqLog", profileBranchNode.getNotificationFreqLog());
                 if (profileBranchNode.hasCondition()) {
                     args.add("branchCondition", profileBranchNode.branchCondition());
@@ -127,6 +139,8 @@
                 // Method invocation event
                 Arguments args = new Arguments(profileMethodEntry, graph.getGuardsStage(), tool.getLoweringStage());
                 args.add("counters", counters);
+                args.add("step", step);
+                args.add("stepLog", stepLog);
                 args.addConst("freqLog", profileInvokeNode.getNotificationFreqLog());
                 SnippetTemplate template = template(graph.getDebug(), args);
                 template.instantiate(providers.getMetaAccess(), profileNode, DEFAULT_REPLACER, args);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/NewArrayStub.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/NewArrayStub.java	Wed Nov 08 16:03:35 2017 -0500
@@ -33,6 +33,7 @@
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.layoutHelperLog2ElementSizeShift;
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.readLayoutHelper;
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.registerAsWord;
+import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.useCMSIncrementalMode;
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.wordSize;
 import static org.graalvm.compiler.hotspot.replacements.NewObjectSnippets.MAX_ARRAY_FAST_PATH_ALLOCATION_LENGTH;
 import static org.graalvm.compiler.hotspot.replacements.NewObjectSnippets.formatArray;
@@ -122,7 +123,7 @@
         // check that array length is small enough for fast path.
         Word thread = registerAsWord(threadRegister);
         boolean inlineContiguousAllocationSupported = GraalHotSpotVMConfigNode.inlineContiguousAllocationSupported();
-        if (inlineContiguousAllocationSupported && length >= 0 && length <= MAX_ARRAY_FAST_PATH_ALLOCATION_LENGTH) {
+        if (inlineContiguousAllocationSupported && !useCMSIncrementalMode(INJECTED_VMCONFIG) && length >= 0 && length <= MAX_ARRAY_FAST_PATH_ALLOCATION_LENGTH) {
             Word memory = refillAllocate(thread, intArrayHub, sizeInBytes, logging(options));
             if (memory.notEqual(0)) {
                 if (logging(options)) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/NewInstanceStub.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/NewInstanceStub.java	Wed Nov 08 16:03:35 2017 -0500
@@ -53,6 +53,7 @@
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.tlabRefillWasteLimitOffset;
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.tlabSlowAllocationsOffset;
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.tlabStats;
+import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.useCMSIncrementalMode;
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.useG1GC;
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.useTLAB;
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.wordSize;
@@ -147,7 +148,7 @@
          */
         Word thread = registerAsWord(threadRegister);
         boolean inlineContiguousAllocationSupported = GraalHotSpotVMConfigNode.inlineContiguousAllocationSupported();
-        if (!forceSlowPath(options) && inlineContiguousAllocationSupported) {
+        if (!forceSlowPath(options) && inlineContiguousAllocationSupported && !useCMSIncrementalMode(INJECTED_VMCONFIG)) {
             if (isInstanceKlassFullyInitialized(hub)) {
                 int sizeInBytes = readLayoutHelper(hub);
                 Word memory = refillAllocate(thread, intArrayHub, sizeInBytes, logging(options));
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParser.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParser.java	Wed Nov 08 16:03:35 2017 -0500
@@ -342,7 +342,7 @@
 import org.graalvm.compiler.nodes.calc.AndNode;
 import org.graalvm.compiler.nodes.calc.CompareNode;
 import org.graalvm.compiler.nodes.calc.ConditionalNode;
-import org.graalvm.compiler.nodes.calc.DivNode;
+import org.graalvm.compiler.nodes.calc.FloatDivNode;
 import org.graalvm.compiler.nodes.calc.FloatConvertNode;
 import org.graalvm.compiler.nodes.calc.IntegerBelowNode;
 import org.graalvm.compiler.nodes.calc.IntegerEqualsNode;
@@ -374,7 +374,6 @@
 import org.graalvm.compiler.nodes.extended.StateSplitProxyNode;
 import org.graalvm.compiler.nodes.extended.ValueAnchorNode;
 import org.graalvm.compiler.nodes.graphbuilderconf.ClassInitializationPlugin;
-import org.graalvm.compiler.nodes.graphbuilderconf.InvokeDynamicPlugin;
 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration;
 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.BytecodeExceptionMode;
 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext;
@@ -383,6 +382,7 @@
 import org.graalvm.compiler.nodes.graphbuilderconf.IntrinsicContext;
 import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin;
 import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.InvocationPluginReceiver;
+import org.graalvm.compiler.nodes.graphbuilderconf.InvokeDynamicPlugin;
 import org.graalvm.compiler.nodes.graphbuilderconf.NodePlugin;
 import org.graalvm.compiler.nodes.graphbuilderconf.ProfilingPlugin;
 import org.graalvm.compiler.nodes.java.ArrayLengthNode;
@@ -435,6 +435,7 @@
 import jdk.vm.ci.meta.ResolvedJavaType;
 import jdk.vm.ci.meta.Signature;
 import jdk.vm.ci.meta.TriState;
+import org.graalvm.compiler.core.common.type.IntegerStamp;
 
 /**
  * The {@code GraphBuilder} class parses the bytecode of a method and builds the IR graph.
@@ -1036,7 +1037,7 @@
         deopt.updateNodeSourcePosition(() -> createBytecodePosition());
     }
 
-    private AbstractBeginNode handleException(ValueNode exceptionObject, int bci) {
+    private AbstractBeginNode handleException(ValueNode exceptionObject, int bci, boolean deoptimizeOnly) {
         assert bci == BytecodeFrame.BEFORE_BCI || bci == bci() : "invalid bci";
         debug.log("Creating exception dispatch edges at %d, exception object=%s, exception seen=%s", bci, exceptionObject, (profilingInfo == null ? "" : profilingInfo.getExceptionSeen(bci)));
 
@@ -1058,8 +1059,12 @@
         this.controlFlowSplit = true;
         FixedWithNextNode finishedDispatch = finishInstruction(dispatchBegin, dispatchState);
 
-        createHandleExceptionTarget(finishedDispatch, bci, dispatchState);
-
+        if (deoptimizeOnly) {
+            DeoptimizeNode deoptimizeNode = graph.add(new DeoptimizeNode(DeoptimizationAction.None, DeoptimizationReason.TransferToInterpreter));
+            dispatchBegin.setNext(BeginNode.begin(deoptimizeNode));
+        } else {
+            createHandleExceptionTarget(finishedDispatch, bci, dispatchState);
+        }
         return dispatchBegin;
     }
 
@@ -1111,7 +1116,7 @@
     }
 
     protected ValueNode genFloatDiv(ValueNode x, ValueNode y) {
-        return DivNode.create(x, y);
+        return FloatDivNode.create(x, y);
     }
 
     protected ValueNode genFloatRem(ValueNode x, ValueNode y) {
@@ -1215,7 +1220,7 @@
         ValueNode exception = frameState.pop(JavaKind.Object);
         FixedGuardNode nullCheck = append(new FixedGuardNode(graph.addOrUniqueWithInputs(IsNullNode.create(exception)), NullCheckException, InvalidateReprofile, true));
         ValueNode nonNullException = graph.maybeAddOrUnique(PiNode.create(exception, exception.stamp().join(objectNonNull()), nullCheck));
-        lastInstr.setNext(handleException(nonNullException, bci()));
+        lastInstr.setNext(handleException(nonNullException, bci(), false));
     }
 
     protected LogicNode createInstanceOf(TypeReference type, ValueNode object) {
@@ -1275,12 +1280,12 @@
         }
         BytecodeExceptionNode exception = graph.add(new BytecodeExceptionNode(metaAccess, NullPointerException.class));
         AbstractBeginNode falseSucc = graph.add(new BeginNode());
-        ValueNode nonNullReceiver = graph.addOrUnique(PiNode.create(receiver, objectNonNull(), falseSucc));
+        ValueNode nonNullReceiver = graph.addOrUniqueWithInputs(PiNode.create(receiver, objectNonNull(), falseSucc));
         append(new IfNode(graph.addOrUniqueWithInputs(IsNullNode.create(receiver)), exception, falseSucc, SLOW_PATH_PROBABILITY));
         lastInstr = falseSucc;
 
         exception.setStateAfter(createFrameState(bci(), exception));
-        exception.setNext(handleException(exception, bci()));
+        exception.setNext(handleException(exception, bci(), false));
         EXPLICIT_EXCEPTIONS.increment(debug);
         return nonNullReceiver;
     }
@@ -1292,7 +1297,7 @@
         lastInstr = trueSucc;
 
         exception.setStateAfter(createFrameState(bci(), exception));
-        exception.setNext(handleException(exception, bci()));
+        exception.setNext(handleException(exception, bci(), false));
     }
 
     protected ValueNode genArrayLength(ValueNode x) {
@@ -1532,8 +1537,8 @@
     @Override
     public void handleReplacedInvoke(CallTargetNode callTarget, JavaKind resultType) {
         BytecodeParser intrinsicCallSiteParser = getNonIntrinsicAncestor();
-        boolean withExceptionEdge = intrinsicCallSiteParser == null ? !omitInvokeExceptionEdge(null) : !intrinsicCallSiteParser.omitInvokeExceptionEdge(null);
-        createNonInlinedInvoke(withExceptionEdge, bci(), callTarget, resultType);
+        ExceptionEdgeAction exceptionEdgeAction = intrinsicCallSiteParser == null ? getActionForInvokeExceptionEdge(null) : intrinsicCallSiteParser.getActionForInvokeExceptionEdge(null);
+        createNonInlinedInvoke(exceptionEdgeAction, bci(), callTarget, resultType);
     }
 
     protected Invoke appendInvoke(InvokeKind initialInvokeKind, ResolvedJavaMethod initialTargetMethod, ValueNode[] args) {
@@ -1603,7 +1608,7 @@
 
         int invokeBci = bci();
         JavaTypeProfile profile = getProfileForInvoke(invokeKind);
-        boolean withExceptionEdge = !omitInvokeExceptionEdge(inlineInfo);
+        ExceptionEdgeAction edgeAction = getActionForInvokeExceptionEdge(inlineInfo);
         boolean partialIntrinsicExit = false;
         if (intrinsicContext != null && intrinsicContext.isCallToOriginal(targetMethod)) {
             partialIntrinsicExit = true;
@@ -1614,7 +1619,7 @@
                 // must use the same context as the call to the intrinsic.
                 invokeBci = intrinsicCallSiteParser.bci();
                 profile = intrinsicCallSiteParser.getProfileForInvoke(invokeKind);
-                withExceptionEdge = !intrinsicCallSiteParser.omitInvokeExceptionEdge(inlineInfo);
+                edgeAction = intrinsicCallSiteParser.getActionForInvokeExceptionEdge(inlineInfo);
             } else {
                 // We are parsing the intrinsic for the root compilation or for inlining,
                 // This call is a partial intrinsic exit, and we do not have profile information
@@ -1624,7 +1629,7 @@
                 assert intrinsicContext.isPostParseInlined();
                 invokeBci = BytecodeFrame.UNKNOWN_BCI;
                 profile = null;
-                withExceptionEdge = graph.method().getAnnotation(Snippet.class) == null;
+                edgeAction = graph.method().getAnnotation(Snippet.class) == null ? ExceptionEdgeAction.INCLUDE_AND_HANDLE : ExceptionEdgeAction.OMIT;
             }
 
             if (originalMethod.isStatic()) {
@@ -1637,10 +1642,10 @@
             Signature sig = originalMethod.getSignature();
             returnType = sig.getReturnType(method.getDeclaringClass());
             resultType = sig.getReturnKind();
-            assert checkPartialIntrinsicExit(intrinsicCallSiteParser == null ? null : intrinsicCallSiteParser.currentInvoke.args, args);
+            assert intrinsicContext.allowPartialIntrinsicArgumentMismatch() || checkPartialIntrinsicExit(intrinsicCallSiteParser == null ? null : intrinsicCallSiteParser.currentInvoke.args, args);
             targetMethod = originalMethod;
         }
-        Invoke invoke = createNonInlinedInvoke(withExceptionEdge, invokeBci, args, targetMethod, invokeKind, resultType, returnType, profile);
+        Invoke invoke = createNonInlinedInvoke(edgeAction, invokeBci, args, targetMethod, invokeKind, resultType, returnType, profile);
         if (partialIntrinsicExit) {
             // This invoke must never be later inlined as it might select the intrinsic graph.
             // Until there is a mechanism to guarantee that any late inlining will not select
@@ -1698,14 +1703,14 @@
         } else {
             for (int i = 0; i < recursiveArgs.length; i++) {
                 ValueNode arg = GraphUtil.unproxify(recursiveArgs[i]);
-                assert arg instanceof ParameterNode && ((ParameterNode) arg).index() == i : String.format("argument %d of call denoting partial intrinsic exit should be a %s with index %d, not %s", i,
-                                ParameterNode.class.getSimpleName(), i, arg);
+                assert arg instanceof ParameterNode && ((ParameterNode) arg).index() == i : String.format("argument %d of call denoting partial intrinsic exit should be a %s with index %d, not %s",
+                                i, ParameterNode.class.getSimpleName(), i, arg);
             }
         }
         return true;
     }
 
-    protected Invoke createNonInlinedInvoke(boolean withExceptionEdge, int invokeBci, ValueNode[] invokeArgs, ResolvedJavaMethod targetMethod,
+    protected Invoke createNonInlinedInvoke(ExceptionEdgeAction exceptionEdge, int invokeBci, ValueNode[] invokeArgs, ResolvedJavaMethod targetMethod,
                     InvokeKind invokeKind, JavaKind resultType, JavaType returnType, JavaTypeProfile profile) {
 
         StampPair returnStamp = graphBuilderConfig.getPlugins().getOverridingStamp(this, returnType, false);
@@ -1714,7 +1719,7 @@
         }
 
         MethodCallTargetNode callTarget = graph.add(createMethodCallTarget(invokeKind, targetMethod, invokeArgs, returnStamp, profile));
-        Invoke invoke = createNonInlinedInvoke(withExceptionEdge, invokeBci, callTarget, resultType);
+        Invoke invoke = createNonInlinedInvoke(exceptionEdge, invokeBci, callTarget, resultType);
 
         for (InlineInvokePlugin plugin : graphBuilderConfig.getPlugins().getInlineInvokePlugins()) {
             plugin.notifyNotInlined(this, targetMethod, invoke);
@@ -1723,11 +1728,11 @@
         return invoke;
     }
 
-    protected Invoke createNonInlinedInvoke(boolean withExceptionEdge, int invokeBci, CallTargetNode callTarget, JavaKind resultType) {
-        if (!withExceptionEdge) {
+    protected Invoke createNonInlinedInvoke(ExceptionEdgeAction exceptionEdge, int invokeBci, CallTargetNode callTarget, JavaKind resultType) {
+        if (exceptionEdge == ExceptionEdgeAction.OMIT) {
             return createInvoke(invokeBci, callTarget, resultType);
         } else {
-            Invoke invoke = createInvokeWithException(invokeBci, callTarget, resultType);
+            Invoke invoke = createInvokeWithException(invokeBci, callTarget, resultType, exceptionEdge);
             AbstractBeginNode beginNode = graph.add(KillingBeginNode.create(LocationIdentity.any()));
             invoke.setNext(beginNode);
             lastInstr = beginNode;
@@ -1736,20 +1741,29 @@
     }
 
     /**
-     * If the method returns true, the invocation of the given {@link MethodCallTargetNode call
-     * target} does not need an exception edge.
+     * Describes what should be done with the exception edge of an invocation. The edge can be
+     * omitted or included. An included edge can handle the exception or transfer execution to the
+     * interpreter for handling (deoptimize).
      */
-    protected boolean omitInvokeExceptionEdge(InlineInfo lastInlineInfo) {
+    protected enum ExceptionEdgeAction {
+        OMIT,
+        INCLUDE_AND_HANDLE,
+        INCLUDE_AND_DEOPTIMIZE
+    }
+
+    protected ExceptionEdgeAction getActionForInvokeExceptionEdge(InlineInfo lastInlineInfo) {
         if (lastInlineInfo == InlineInfo.DO_NOT_INLINE_WITH_EXCEPTION) {
-            return false;
+            return ExceptionEdgeAction.INCLUDE_AND_HANDLE;
         } else if (lastInlineInfo == InlineInfo.DO_NOT_INLINE_NO_EXCEPTION) {
-            return true;
+            return ExceptionEdgeAction.OMIT;
+        } else if (lastInlineInfo == InlineInfo.DO_NOT_INLINE_DEOPTIMIZE_ON_EXCEPTION) {
+            return ExceptionEdgeAction.INCLUDE_AND_DEOPTIMIZE;
         } else if (graphBuilderConfig.getBytecodeExceptionMode() == BytecodeExceptionMode.CheckAll) {
-            return false;
+            return ExceptionEdgeAction.INCLUDE_AND_HANDLE;
         } else if (graphBuilderConfig.getBytecodeExceptionMode() == BytecodeExceptionMode.ExplicitOnly) {
-            return false;
+            return ExceptionEdgeAction.INCLUDE_AND_HANDLE;
         } else if (graphBuilderConfig.getBytecodeExceptionMode() == BytecodeExceptionMode.OmitAll) {
-            return true;
+            return ExceptionEdgeAction.OMIT;
         } else {
             assert graphBuilderConfig.getBytecodeExceptionMode() == BytecodeExceptionMode.Profile;
             // be conservative if information was not recorded (could result in endless
@@ -1759,12 +1773,12 @@
                     if (profilingInfo != null) {
                         TriState exceptionSeen = profilingInfo.getExceptionSeen(bci());
                         if (exceptionSeen == TriState.FALSE) {
-                            return true;
+                            return ExceptionEdgeAction.OMIT;
                         }
                     }
                 }
             }
-            return false;
+            return ExceptionEdgeAction.INCLUDE_AND_HANDLE;
         }
     }
 
@@ -1887,7 +1901,7 @@
                     if (newProfile != profile) {
                         if (newProfile.getTypes().length == 0) {
                             // All profiled types select the intrinsic so
-                            // emit a fixed guard instead of a if-then-else.
+                            // emit a fixed guard instead of an if-then-else.
                             lastInstr = append(new FixedGuardNode(compare, TypeCheckedInliningViolated, InvalidateReprofile, false));
                             return new IntrinsicGuard(currentLastInstr, intrinsicReceiver, mark, null, null);
                         }
@@ -1966,7 +1980,7 @@
                     }
 
                     lastInstr = intrinsicGuard.nonIntrinsicBranch;
-                    createNonInlinedInvoke(omitInvokeExceptionEdge(null), bci(), args, targetMethod, invokeKind, resultType, returnType, intrinsicGuard.profile);
+                    createNonInlinedInvoke(getActionForInvokeExceptionEdge(null), bci(), args, targetMethod, invokeKind, resultType, returnType, intrinsicGuard.profile);
 
                     EndNode nonIntrinsicEnd = append(new EndNode());
                     AbstractMergeNode mergeNode = graph.add(new MergeNode());
@@ -2303,7 +2317,7 @@
             if (calleeBeforeUnwindNode != null) {
                 ValueNode calleeUnwindValue = parser.getUnwindValue();
                 assert calleeUnwindValue != null;
-                calleeBeforeUnwindNode.setNext(handleException(calleeUnwindValue, bci()));
+                calleeBeforeUnwindNode.setNext(handleException(calleeUnwindValue, bci(), false));
             }
         }
     }
@@ -2319,7 +2333,7 @@
         return invoke;
     }
 
-    protected InvokeWithExceptionNode createInvokeWithException(int invokeBci, CallTargetNode callTarget, JavaKind resultType) {
+    protected InvokeWithExceptionNode createInvokeWithException(int invokeBci, CallTargetNode callTarget, JavaKind resultType, ExceptionEdgeAction exceptionEdgeAction) {
         if (currentBlock != null && stream.nextBCI() > currentBlock.endBci) {
             /*
              * Clear non-live locals early so that the exception handler entry gets the cleared
@@ -2328,7 +2342,7 @@
             frameState.clearNonLiveLocals(currentBlock, liveness, false);
         }
 
-        AbstractBeginNode exceptionEdge = handleException(null, bci());
+        AbstractBeginNode exceptionEdge = handleException(null, bci(), exceptionEdgeAction == ExceptionEdgeAction.INCLUDE_AND_DEOPTIMIZE);
         InvokeWithExceptionNode invoke = append(new InvokeWithExceptionNode(callTarget, exceptionEdge, invokeBci));
         frameState.pushReturn(resultType, invoke);
         invoke.setStateAfter(createFrameState(stream.nextBCI(), invoke));
@@ -2359,20 +2373,43 @@
             }
         }
 
+        ValueNode realReturnVal = processReturnValue(returnVal, returnKind);
+
         frameState.setRethrowException(false);
         frameState.clearStack();
-        beforeReturn(returnVal, returnKind);
+        beforeReturn(realReturnVal, returnKind);
         if (parent == null) {
-            append(new ReturnNode(returnVal));
+            append(new ReturnNode(realReturnVal));
         } else {
             if (returnDataList == null) {
                 returnDataList = new ArrayList<>();
             }
-            returnDataList.add(new ReturnToCallerData(returnVal, lastInstr));
+            returnDataList.add(new ReturnToCallerData(realReturnVal, lastInstr));
             lastInstr = null;
         }
     }
 
+    private ValueNode processReturnValue(ValueNode value, JavaKind kind) {
+        JavaKind returnKind = method.getSignature().getReturnKind();
+        if (kind != returnKind) {
+            // sub-word integer
+            assert returnKind.isNumericInteger() && returnKind.getStackKind() == JavaKind.Int;
+            IntegerStamp stamp = (IntegerStamp) value.stamp();
+
+            // the bytecode verifier doesn't check that the value is in the correct range
+            if (stamp.lowerBound() < returnKind.getMinValue() || returnKind.getMaxValue() < stamp.upperBound()) {
+                ValueNode narrow = append(genNarrow(value, returnKind.getBitCount()));
+                if (returnKind.isUnsigned()) {
+                    return append(genZeroExtend(narrow, 32));
+                } else {
+                    return append(genSignExtend(narrow, 32));
+                }
+            }
+        }
+
+        return value;
+    }
+
     private void beforeReturn(ValueNode x, JavaKind kind) {
         if (graph.method() != null && graph.method().isJavaLangObjectInit()) {
             /*
@@ -2794,6 +2831,8 @@
     }
 
     private void createExceptionDispatch(ExceptionDispatchBlock block) {
+        lastInstr = finishInstruction(lastInstr, frameState);
+
         assert frameState.stackSize() == 1 : frameState;
         if (block.handler.isCatchAll()) {
             assert block.getSuccessorCount() == 1;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/FrameStateBuilder.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/FrameStateBuilder.java	Wed Nov 08 16:03:35 2017 -0500
@@ -207,7 +207,7 @@
                 receiver = new ParameterNode(javaIndex, receiverStamp);
             }
 
-            locals[javaIndex] = graph.addOrUnique(receiver);
+            locals[javaIndex] = graph.addOrUniqueWithInputs(receiver);
             javaIndex = 1;
             index = 1;
         }
@@ -241,7 +241,7 @@
                 param = new ParameterNode(index, stamp);
             }
 
-            locals[javaIndex] = graph.addOrUnique(param);
+            locals[javaIndex] = graph.addOrUniqueWithInputs(param);
             javaIndex++;
             if (kind.needsTwoSlots()) {
                 locals[javaIndex] = TWO_SLOT_MARKER;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/optimize/ConditionalElimination02.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/optimize/ConditionalElimination02.java	Wed Nov 08 16:03:35 2017 -0500
@@ -29,6 +29,9 @@
 import org.junit.Test;
 
 import org.graalvm.compiler.jtt.JTTTest;
+import org.graalvm.compiler.phases.OptimisticOptimizations;
+import org.graalvm.compiler.phases.OptimisticOptimizations.Optimization;
+import org.graalvm.compiler.phases.tiers.HighTierContext;
 
 public class ConditionalElimination02 extends JTTTest {
 
@@ -59,6 +62,14 @@
         return -1;
     }
 
+    /**
+     * These tests assume all code paths are reachable so disable profile based dead code removal.
+     */
+    @Override
+    protected HighTierContext getDefaultHighTierContext() {
+        return new HighTierContext(getProviders(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL.remove(Optimization.RemoveNeverExecutedCode));
+    }
+
     @Test
     public void run0() throws Throwable {
         runTest(EnumSet.of(DeoptimizationReason.NullCheckException), "test", new A(5), false, false);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/optimize/Fold_Double04.java	Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 org.graalvm.compiler.jtt.optimize;
+
+import org.junit.Test;
+
+import org.graalvm.compiler.jtt.JTTTest;
+
+/*
+ * Tests constant folding of double operations.
+ */
+public class Fold_Double04 extends JTTTest {
+
+    // Contrived check whether both arguments are the same kind of zero
+    public static boolean test(double x, double y) {
+        if (x == 0) {
+            if (1 / x == Double.NEGATIVE_INFINITY) {
+                return 1 / y == Double.NEGATIVE_INFINITY;
+            } else {
+                return 1 / y == Double.POSITIVE_INFINITY;
+            }
+        }
+        return false;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        runTest("test", -0d, -0d);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        runTest("test", -0d, 0d);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        runTest("test", 0d, -0d);
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        runTest("test", 0d, 0d);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/optimize/Fold_Float03.java	Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 org.graalvm.compiler.jtt.optimize;
+
+import org.junit.Test;
+
+import org.graalvm.compiler.jtt.JTTTest;
+
+/*
+ * Tests constant folding of float operations.
+ */
+public class Fold_Float03 extends JTTTest {
+
+    // Contrived check whether both arguments are the same kind of zero
+    public static boolean test(float x, float y) {
+        if (x == 0) {
+            if (1 / x == Float.NEGATIVE_INFINITY) {
+                return 1 / y == Float.NEGATIVE_INFINITY;
+            } else {
+                return 1 / y == Float.POSITIVE_INFINITY;
+            }
+        }
+        return false;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        runTest("test", -0f, -0f);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        runTest("test", -0f, 0f);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        runTest("test", 0f, -0f);
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        runTest("test", 0f, 0f);
+    }
+
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ArrayEqualsOp.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ArrayEqualsOp.java	Wed Nov 08 16:03:35 2017 -0500
@@ -37,6 +37,7 @@
 import org.graalvm.compiler.asm.amd64.AMD64Assembler.SSEOp;
 import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler;
 import org.graalvm.compiler.core.common.LIRKind;
+import org.graalvm.compiler.core.common.NumUtil;
 import org.graalvm.compiler.lir.LIRInstructionClass;
 import org.graalvm.compiler.lir.Opcode;
 import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
@@ -132,12 +133,19 @@
         masm.leaq(array2, new AMD64Address(asRegister(array2Value), arrayBaseOffset));
 
         // Get array length in bytes.
-        masm.imull(length, asRegister(lengthValue), arrayIndexScale);
+        masm.movl(length, asRegister(lengthValue));
+
+        if (arrayIndexScale > 1) {
+            masm.shll(length, NumUtil.log2Ceil(arrayIndexScale)); // scale length
+        }
+
         masm.movl(result, length); // copy
 
         if (supportsAVX2(crb.target)) {
             emitAVXCompare(crb, masm, result, array1, array2, length, trueLabel, falseLabel);
         } else if (supportsSSE41(crb.target)) {
+            // this code is used for AVX as well because our backend correctly ensures that
+            // VEX-prefixed instructions are emitted if AVX is supported
             emitSSE41Compare(crb, masm, result, array1, array2, length, trueLabel, falseLabel);
         }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ControlFlow.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ControlFlow.java	Wed Nov 08 16:03:35 2017 -0500
@@ -22,21 +22,21 @@
  */
 package org.graalvm.compiler.lir.amd64;
 
+import static jdk.vm.ci.code.ValueUtil.asRegister;
+import static jdk.vm.ci.code.ValueUtil.isRegister;
 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.CONST;
 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.HINT;
 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.ILLEGAL;
 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG;
 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.STACK;
-import static jdk.vm.ci.code.ValueUtil.asRegister;
-import static jdk.vm.ci.code.ValueUtil.isRegister;
 
 import org.graalvm.compiler.asm.Label;
-import org.graalvm.compiler.core.common.NumUtil;
 import org.graalvm.compiler.asm.amd64.AMD64Address;
 import org.graalvm.compiler.asm.amd64.AMD64Address.Scale;
 import org.graalvm.compiler.asm.amd64.AMD64Assembler.ConditionFlag;
 import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler;
 import org.graalvm.compiler.code.CompilationResult.JumpTable;
+import org.graalvm.compiler.core.common.NumUtil;
 import org.graalvm.compiler.core.common.calc.Condition;
 import org.graalvm.compiler.debug.GraalError;
 import org.graalvm.compiler.lir.LIRInstructionClass;
@@ -312,6 +312,42 @@
         }
     }
 
+    @Opcode("SETcc")
+    public static final class CondSetOp extends AMD64LIRInstruction {
+        public static final LIRInstructionClass<CondSetOp> TYPE = LIRInstructionClass.create(CondSetOp.class);
+        @Def({REG, HINT}) protected Value result;
+        private final ConditionFlag condition;
+
+        public CondSetOp(Variable result, Condition condition) {
+            super(TYPE);
+            this.result = result;
+            this.condition = intCond(condition);
+        }
+
+        @Override
+        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+            setcc(masm, result, condition);
+        }
+    }
+
+    @Opcode("SETcc")
+    public static final class FloatCondSetOp extends AMD64LIRInstruction {
+        public static final LIRInstructionClass<FloatCondSetOp> TYPE = LIRInstructionClass.create(FloatCondSetOp.class);
+        @Def({REG, HINT}) protected Value result;
+        private final ConditionFlag condition;
+
+        public FloatCondSetOp(Variable result, Condition condition) {
+            super(TYPE);
+            this.result = result;
+            this.condition = floatCond(condition);
+        }
+
+        @Override
+        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+            setcc(masm, result, condition);
+        }
+    }
+
     @Opcode("CMOVE")
     public static final class CondMoveOp extends AMD64LIRInstruction {
         public static final LIRInstructionClass<CondMoveOp> TYPE = LIRInstructionClass.create(CondMoveOp.class);
@@ -418,6 +454,21 @@
         }
     }
 
+    private static void setcc(AMD64MacroAssembler masm, Value result, ConditionFlag cond) {
+        switch ((AMD64Kind) result.getPlatformKind()) {
+            case BYTE:
+            case WORD:
+            case DWORD:
+                masm.setl(cond, asRegister(result));
+                break;
+            case QWORD:
+                masm.setq(cond, asRegister(result));
+                break;
+            default:
+                throw GraalError.shouldNotReachHere();
+        }
+    }
+
     private static ConditionFlag intCond(Condition cond) {
         switch (cond) {
             case EQ:
@@ -464,6 +515,10 @@
         }
     }
 
+    public static boolean trueOnUnordered(Condition condition) {
+        return trueOnUnordered(floatCond(condition));
+    }
+
     private static boolean trueOnUnordered(ConditionFlag condition) {
         switch (condition) {
             case AboveEqual:
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64Move.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64Move.java	Wed Nov 08 16:03:35 2017 -0500
@@ -22,8 +22,11 @@
  */
 package org.graalvm.compiler.lir.amd64;
 
+import static org.graalvm.compiler.asm.amd64.AMD64Assembler.ConditionFlag.Equal;
+import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC;
 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.COMPOSITE;
 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.HINT;
+import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.ILLEGAL;
 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG;
 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.STACK;
 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.UNINITIALIZED;
@@ -35,12 +38,16 @@
 import static jdk.vm.ci.code.ValueUtil.isRegister;
 import static jdk.vm.ci.code.ValueUtil.isStackSlot;
 
+import org.graalvm.compiler.asm.Label;
+import org.graalvm.compiler.core.common.CompressEncoding;
+import org.graalvm.compiler.core.common.LIRKind;
 import org.graalvm.compiler.core.common.NumUtil;
 import org.graalvm.compiler.asm.amd64.AMD64Address;
 import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64MIOp;
 import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64MOp;
 import org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize;
 import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler;
+import org.graalvm.compiler.core.common.spi.LIRKindTool;
 import org.graalvm.compiler.core.common.type.DataPointerConstant;
 import org.graalvm.compiler.debug.GraalError;
 import org.graalvm.compiler.lir.LIRFrameState;
@@ -740,4 +747,110 @@
                 throw GraalError.shouldNotReachHere("Unknown result Kind: " + result.getPlatformKind());
         }
     }
+
+    public abstract static class Pointer extends AMD64LIRInstruction {
+        protected final LIRKindTool lirKindTool;
+        protected final CompressEncoding encoding;
+        protected final boolean nonNull;
+
+        @Def({REG, HINT}) private AllocatableValue result;
+        @Use({REG}) private AllocatableValue input;
+        @Alive({REG, ILLEGAL}) private AllocatableValue baseRegister;
+
+        protected Pointer(LIRInstructionClass<? extends Pointer> type, AllocatableValue result, AllocatableValue input, AllocatableValue baseRegister, CompressEncoding encoding, boolean nonNull,
+                        LIRKindTool lirKindTool) {
+            super(type);
+            this.result = result;
+            this.input = input;
+            this.baseRegister = baseRegister;
+            this.encoding = encoding;
+            this.nonNull = nonNull;
+            this.lirKindTool = lirKindTool;
+        }
+
+        protected boolean hasBase(CompilationResultBuilder crb) {
+            return GeneratePIC.getValue(crb.getOptions()) || encoding.hasBase();
+        }
+
+        protected final Register getResultRegister() {
+            return asRegister(result);
+        }
+
+        protected final Register getBaseRegister() {
+            return asRegister(baseRegister);
+        }
+
+        protected final int getShift() {
+            return encoding.getShift();
+        }
+
+        protected final void move(LIRKind kind, CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+            AMD64Move.move((AMD64Kind) kind.getPlatformKind(), crb, masm, result, input);
+        }
+    }
+
+    public static final class CompressPointer extends Pointer {
+        public static final LIRInstructionClass<CompressPointer> TYPE = LIRInstructionClass.create(CompressPointer.class);
+
+        public CompressPointer(AllocatableValue result, AllocatableValue input, AllocatableValue baseRegister, CompressEncoding encoding, boolean nonNull, LIRKindTool lirKindTool) {
+            super(TYPE, result, input, baseRegister, encoding, nonNull, lirKindTool);
+        }
+
+        @Override
+        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+            move(lirKindTool.getObjectKind(), crb, masm);
+
+            Register resReg = getResultRegister();
+            if (hasBase(crb)) {
+                Register baseReg = getBaseRegister();
+                if (!nonNull) {
+                    masm.testq(resReg, resReg);
+                    masm.cmovq(Equal, resReg, baseReg);
+                }
+                masm.subq(resReg, baseReg);
+            }
+
+            int shift = getShift();
+            if (shift != 0) {
+                masm.shrq(resReg, shift);
+            }
+        }
+    }
+
+    public static final class UncompressPointer extends Pointer {
+        public static final LIRInstructionClass<UncompressPointer> TYPE = LIRInstructionClass.create(UncompressPointer.class);
+
+        public UncompressPointer(AllocatableValue result, AllocatableValue input, AllocatableValue baseRegister, CompressEncoding encoding, boolean nonNull, LIRKindTool lirKindTool) {
+            super(TYPE, result, input, baseRegister, encoding, nonNull, lirKindTool);
+        }
+
+        @Override
+        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+            move(lirKindTool.getNarrowOopKind(), crb, masm);
+
+            Register resReg = getResultRegister();
+            int shift = getShift();
+            if (shift != 0) {
+                masm.shlq(resReg, shift);
+            }
+
+            if (hasBase(crb)) {
+                Register baseReg = getBaseRegister();
+                if (nonNull) {
+                    masm.addq(resReg, baseReg);
+                    return;
+                }
+
+                if (shift == 0) {
+                    // if encoding.shift != 0, the flags are already set by the shlq
+                    masm.testq(resReg, resReg);
+                }
+
+                Label done = new Label();
+                masm.jccb(Equal, done);
+                masm.addq(resReg, baseReg);
+                masm.bind(done);
+            }
+        }
+    }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.sparc/src/org/graalvm/compiler/lir/sparc/SPARCLoadConstantTableBaseOp.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.sparc/src/org/graalvm/compiler/lir/sparc/SPARCLoadConstantTableBaseOp.java	Wed Nov 08 16:03:35 2017 -0500
@@ -55,8 +55,8 @@
  * this case absolute addressing (without using the base pointer is used). See also:
  * CodeInstaller::pd_patch_DataSectionReference
  *
- * @see SPARCMove#loadFromConstantTable(CompilationResultBuilder, SPARCMacroAssembler, int,
- *      Register, jdk.vm.ci.meta.Constant, Register, SPARCDelayedControlTransfer)
+ * @see SPARCMove#loadFromConstantTable(CompilationResultBuilder, SPARCMacroAssembler, Register,
+ *      jdk.vm.ci.meta.Constant, Register, SPARCDelayedControlTransfer)
  */
 public class SPARCLoadConstantTableBaseOp extends SPARCLIRInstruction {
     public static final LIRInstructionClass<SPARCLoadConstantTableBaseOp> TYPE = LIRInstructionClass.create(SPARCLoadConstantTableBaseOp.class);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.sparc/src/org/graalvm/compiler/lir/sparc/SPARCMove.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.sparc/src/org/graalvm/compiler/lir/sparc/SPARCMove.java	Wed Nov 08 16:03:35 2017 -0500
@@ -53,6 +53,7 @@
 import org.graalvm.compiler.asm.sparc.SPARCAssembler;
 import org.graalvm.compiler.asm.sparc.SPARCMacroAssembler;
 import org.graalvm.compiler.asm.sparc.SPARCMacroAssembler.ScratchRegister;
+import org.graalvm.compiler.code.DataSection.Data;
 import org.graalvm.compiler.core.common.LIRKind;
 import org.graalvm.compiler.core.common.type.DataPointerConstant;
 import org.graalvm.compiler.debug.GraalError;
@@ -116,11 +117,11 @@
         public static final LIRInstructionClass<LoadConstantFromTable> TYPE = LIRInstructionClass.create(LoadConstantFromTable.class);
         public static final SizeEstimate SIZE = SizeEstimate.create(1, 8);
 
-        private Constant constant;
+        private JavaConstant constant;
         @Def({REG, STACK}) AllocatableValue result;
         @Use({REG}) private AllocatableValue constantTableBase;
 
-        public LoadConstantFromTable(Constant constant, AllocatableValue constantTableBase, AllocatableValue result) {
+        public LoadConstantFromTable(JavaConstant constant, AllocatableValue constantTableBase, AllocatableValue result) {
             super(TYPE, SIZE);
             this.constant = constant;
             this.result = result;
@@ -134,11 +135,11 @@
             Register baseRegister = asRegister(constantTableBase);
             if (isRegister(result)) {
                 Register resultRegister = asRegister(result);
-                loadFromConstantTable(crb, masm, byteCount, baseRegister, constant, resultRegister, getDelayedControlTransfer());
+                loadFromConstantTable(crb, masm, baseRegister, constant, resultRegister, getDelayedControlTransfer());
             } else if (isStackSlot(result)) {
                 try (ScratchRegister scratch = masm.getScratchRegister()) {
                     Register scratchRegister = scratch.getRegister();
-                    loadFromConstantTable(crb, masm, byteCount, baseRegister, constant, scratchRegister, getDelayedControlTransfer());
+                    loadFromConstantTable(crb, masm, baseRegister, constant, scratchRegister, getDelayedControlTransfer());
                     StackSlot slot = asStackSlot(result);
                     reg2stack(crb, masm, slot, scratchRegister.asValue(), getDelayedControlTransfer());
                 }
@@ -642,7 +643,6 @@
             boolean hasVIS1 = cpuFeatures.contains(CPUFeature.VIS1);
             boolean hasVIS3 = cpuFeatures.contains(CPUFeature.VIS3);
             Register resultRegister = asRegister(result);
-            int byteCount = result.getPlatformKind().getSizeInBytes();
             switch (input.getJavaKind().getStackKind()) {
                 case Int:
                     if (input.isDefaultForKind()) {
@@ -655,7 +655,7 @@
                         if (constantTableBase.equals(g0)) {
                             throw GraalError.shouldNotReachHere();
                         } else {
-                            loadFromConstantTable(crb, masm, byteCount, constantTableBase, input, resultRegister, delaySlotLir);
+                            loadFromConstantTable(crb, masm, constantTableBase, input, resultRegister, delaySlotLir);
                         }
                     }
                     break;
@@ -667,7 +667,7 @@
                         delaySlotLir.emitControlTransfer(crb, masm);
                         masm.or(g0, (int) input.asLong(), resultRegister);
                     } else {
-                        loadFromConstantTable(crb, masm, byteCount, constantTableBase, input, resultRegister, delaySlotLir);
+                        loadFromConstantTable(crb, masm, constantTableBase, input, resultRegister, delaySlotLir);
                     }
                     break;
                 case Float: {
@@ -683,7 +683,7 @@
                             masm.movwtos(scratch, resultRegister);
                         } else {
                             // First load the address into the scratch register
-                            loadFromConstantTable(crb, masm, byteCount, constantTableBase, input, resultRegister, delaySlotLir);
+                            loadFromConstantTable(crb, masm, constantTableBase, input, resultRegister, delaySlotLir);
                         }
                     }
                     break;
@@ -700,7 +700,7 @@
                             delaySlotLir.emitControlTransfer(crb, masm);
                             masm.movxtod(scratch, resultRegister);
                         } else {
-                            loadFromConstantTable(crb, masm, byteCount, constantTableBase, input, resultRegister, delaySlotLir);
+                            loadFromConstantTable(crb, masm, constantTableBase, input, resultRegister, delaySlotLir);
                         }
                     }
                     break;
@@ -710,7 +710,7 @@
                         delaySlotLir.emitControlTransfer(crb, masm);
                         masm.clr(resultRegister);
                     } else {
-                        loadFromConstantTable(crb, masm, byteCount, constantTableBase, input, resultRegister, delaySlotLir);
+                        loadFromConstantTable(crb, masm, constantTableBase, input, resultRegister, delaySlotLir);
                     }
                     break;
                 default:
@@ -768,25 +768,30 @@
      * patterns used for small constant sections (<8k) and large constant sections (>=8k). The
      * generated patterns by this method must be understood by
      * CodeInstaller::pd_patch_DataSectionReference (jvmciCodeInstaller_sparc.cpp).
+     *
+     * @return the number of bytes loaded from the constant table
      */
-    public static void loadFromConstantTable(CompilationResultBuilder crb, SPARCMacroAssembler masm, int byteCount, Register constantTableBase, Constant input, Register dest,
+    public static int loadFromConstantTable(CompilationResultBuilder crb, SPARCMacroAssembler masm, Register constantTableBase, Constant input, Register dest,
                     SPARCDelayedControlTransfer delaySlotInstruction) {
         SPARCAddress address;
         ScratchRegister scratch = null;
         try {
+            Data data = crb.createDataItem(input);
+            int size = data.getSize();
             if (masm.isImmediateConstantLoad()) {
                 address = new SPARCAddress(constantTableBase, 0);
                 // Make delayed only, when using immediate constant load.
                 delaySlotInstruction.emitControlTransfer(crb, masm);
-                crb.recordDataReferenceInCode(input, byteCount);
+                crb.recordDataReferenceInCode(data, size);
             } else {
                 scratch = masm.getScratchRegister();
                 Register sr = scratch.getRegister();
-                crb.recordDataReferenceInCode(input, byteCount);
+                crb.recordDataReferenceInCode(data, size);
                 masm.sethix(0, sr, true);
                 address = new SPARCAddress(sr, 0);
             }
-            masm.ld(address, dest, byteCount, false);
+            masm.ld(address, dest, size, false);
+            return size;
         } finally {
             if (scratch != null) {
                 scratch.close();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/LIRValueUtil.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/LIRValueUtil.java	Wed Nov 08 16:03:35 2017 -0500
@@ -69,6 +69,16 @@
         return asConstantValue(value).getJavaConstant();
     }
 
+    public static boolean isIntConstant(Value value, long expected) {
+        if (isJavaConstant(value)) {
+            JavaConstant javaConstant = asJavaConstant(value);
+            if (javaConstant != null && javaConstant.getJavaKind().isNumericInteger()) {
+                return javaConstant.asLong() == expected;
+            }
+        }
+        return false;
+    }
+
     public static boolean isStackSlotValue(Value value) {
         assert value != null;
         return value instanceof StackSlot || value instanceof VirtualStackSlot;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/RedundantMoveElimination.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/RedundantMoveElimination.java	Wed Nov 08 16:03:35 2017 -0500
@@ -30,6 +30,7 @@
 import java.util.Collections;
 import java.util.EnumSet;
 
+import jdk.vm.ci.code.RegisterConfig;
 import org.graalvm.compiler.core.common.LIRKind;
 import org.graalvm.compiler.core.common.cfg.AbstractBlockBase;
 import org.graalvm.compiler.debug.CounterKey;
@@ -138,8 +139,8 @@
         private void doOptimize(LIR lir) {
             DebugContext debug = lir.getDebug();
             try (Indent indent = debug.logAndIndent("eliminate redundant moves")) {
-
-                callerSaveRegs = frameMap.getRegisterConfig().getCallerSaveRegisters();
+                RegisterConfig registerConfig = frameMap.getRegisterConfig();
+                callerSaveRegs = registerConfig.getCallerSaveRegisters();
 
                 initBlockData(lir);
 
@@ -147,7 +148,7 @@
                 // Unallocatable registers should never be optimized.
                 eligibleRegs = new int[numRegs];
                 Arrays.fill(eligibleRegs, -1);
-                for (Register reg : frameMap.getRegisterConfig().getAllocatableRegisters()) {
+                for (Register reg : registerConfig.getAllocatableRegisters()) {
                     if (reg.number < numRegs) {
                         eligibleRegs[reg.number] = reg.number;
                     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/SaveCalleeSaveRegisters.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/SaveCalleeSaveRegisters.java	Wed Nov 08 16:03:35 2017 -0500
@@ -31,7 +31,6 @@
 import org.graalvm.compiler.lir.LIRInstruction;
 import org.graalvm.compiler.lir.StandardOp;
 import org.graalvm.compiler.lir.Variable;
-import org.graalvm.compiler.lir.framemap.FrameMapBuilder;
 import org.graalvm.compiler.lir.gen.LIRGenerationResult;
 import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
 import org.graalvm.compiler.lir.phases.PreAllocationOptimizationPhase;
@@ -48,8 +47,7 @@
 
     @Override
     protected void run(TargetDescription target, LIRGenerationResult lirGenRes, PreAllocationOptimizationContext context) {
-        FrameMapBuilder frameMapBuilder = lirGenRes.getFrameMapBuilder();
-        RegisterArray calleeSaveRegisters = frameMapBuilder.getCodeCache().getRegisterConfig().getCalleeSaveRegisters();
+        RegisterArray calleeSaveRegisters = lirGenRes.getRegisterConfig().getCalleeSaveRegisters();
         if (calleeSaveRegisters == null || calleeSaveRegisters.size() == 0) {
             return;
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/asm/CompilationResultBuilder.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/asm/CompilationResultBuilder.java	Wed Nov 08 16:03:35 2017 -0500
@@ -80,10 +80,10 @@
  */
 public class CompilationResultBuilder {
 
-    // @formatter:off
-    @Option(help = "Include the LIR as comments with the final assembly.", type = OptionType.Debug)
-    public static final OptionKey<Boolean> PrintLIRWithAssembly = new OptionKey<>(false);
-    // @formatter:on
+    public static class Options {
+        @Option(help = "Include the LIR as comments with the final assembly.", type = OptionType.Debug) //
+        public static final OptionKey<Boolean> PrintLIRWithAssembly = new OptionKey<>(false);
+    }
 
     private static class ExceptionInfo {
 
@@ -295,13 +295,24 @@
     public AbstractAddress recordDataReferenceInCode(Constant constant, int alignment) {
         assert constant != null;
         debug.log("Constant reference in code: pos = %d, data = %s", asm.position(), constant);
+        Data data = createDataItem(constant);
+        data.updateAlignment(alignment);
+        return recordDataSectionReference(data);
+    }
+
+    public AbstractAddress recordDataReferenceInCode(Data data, int alignment) {
+        assert data != null;
+        data.updateAlignment(alignment);
+        return recordDataSectionReference(data);
+    }
+
+    public Data createDataItem(Constant constant) {
         Data data = dataCache.get(constant);
         if (data == null) {
             data = dataBuilder.createDataItem(constant);
             dataCache.put(constant, data);
         }
-        data.updateAlignment(alignment);
-        return recordDataSectionReference(data);
+        return data;
     }
 
     public AbstractAddress recordDataReferenceInCode(byte[] data, int alignment) {
@@ -472,7 +483,7 @@
         if (block == null) {
             return;
         }
-        boolean emitComment = debug.isDumpEnabled(DebugContext.BASIC_LEVEL) || PrintLIRWithAssembly.getValue(getOptions());
+        boolean emitComment = debug.isDumpEnabled(DebugContext.BASIC_LEVEL) || Options.PrintLIRWithAssembly.getValue(getOptions());
         if (emitComment) {
             blockComment(String.format("block B%d %s", block.getId(), block.getLoop()));
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/gen/ArithmeticLIRGenerator.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/gen/ArithmeticLIRGenerator.java	Wed Nov 08 16:03:35 2017 -0500
@@ -50,8 +50,19 @@
 
     protected abstract Variable emitAdd(LIRKind resultKind, Value a, Value b, boolean setFlags);
 
+    protected abstract Variable emitSub(LIRKind resultKind, Value a, Value b, boolean setFlags);
+
     @Override
     public final Variable emitAdd(Value aVal, Value bVal, boolean setFlags) {
+        return emitAddOrSub(aVal, bVal, setFlags, true);
+    }
+
+    @Override
+    public final Variable emitSub(Value aVal, Value bVal, boolean setFlags) {
+        return emitAddOrSub(aVal, bVal, setFlags, false);
+    }
+
+    private Variable emitAddOrSub(Value aVal, Value bVal, boolean setFlags, boolean isAdd) {
         LIRKind resultKind;
         Value a = aVal;
         Value b = bVal;
@@ -90,47 +101,7 @@
             resultKind = LIRKind.combine(a, b);
         }
 
-        return emitAdd(resultKind, a, b, setFlags);
+        return isAdd ? emitAdd(resultKind, a, b, setFlags) : emitSub(resultKind, a, b, setFlags);
     }
 
-    protected abstract Variable emitSub(LIRKind resultKind, Value a, Value b, boolean setFlags);
-
-    @Override
-    public final Variable emitSub(Value aVal, Value bVal, boolean setFlags) {
-        LIRKind resultKind;
-        Value a = aVal;
-        Value b = bVal;
-
-        if (isNumericInteger(a.getPlatformKind())) {
-            LIRKind aKind = a.getValueKind(LIRKind.class);
-            LIRKind bKind = b.getValueKind(LIRKind.class);
-            assert a.getPlatformKind() == b.getPlatformKind();
-
-            if (aKind.isUnknownReference()) {
-                resultKind = aKind;
-            } else if (bKind.isUnknownReference()) {
-                resultKind = bKind;
-            }
-
-            if (aKind.isValue() && bKind.isValue()) {
-                resultKind = aKind;
-            } else if (bKind.isValue()) {
-                if (aKind.isDerivedReference()) {
-                    resultKind = aKind;
-                } else {
-                    AllocatableValue allocatable = getLIRGen().asAllocatable(a);
-                    resultKind = aKind.makeDerivedReference(allocatable);
-                    a = allocatable;
-                }
-            } else if (aKind.isDerivedReference() && bKind.isDerivedReference() && aKind.getDerivedReferenceBase().equals(bKind.getDerivedReferenceBase())) {
-                resultKind = LIRKind.value(a.getPlatformKind());
-            } else {
-                resultKind = aKind.makeUnknownReference();
-            }
-        } else {
-            resultKind = LIRKind.combine(a, b);
-        }
-
-        return emitSub(resultKind, a, b, setFlags);
-    }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/gen/LIRGenerationResult.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/gen/LIRGenerationResult.java	Wed Nov 08 16:03:35 2017 -0500
@@ -22,6 +22,7 @@
  */
 package org.graalvm.compiler.lir.gen;
 
+import jdk.vm.ci.code.RegisterConfig;
 import org.graalvm.compiler.core.common.CompilationIdentifier;
 import org.graalvm.compiler.core.common.CompilationIdentifier.Verbosity;
 import org.graalvm.compiler.debug.DebugContext;
@@ -123,6 +124,10 @@
         return frameMap;
     }
 
+    public final RegisterConfig getRegisterConfig() {
+        return frameMapBuilder.getRegisterConfig();
+    }
+
     public LIR getLIR() {
         return lir;
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/gen/LIRGenerator.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/gen/LIRGenerator.java	Wed Nov 08 16:03:35 2017 -0500
@@ -34,6 +34,7 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import jdk.vm.ci.code.RegisterConfig;
 import org.graalvm.compiler.asm.Label;
 import org.graalvm.compiler.core.common.LIRKind;
 import org.graalvm.compiler.core.common.calc.Condition;
@@ -201,8 +202,13 @@
     }
 
     @Override
+    public RegisterConfig getRegisterConfig() {
+        return res.getRegisterConfig();
+    }
+
+    @Override
     public RegisterAttributes attributes(Register register) {
-        return res.getFrameMapBuilder().getRegisterConfig().getAttributesMap()[register.number];
+        return getRegisterConfig().getAttributesMap()[register.number];
     }
 
     @Override
@@ -228,7 +234,7 @@
         if (moveFactory.canInlineConstant(constant)) {
             return new ConstantValue(toRegisterKind(kind), constant);
         } else {
-            return emitLoadConstant(kind, constant);
+            return emitLoadConstant(toRegisterKind(kind), constant);
         }
     }
 
@@ -289,7 +295,7 @@
      */
     @Override
     public AllocatableValue resultOperandFor(JavaKind javaKind, ValueKind<?> valueKind) {
-        Register reg = res.getFrameMapBuilder().getRegisterConfig().getReturnRegister(javaKind);
+        Register reg = getRegisterConfig().getReturnRegister(javaKind);
         assert target().arch.canStoreValue(reg.getRegisterCategory(), valueKind.getPlatformKind()) : reg.getRegisterCategory() + " " + valueKind.getPlatformKind();
         return reg.asValue(valueKind);
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/gen/LIRGeneratorTool.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/gen/LIRGeneratorTool.java	Wed Nov 08 16:03:35 2017 -0500
@@ -22,6 +22,7 @@
  */
 package org.graalvm.compiler.lir.gen;
 
+import jdk.vm.ci.code.RegisterConfig;
 import org.graalvm.compiler.core.common.CompressEncoding;
 import org.graalvm.compiler.core.common.LIRKind;
 import org.graalvm.compiler.core.common.calc.Condition;
@@ -109,6 +110,8 @@
 
     LIRGenerationResult getResult();
 
+    RegisterConfig getRegisterConfig();
+
     boolean hasBlockEnd(AbstractBlockBase<?> block);
 
     MoveFactory getMoveFactory();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop.test/src/org/graalvm/compiler/loop/test/LoopPartialUnrollTest.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop.test/src/org/graalvm/compiler/loop/test/LoopPartialUnrollTest.java	Wed Nov 08 16:03:35 2017 -0500
@@ -214,7 +214,7 @@
             }
         };
         ResolvedJavaMethod method = getResolvedJavaMethod(name);
-        OptionValues options = new OptionValues(getInitialOptions(), DefaultLoopPolicies.UnrollMaxIterations, 2);
+        OptionValues options = new OptionValues(getInitialOptions(), DefaultLoopPolicies.Options.UnrollMaxIterations, 2);
         StructuredGraph graph = parse(builder(method, StructuredGraph.AllowAssumptions.YES, id, options), getEagerGraphBuilderSuite());
         try (DebugContext.Scope buildScope = graph.getDebug().scope(name, method, graph)) {
             MidTierContext context = new MidTierContext(getProviders(), getTargetProvider(), OptimisticOptimizations.ALL, null);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/CountedLoopInfo.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/CountedLoopInfo.java	Wed Nov 08 16:03:35 2017 -0500
@@ -83,7 +83,11 @@
             range = add(graph, range, oneDirection);
         }
         // round-away-from-zero divison: (range + stride -/+ 1) / stride
-        ValueNode denominator = add(graph, sub(graph, range, oneDirection), iv.strideNode());
+        ValueNode denominator = range;
+        if (!oneDirection.stamp().equals(iv.strideNode().stamp())) {
+            ValueNode subedRanged = sub(graph, range, oneDirection);
+            denominator = add(graph, subedRanged, iv.strideNode());
+        }
         ValueNode div = divBefore(graph, loop.entryPoint(), denominator, iv.strideNode());
 
         if (assumePositive) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/DefaultLoopPolicies.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/DefaultLoopPolicies.java	Wed Nov 08 16:03:35 2017 -0500
@@ -55,16 +55,19 @@
 import jdk.vm.ci.meta.MetaAccessProvider;
 
 public class DefaultLoopPolicies implements LoopPolicies {
-    @Option(help = "", type = OptionType.Expert) public static final OptionKey<Integer> LoopUnswitchMaxIncrease = new OptionKey<>(500);
-    @Option(help = "", type = OptionType.Expert) public static final OptionKey<Integer> LoopUnswitchTrivial = new OptionKey<>(10);
-    @Option(help = "", type = OptionType.Expert) public static final OptionKey<Double> LoopUnswitchFrequencyBoost = new OptionKey<>(10.0);
+
+    public static class Options {
+        @Option(help = "", type = OptionType.Expert) public static final OptionKey<Integer> LoopUnswitchMaxIncrease = new OptionKey<>(500);
+        @Option(help = "", type = OptionType.Expert) public static final OptionKey<Integer> LoopUnswitchTrivial = new OptionKey<>(10);
+        @Option(help = "", type = OptionType.Expert) public static final OptionKey<Double> LoopUnswitchFrequencyBoost = new OptionKey<>(10.0);
 
-    @Option(help = "", type = OptionType.Expert) public static final OptionKey<Integer> FullUnrollMaxNodes = new OptionKey<>(300);
-    @Option(help = "", type = OptionType.Expert) public static final OptionKey<Integer> FullUnrollMaxIterations = new OptionKey<>(600);
-    @Option(help = "", type = OptionType.Expert) public static final OptionKey<Integer> ExactFullUnrollMaxNodes = new OptionKey<>(1200);
-    @Option(help = "", type = OptionType.Expert) public static final OptionKey<Integer> ExactPartialUnrollMaxNodes = new OptionKey<>(200);
+        @Option(help = "", type = OptionType.Expert) public static final OptionKey<Integer> FullUnrollMaxNodes = new OptionKey<>(300);
+        @Option(help = "", type = OptionType.Expert) public static final OptionKey<Integer> FullUnrollMaxIterations = new OptionKey<>(600);
+        @Option(help = "", type = OptionType.Expert) public static final OptionKey<Integer> ExactFullUnrollMaxNodes = new OptionKey<>(1200);
+        @Option(help = "", type = OptionType.Expert) public static final OptionKey<Integer> ExactPartialUnrollMaxNodes = new OptionKey<>(200);
 
-    @Option(help = "", type = OptionType.Expert) public static final OptionKey<Integer> UnrollMaxIterations = new OptionKey<>(16);
+        @Option(help = "", type = OptionType.Expert) public static final OptionKey<Integer> UnrollMaxIterations = new OptionKey<>(16);
+    }
 
     @Override
     public boolean shouldPeel(LoopEx loop, ControlFlowGraph cfg, MetaAccessProvider metaAccess) {
@@ -87,10 +90,10 @@
         OptionValues options = loop.entryPoint().getOptions();
         CountedLoopInfo counted = loop.counted();
         long maxTrips = counted.constantMaxTripCount();
-        int maxNodes = (counted.isExactTripCount() && counted.isConstantExactTripCount()) ? ExactFullUnrollMaxNodes.getValue(options) : FullUnrollMaxNodes.getValue(options);
+        int maxNodes = (counted.isExactTripCount() && counted.isConstantExactTripCount()) ? Options.ExactFullUnrollMaxNodes.getValue(options) : Options.FullUnrollMaxNodes.getValue(options);
         maxNodes = Math.min(maxNodes, Math.max(0, MaximumDesiredSize.getValue(options) - loop.loopBegin().graph().getNodeCount()));
         int size = Math.max(1, loop.size() - 1 - loop.loopBegin().phis().count());
-        if (maxTrips <= FullUnrollMaxIterations.getValue(options) && size * (maxTrips - 1) <= maxNodes) {
+        if (maxTrips <= Options.FullUnrollMaxIterations.getValue(options) && size * (maxTrips - 1) <= maxNodes) {
             // check whether we're allowed to unroll this loop
             return loop.canDuplicateLoop();
         } else {
@@ -106,7 +109,7 @@
             return false;
         }
         OptionValues options = loop.entryPoint().getOptions();
-        int maxNodes = ExactPartialUnrollMaxNodes.getValue(options);
+        int maxNodes = Options.ExactPartialUnrollMaxNodes.getValue(options);
         maxNodes = Math.min(maxNodes, Math.max(0, MaximumDesiredSize.getValue(options) - loop.loopBegin().graph().getNodeCount()));
         int size = Math.max(1, loop.size() - 1 - loop.loopBegin().phis().count());
         int unrollFactor = loopBegin.getUnrollFactor();
@@ -118,7 +121,7 @@
             }
             loopBegin.setLoopOrigFrequency(loopFrequency);
         }
-        int maxUnroll = UnrollMaxIterations.getValue(options);
+        int maxUnroll = Options.UnrollMaxIterations.getValue(options);
         // Now correct size for the next unroll. UnrollMaxIterations == 1 means perform the
         // pre/main/post transformation but don't actually unroll the main loop.
         size += size;
@@ -190,9 +193,9 @@
         CountingClosure stateNodesCount = new CountingClosure();
         double loopFrequency = loop.loopBegin().loopFrequency();
         OptionValues options = loop.loopBegin().getOptions();
-        int maxDiff = LoopUnswitchTrivial.getValue(options) + (int) (LoopUnswitchFrequencyBoost.getValue(options) * (loopFrequency - 1.0 + phis));
+        int maxDiff = Options.LoopUnswitchTrivial.getValue(options) + (int) (Options.LoopUnswitchFrequencyBoost.getValue(options) * (loopFrequency - 1.0 + phis));
 
-        maxDiff = Math.min(maxDiff, LoopUnswitchMaxIncrease.getValue(options));
+        maxDiff = Math.min(maxDiff, Options.LoopUnswitchMaxIncrease.getValue(options));
         int remainingGraphSpace = MaximumDesiredSize.getValue(options) - graph.getNodeCount();
         maxDiff = Math.min(maxDiff, remainingGraphSpace);
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodeinfo/src/org/graalvm/compiler/nodeinfo/NodeCycles.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodeinfo/src/org/graalvm/compiler/nodeinfo/NodeCycles.java	Wed Nov 08 16:03:35 2017 -0500
@@ -68,6 +68,10 @@
         this.value = value;
     }
 
+    public boolean isValueKnown() {
+        return this != NodeCycles.CYCLES_UNKNOWN && this != NodeCycles.CYCLES_UNSET;
+    }
+
     public static final int IGNORE_CYCLES_CONTRACT_FACTOR = 0xFFFF;
 
     public static NodeCycles compute(NodeCycles base, int opCount) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes.test/src/org/graalvm/compiler/nodes/test/IntegerStampTest.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes.test/src/org/graalvm/compiler/nodes/test/IntegerStampTest.java	Wed Nov 08 16:03:35 2017 -0500
@@ -552,4 +552,21 @@
             return result.longValue();
         }
     }
+
+    @Test
+    public void testDiv() {
+        testDiv(32, Integer.MIN_VALUE, Integer.MAX_VALUE);
+        testDiv(64, Long.MIN_VALUE, Long.MAX_VALUE);
+    }
+
+    private static void testDiv(int bits, long min, long max) {
+        BinaryOp<?> div = IntegerStamp.OPS.getDiv();
+        assertEquals(IntegerStamp.create(bits, -50, 50), div.foldStamp(IntegerStamp.create(bits, -100, 100), IntegerStamp.create(bits, 2, 5)));
+        assertEquals(IntegerStamp.create(bits, 20, 500), div.foldStamp(IntegerStamp.create(bits, 100, 1000), IntegerStamp.create(bits, 2, 5)));
+        assertEquals(IntegerStamp.create(bits, -500, -20), div.foldStamp(IntegerStamp.create(bits, -1000, -100), IntegerStamp.create(bits, 2, 5)));
+        assertEquals(IntegerStamp.create(bits, min, max), div.foldStamp(IntegerStamp.create(bits, min, max), IntegerStamp.create(bits, 1, max)));
+        assertEquals(IntegerStamp.create(bits, -100, 100), div.foldStamp(IntegerStamp.create(bits, -100, 100), IntegerStamp.create(bits, 1, max)));
+        assertEquals(IntegerStamp.create(bits, 0, 1000), div.foldStamp(IntegerStamp.create(bits, 100, 1000), IntegerStamp.create(bits, 1, max)));
+        assertEquals(IntegerStamp.create(bits, -1000, 0), div.foldStamp(IntegerStamp.create(bits, -1000, -100), IntegerStamp.create(bits, 1, max)));
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes.test/src/org/graalvm/compiler/nodes/test/PrimitiveStampBoundaryTest.java	Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,326 @@
+/*
+ * 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
+ * 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 org.graalvm.compiler.nodes.test;
+
+import java.util.EnumSet;
+import java.util.HashSet;
+
+import org.graalvm.compiler.core.common.calc.FloatConvert;
+import org.graalvm.compiler.core.common.calc.FloatConvertCategory;
+import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
+import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp;
+import org.graalvm.compiler.core.common.type.ArithmeticOpTable.IntegerConvertOp;
+import org.graalvm.compiler.core.common.type.ArithmeticOpTable.ShiftOp;
+import org.graalvm.compiler.core.common.type.FloatStamp;
+import org.graalvm.compiler.core.common.type.IntegerStamp;
+import org.graalvm.compiler.core.common.type.PrimitiveStamp;
+import org.graalvm.compiler.core.common.type.Stamp;
+import org.graalvm.compiler.test.GraalTest;
+import org.junit.Test;
+
+import jdk.vm.ci.meta.Constant;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.JavaKind;
+
+/**
+ * Exercise the various stamp folding operations by generating ranges from a set of boundary values
+ * and then ensuring that the values that produced those ranges are in the resulting stamp.
+ */
+public class PrimitiveStampBoundaryTest extends GraalTest {
+
+    static long[] longBoundaryValues = {Long.MIN_VALUE, Long.MIN_VALUE + 1, Integer.MIN_VALUE, Integer.MIN_VALUE + 1, -1, 0, 1, Integer.MAX_VALUE - 1, Integer.MAX_VALUE, Long.MAX_VALUE - 1,
+                    Long.MAX_VALUE};
+
+    static int[] shiftBoundaryValues = {-128, -1, 0, 1, 4, 8, 16, 31, 63, 128};
+
+    static HashSet<IntegerStamp> shiftStamps;
+    static HashSet<PrimitiveStamp> integerTestStamps;
+    static HashSet<PrimitiveStamp> floatTestStamps;
+
+    static {
+        shiftStamps = new HashSet<>();
+        for (long v1 : shiftBoundaryValues) {
+            for (long v2 : shiftBoundaryValues) {
+                shiftStamps.add(IntegerStamp.create(32, Math.min(v1, v2), Math.max(v1, v2)));
+            }
+        }
+
+        integerTestStamps = new HashSet<>();
+        for (long v1 : longBoundaryValues) {
+            for (long v2 : longBoundaryValues) {
+                if (v2 == (int) v2 && v1 == (int) v1) {
+                    integerTestStamps.add(IntegerStamp.create(32, Math.min(v1, v2), Math.max(v1, v2)));
+                }
+                integerTestStamps.add(IntegerStamp.create(64, Math.min(v1, v2), Math.max(v1, v2)));
+            }
+        }
+    }
+
+    static double[] doubleBoundaryValues = {Double.NEGATIVE_INFINITY, Double.MIN_VALUE, Float.NEGATIVE_INFINITY, Float.MIN_VALUE,
+                    Long.MIN_VALUE, Long.MIN_VALUE + 1, Integer.MIN_VALUE, Integer.MIN_VALUE + 1, -1, 0, 1,
+                    Integer.MAX_VALUE - 1, Integer.MAX_VALUE, Long.MAX_VALUE - 1, Long.MAX_VALUE,
+                    Float.MAX_VALUE, Float.POSITIVE_INFINITY, Double.MAX_VALUE, Double.POSITIVE_INFINITY};
+
+    static double[] doubleSpecialValues = {Double.NaN, -0.0, -0.0F, Float.NaN};
+
+    static {
+        floatTestStamps = new HashSet<>();
+
+        for (double d1 : doubleBoundaryValues) {
+            for (double d2 : doubleBoundaryValues) {
+                float f1 = (float) d2;
+                float f2 = (float) d1;
+                if (d2 == f1 && d1 == f2) {
+                    generateFloatingStamps(new FloatStamp(32, Math.min(f2, f1), Math.max(f2, f1), true));
+                    generateFloatingStamps(new FloatStamp(32, Math.min(f2, f1), Math.max(f2, f1), false));
+                }
+                generateFloatingStamps(new FloatStamp(64, Math.min(d1, d2), Math.max(d1, d2), true));
+                generateFloatingStamps(new FloatStamp(64, Math.min(d1, d2), Math.max(d1, d2), false));
+            }
+        }
+    }
+
+    private static void generateFloatingStamps(FloatStamp floatStamp) {
+        floatTestStamps.add(floatStamp);
+        for (double d : doubleSpecialValues) {
+            FloatStamp newStamp = (FloatStamp) floatStamp.meet(floatStampForConstant(d, floatStamp.getBits()));
+            if (!newStamp.isUnrestricted()) {
+                floatTestStamps.add(newStamp);
+            }
+        }
+    }
+
+    @Test
+    public void testConvertBoundaryValues() {
+        testConvertBoundaryValues(IntegerStamp.OPS.getSignExtend(), 32, 64, integerTestStamps);
+        testConvertBoundaryValues(IntegerStamp.OPS.getZeroExtend(), 32, 64, integerTestStamps);
+        testConvertBoundaryValues(IntegerStamp.OPS.getNarrow(), 64, 32, integerTestStamps);
+    }
+
+    private static void testConvertBoundaryValues(IntegerConvertOp<?> op, int inputBits, int resultBits, HashSet<PrimitiveStamp> stamps) {
+        for (PrimitiveStamp stamp : stamps) {
+            if (inputBits == stamp.getBits()) {
+                Stamp lower = boundaryStamp(stamp, false);
+                Stamp upper = boundaryStamp(stamp, true);
+                checkConvertOperation(op, inputBits, resultBits, op.foldStamp(inputBits, resultBits, stamp), lower);
+                checkConvertOperation(op, inputBits, resultBits, op.foldStamp(inputBits, resultBits, stamp), upper);
+            }
+        }
+    }
+
+    private static void checkConvertOperation(IntegerConvertOp<?> op, int inputBits, int resultBits, Stamp result, Stamp v1stamp) {
+        Stamp folded = op.foldStamp(inputBits, resultBits, v1stamp);
+        assertTrue(folded.asConstant() != null, "should constant fold %s %s %s", op, v1stamp, folded);
+        assertTrue(result.meet(folded).equals(result), "result out of range %s %s %s %s %s", op, v1stamp, folded, result, result.meet(folded));
+    }
+
+    @Test
+    public void testFloatConvertBoundaryValues() {
+        for (FloatConvert op : EnumSet.allOf(FloatConvert.class)) {
+            ArithmeticOpTable.FloatConvertOp floatConvert = IntegerStamp.OPS.getFloatConvert(op);
+            if (floatConvert == null) {
+                continue;
+            }
+            assert op.getCategory() == FloatConvertCategory.IntegerToFloatingPoint : op;
+            testConvertBoundaryValues(floatConvert, op.getInputBits(), integerTestStamps);
+        }
+        for (FloatConvert op : EnumSet.allOf(FloatConvert.class)) {
+            ArithmeticOpTable.FloatConvertOp floatConvert = FloatStamp.OPS.getFloatConvert(op);
+            if (floatConvert == null) {
+                continue;
+            }
+            assert op.getCategory() == FloatConvertCategory.FloatingPointToInteger || op.getCategory() == FloatConvertCategory.FloatingPointToFloatingPoint : op;
+            testConvertBoundaryValues(floatConvert, op.getInputBits(), floatTestStamps);
+        }
+    }
+
+    private static void testConvertBoundaryValues(ArithmeticOpTable.FloatConvertOp op, int bits, HashSet<PrimitiveStamp> stamps) {
+        for (PrimitiveStamp stamp : stamps) {
+            if (bits == stamp.getBits()) {
+                Stamp lower = boundaryStamp(stamp, false);
+                Stamp upper = boundaryStamp(stamp, true);
+                checkConvertOperation(op, op.foldStamp(stamp), lower);
+                checkConvertOperation(op, op.foldStamp(stamp), upper);
+            }
+        }
+    }
+
+    private static void checkConvertOperation(ArithmeticOpTable.FloatConvertOp op, Stamp result, Stamp v1stamp) {
+        Stamp folded = op.foldStamp(v1stamp);
+        assertTrue(folded.asConstant() != null, "should constant fold %s %s %s", op, v1stamp, folded);
+        assertTrue(result.meet(folded).equals(result), "result out of range %s %s %s %s %s", op, v1stamp, folded, result, result.meet(folded));
+    }
+
+    @Test
+    public void testShiftBoundaryValues() {
+        for (ShiftOp<?> op : IntegerStamp.OPS.getShiftOps()) {
+            testShiftBoundaryValues(op, integerTestStamps, shiftStamps);
+        }
+    }
+
+    private static void testShiftBoundaryValues(ShiftOp<?> shiftOp, HashSet<PrimitiveStamp> stamps, HashSet<IntegerStamp> shifts) {
+        for (PrimitiveStamp testStamp : stamps) {
+            if (testStamp instanceof IntegerStamp) {
+                IntegerStamp stamp = (IntegerStamp) testStamp;
+                for (IntegerStamp shiftStamp : shifts) {
+                    IntegerStamp foldedStamp = (IntegerStamp) shiftOp.foldStamp(stamp, shiftStamp);
+                    checkShiftOperation(stamp.getBits(), shiftOp, foldedStamp, stamp.lowerBound(), shiftStamp.lowerBound());
+                    checkShiftOperation(stamp.getBits(), shiftOp, foldedStamp, stamp.lowerBound(), shiftStamp.upperBound());
+                    checkShiftOperation(stamp.getBits(), shiftOp, foldedStamp, stamp.upperBound(), shiftStamp.lowerBound());
+                    checkShiftOperation(stamp.getBits(), shiftOp, foldedStamp, stamp.upperBound(), shiftStamp.upperBound());
+                }
+            }
+        }
+    }
+
+    private static void checkShiftOperation(int bits, ShiftOp<?> op, IntegerStamp result, long v1, long v2) {
+        IntegerStamp v1stamp = IntegerStamp.create(bits, v1, v1);
+        IntegerStamp v2stamp = IntegerStamp.create(32, v2, v2);
+        IntegerStamp folded = (IntegerStamp) op.foldStamp(v1stamp, v2stamp);
+        Constant constant = op.foldConstant(JavaConstant.forPrimitiveInt(bits, v1), (int) v2);
+        assertTrue(constant != null);
+        assertTrue(folded.asConstant() != null, "should constant fold %s %s %s %s", op, v1stamp, v2stamp, folded);
+        assertTrue(result.meet(folded).equals(result), "result out of range %s %s %s %s %s %s", op, v1stamp, v2stamp, folded, result, result.meet(folded));
+    }
+
+    private static void checkBinaryOperation(ArithmeticOpTable.BinaryOp<?> op, Stamp result, Stamp v1stamp, Stamp v2stamp) {
+        Stamp folded = op.foldStamp(v1stamp, v2stamp);
+        Constant constant = op.foldConstant(v1stamp.asConstant(), v2stamp.asConstant());
+        if (constant != null) {
+            Constant constant2 = folded.asConstant();
+            if (constant2 == null && v1stamp instanceof FloatStamp) {
+                JavaConstant c = (JavaConstant) constant;
+                assertTrue((c.getJavaKind() == JavaKind.Double && Double.isNaN(c.asDouble())) ||
+                                (c.getJavaKind() == JavaKind.Float && Float.isNaN(c.asFloat())));
+            } else {
+                assertTrue(constant2 != null, "should constant fold %s %s %s %s", op, v1stamp, v2stamp, folded);
+                if (!constant.equals(constant2)) {
+                    op.foldConstant(v1stamp.asConstant(), v2stamp.asConstant());
+                    op.foldStamp(v1stamp, v2stamp);
+                }
+                assertTrue(constant.equals(constant2), "should produce same constant %s %s %s %s %s", op, v1stamp, v2stamp, constant, constant2);
+            }
+            assertTrue(result.meet(folded).equals(result), "result out of range %s %s %s %s %s %s", op, v1stamp, v2stamp, folded, result, result.meet(folded));
+        }
+    }
+
+    @Test
+    public void testBinaryBoundaryValues() {
+        for (BinaryOp<?> op : IntegerStamp.OPS.getBinaryOps()) {
+            if (op != null) {
+                testBinaryBoundaryValues(op, integerTestStamps);
+            }
+        }
+        for (BinaryOp<?> op : FloatStamp.OPS.getBinaryOps()) {
+            if (op != null) {
+                testBinaryBoundaryValues(op, floatTestStamps);
+            }
+        }
+    }
+
+    private static Stamp boundaryStamp(Stamp v1, boolean upper) {
+        if (v1 instanceof IntegerStamp) {
+            IntegerStamp istamp = (IntegerStamp) v1;
+            long bound = upper ? istamp.upperBound() : istamp.lowerBound();
+            return IntegerStamp.create(istamp.getBits(), bound, bound);
+        } else if (v1 instanceof FloatStamp) {
+            FloatStamp floatStamp = (FloatStamp) v1;
+            double bound = upper ? floatStamp.upperBound() : floatStamp.lowerBound();
+            int bits = floatStamp.getBits();
+            return floatStampForConstant(bound, bits);
+        } else {
+            throw new InternalError("unexpected stamp type " + v1);
+        }
+    }
+
+    private static FloatStamp floatStampForConstant(double bound, int bits) {
+        if (bits == 32) {
+            float fbound = (float) bound;
+            return new FloatStamp(bits, fbound, fbound, !Float.isNaN(fbound));
+        } else {
+            return new FloatStamp(bits, bound, bound, !Double.isNaN(bound));
+        }
+    }
+
+    private static void testBinaryBoundaryValues(ArithmeticOpTable.BinaryOp<?> op, HashSet<PrimitiveStamp> stamps) {
+        for (PrimitiveStamp v1 : stamps) {
+            for (PrimitiveStamp v2 : stamps) {
+                if (v1.getBits() == v2.getBits() && v1.getClass() == v2.getClass()) {
+                    Stamp result = op.foldStamp(v1, v2);
+                    Stamp v1lower = boundaryStamp(v1, false);
+                    Stamp v1upper = boundaryStamp(v1, true);
+                    Stamp v2lower = boundaryStamp(v2, false);
+                    Stamp v2upper = boundaryStamp(v2, true);
+                    checkBinaryOperation(op, result, v1lower, v2lower);
+                    checkBinaryOperation(op, result, v1lower, v2upper);
+                    checkBinaryOperation(op, result, v1upper, v2lower);
+                    checkBinaryOperation(op, result, v1upper, v2upper);
+                }
+            }
+        }
+    }
+
+    @Test
+    public void testUnaryBoundaryValues() {
+        for (ArithmeticOpTable.UnaryOp<?> op : IntegerStamp.OPS.getUnaryOps()) {
+            if (op != null) {
+                testUnaryBoundaryValues(op, integerTestStamps);
+            }
+        }
+        for (ArithmeticOpTable.UnaryOp<?> op : FloatStamp.OPS.getUnaryOps()) {
+            if (op != null) {
+                testUnaryBoundaryValues(op, floatTestStamps);
+            }
+        }
+    }
+
+    private static void testUnaryBoundaryValues(ArithmeticOpTable.UnaryOp<?> op, HashSet<PrimitiveStamp> stamps) {
+        for (PrimitiveStamp v1 : stamps) {
+            Stamp result = op.foldStamp(v1);
+            checkUnaryOperation(op, result, boundaryStamp(v1, false));
+            checkUnaryOperation(op, result, boundaryStamp(v1, true));
+        }
+    }
+
+    private static void checkUnaryOperation(ArithmeticOpTable.UnaryOp<?> op, Stamp result, Stamp v1stamp) {
+        Stamp folded = op.foldStamp(v1stamp);
+        Constant v1constant = v1stamp.asConstant();
+        if (v1constant != null) {
+            Constant constant = op.foldConstant(v1constant);
+            if (constant != null) {
+                Constant constant2 = folded.asConstant();
+                if (constant2 == null && v1stamp instanceof FloatStamp) {
+                    JavaConstant c = (JavaConstant) constant;
+                    assertTrue((c.getJavaKind() == JavaKind.Double && Double.isNaN(c.asDouble())) ||
+                                    (c.getJavaKind() == JavaKind.Float && Float.isNaN(c.asFloat())));
+                } else {
+                    assertTrue(constant2 != null, "should constant fold %s %s %s", op, v1stamp, folded);
+                    assertTrue(constant.equals(constant2), "should produce same constant %s %s %s %s", op, v1stamp, constant, constant2);
+                }
+            }
+        } else {
+            assert v1stamp instanceof FloatStamp;
+        }
+        assertTrue(result.meet(folded).equals(result), "result out of range %s %s %s %s %s", op, v1stamp, folded, result, result.meet(folded));
+    }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/CompressionNode.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/CompressionNode.java	Wed Nov 08 16:03:35 2017 -0500
@@ -122,9 +122,9 @@
                 // We always want uncompressed constants
                 return this;
             }
-            int stableDimension = ((ConstantNode) forValue).getStableDimension();
-            boolean isDefaultStable = ((ConstantNode) forValue).isDefaultStable();
-            return ConstantNode.forConstant(stamp(), convert(forValue.asConstant(), tool.getConstantReflection()), stableDimension, isDefaultStable, tool.getMetaAccess());
+
+            ConstantNode constant = (ConstantNode) forValue;
+            return ConstantNode.forConstant(stamp(), convert(constant.getValue(), tool.getConstantReflection()), constant.getStableDimension(), constant.isDefaultStable(), tool.getMetaAccess());
         } else if (forValue instanceof CompressionNode) {
             CompressionNode other = (CompressionNode) forValue;
             if (op != other.op && encoding.equals(other.encoding)) {
@@ -136,22 +136,22 @@
 
     @Override
     public void generate(NodeLIRBuilderTool gen) {
-        LIRGeneratorTool hsGen = gen.getLIRGeneratorTool();
         boolean nonNull;
-        if (getValue().stamp() instanceof AbstractObjectStamp) {
-            nonNull = StampTool.isPointerNonNull(getValue().stamp());
+        if (value.stamp() instanceof AbstractObjectStamp) {
+            nonNull = StampTool.isPointerNonNull(value.stamp());
         } else {
             // metaspace pointers are never null
             nonNull = true;
         }
 
+        LIRGeneratorTool tool = gen.getLIRGeneratorTool();
         Value result;
         switch (op) {
             case Compress:
-                result = hsGen.emitCompress(gen.operand(getValue()), encoding, nonNull);
+                result = tool.emitCompress(gen.operand(value), encoding, nonNull);
                 break;
             case Uncompress:
-                result = hsGen.emitUncompress(gen.operand(getValue()), encoding, nonNull);
+                result = tool.emitUncompress(gen.operand(value), encoding, nonNull);
                 break;
             default:
                 throw GraalError.shouldNotReachHere();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/ConstantNode.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/ConstantNode.java	Wed Nov 08 16:03:35 2017 -0500
@@ -54,7 +54,7 @@
 /**
  * The {@code ConstantNode} represents a {@link Constant constant}.
  */
-@NodeInfo(nameTemplate = "C({p#rawvalue})", cycles = CYCLES_0, size = SIZE_1)
+@NodeInfo(nameTemplate = "C({p#rawvalue}) {p#stampKind}", cycles = CYCLES_0, size = SIZE_1)
 public final class ConstantNode extends FloatingNode implements LIRLowerable {
 
     public static final NodeClass<ConstantNode> TYPE = NodeClass.create(ConstantNode.class);
@@ -518,13 +518,14 @@
     public Map<Object, Object> getDebugProperties(Map<Object, Object> map) {
         Map<Object, Object> properties = super.getDebugProperties(map);
         properties.put("rawvalue", value.toValueString());
+        properties.put("stampKind", stamp.unrestricted().toString());
         return properties;
     }
 
     @Override
     public String toString(Verbosity verbosity) {
         if (verbosity == Verbosity.Name) {
-            return super.toString(Verbosity.Name) + "(" + value.toValueString() + ")";
+            return super.toString(Verbosity.Name) + "(" + value.toValueString() + ", " + stamp().unrestricted().toString() + ")";
         } else {
             return super.toString(verbosity);
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/IfNode.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/IfNode.java	Wed Nov 08 16:03:35 2017 -0500
@@ -22,7 +22,7 @@
  */
 package org.graalvm.compiler.nodes;
 
-import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_2;
+import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_1;
 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_2;
 
 import java.util.ArrayList;
@@ -74,7 +74,7 @@
  * The {@code IfNode} represents a branch that can go one of two directions depending on the outcome
  * of a comparison.
  */
-@NodeInfo(cycles = CYCLES_2, size = SIZE_2, sizeRationale = "2 jmps")
+@NodeInfo(cycles = CYCLES_1, size = SIZE_2, sizeRationale = "2 jmps")
 public final class IfNode extends ControlSplitNode implements Simplifiable, LIRLowerable {
     public static final NodeClass<IfNode> TYPE = NodeClass.create(IfNode.class);
 
@@ -375,7 +375,7 @@
         }
 
         // Falsify the reference check.
-        setCondition(graph().addOrUnique(LogicConstantNode.contradiction()));
+        setCondition(graph().addOrUniqueWithInputs(LogicConstantNode.contradiction()));
 
         return true;
     }
@@ -726,10 +726,11 @@
 
     protected void removeThroughFalseBranch(SimplifierTool tool, AbstractMergeNode merge) {
         AbstractBeginNode trueBegin = trueSuccessor();
+        LogicNode conditionNode = condition();
         graph().removeSplitPropagate(this, trueBegin);
         tool.addToWorkList(trueBegin);
-        if (condition() != null) {
-            GraphUtil.tryKillUnused(condition());
+        if (conditionNode != null) {
+            GraphUtil.tryKillUnused(conditionNode);
         }
         if (merge.isAlive() && merge.forwardEndCount() > 1) {
             for (FixedNode end : merge.forwardEnds()) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/PhiNode.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/PhiNode.java	Wed Nov 08 16:03:35 2017 -0500
@@ -132,12 +132,24 @@
                 }
                 str.append(valueAt(i) == null ? "-" : valueAt(i).toString(Verbosity.Id));
             }
+            String description = valueDescription();
+            if (description.length() > 0) {
+                str.append(", ").append(description);
+            }
             return super.toString(Verbosity.Name) + "(" + str + ")";
         } else {
             return super.toString(verbosity);
         }
     }
 
+    /**
+     * String describing the kind of value this Phi merges. Used by {@link #toString(Verbosity)} and
+     * dumping.
+     */
+    protected String valueDescription() {
+        return "";
+    }
+
     public void addInput(ValueNode x) {
         assert !(x instanceof ValuePhiNode) || ((ValuePhiNode) x).merge() instanceof LoopBeginNode || ((ValuePhiNode) x).merge() != this.merge();
         assert !(this instanceof ValuePhiNode) || x.stamp().isCompatible(stamp());
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/PiNode.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/PiNode.java	Wed Nov 08 16:03:35 2017 -0500
@@ -59,14 +59,14 @@
  *
  * In contrast to a {@link GuardedValueNode}, a {@link PiNode} is useless as soon as the type of its
  * input is as narrow or narrower than the {@link PiNode}'s type. The {@link PiNode}, and therefore
- * also the scheduling restriction enforced by the anchor, will go away.
+ * also the scheduling restriction enforced by the guard, will go away.
  */
 @NodeInfo(cycles = CYCLES_0, size = SIZE_0)
 public class PiNode extends FloatingGuardedNode implements LIRLowerable, Virtualizable, IterableNodeType, Canonicalizable, ValueProxy {
 
     public static final NodeClass<PiNode> TYPE = NodeClass.create(PiNode.class);
     @Input ValueNode object;
-    protected final Stamp piStamp;
+    protected Stamp piStamp;
 
     public ValueNode object() {
         return object;
@@ -84,12 +84,12 @@
         this(object, stamp, null);
     }
 
-    public PiNode(ValueNode object, Stamp stamp, ValueNode anchor) {
-        this(TYPE, object, stamp, (GuardingNode) anchor);
+    public PiNode(ValueNode object, Stamp stamp, ValueNode guard) {
+        this(TYPE, object, stamp, (GuardingNode) guard);
     }
 
-    public PiNode(ValueNode object, ValueNode anchor) {
-        this(object, AbstractPointerStamp.pointerNonNull(object.stamp()), anchor);
+    public PiNode(ValueNode object, ValueNode guard) {
+        this(object, AbstractPointerStamp.pointerNonNull(object.stamp()), guard);
     }
 
     public PiNode(ValueNode object, ResolvedJavaType toType, boolean exactType, boolean nonNull) {
@@ -104,29 +104,29 @@
         return new PiNode(object, stamp);
     }
 
-    public static ValueNode create(ValueNode object, Stamp stamp, ValueNode anchor) {
-        ValueNode value = canonical(object, stamp, (GuardingNode) anchor);
+    public static ValueNode create(ValueNode object, Stamp stamp, ValueNode guard) {
+        ValueNode value = canonical(object, stamp, (GuardingNode) guard);
         if (value != null) {
             return value;
         }
-        return new PiNode(object, stamp, anchor);
+        return new PiNode(object, stamp, guard);
     }
 
-    public static ValueNode create(ValueNode object, ValueNode anchor) {
+    public static ValueNode create(ValueNode object, ValueNode guard) {
         Stamp stamp = AbstractPointerStamp.pointerNonNull(object.stamp());
-        ValueNode value = canonical(object, stamp, (GuardingNode) anchor);
+        ValueNode value = canonical(object, stamp, (GuardingNode) guard);
         if (value != null) {
             return value;
         }
-        return new PiNode(object, stamp, anchor);
+        return new PiNode(object, stamp, guard);
     }
 
     @SuppressWarnings("unused")
-    public static boolean intrinsify(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode object, ValueNode anchor) {
+    public static boolean intrinsify(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode object, ValueNode guard) {
         Stamp stamp = AbstractPointerStamp.pointerNonNull(object.stamp());
-        ValueNode value = canonical(object, stamp, (GuardingNode) anchor);
+        ValueNode value = canonical(object, stamp, (GuardingNode) guard);
         if (value == null) {
-            value = new PiNode(object, stamp, anchor);
+            value = new PiNode(object, stamp, guard);
         }
         b.push(JavaKind.Object, b.append(value));
         return true;
@@ -147,6 +147,11 @@
         return piStamp;
     }
 
+    public void strengthenPiStamp(Stamp newPiStamp) {
+        assert this.piStamp.join(newPiStamp).equals(newPiStamp) : "stamp can only improve";
+        this.piStamp = newPiStamp;
+    }
+
     @Override
     public void generate(NodeLIRBuilderTool generator) {
         if (generator.hasOperand(object)) {
@@ -256,17 +261,17 @@
 
     /**
      * Changes the stamp of an object and ensures the newly stamped value is non-null and does not
-     * float above a given anchor.
+     * float above a given guard.
      */
     @NodeIntrinsic
-    public static native Object piCastNonNull(Object object, GuardingNode anchor);
+    public static native Object piCastNonNull(Object object, GuardingNode guard);
 
     /**
      * Changes the stamp of an object and ensures the newly stamped value is non-null and does not
-     * float above a given anchor.
+     * float above a given guard.
      */
     @NodeIntrinsic
-    public static native Class<?> piCastNonNullClass(Class<?> type, GuardingNode anchor);
+    public static native Class<?> piCastNonNullClass(Class<?> type, GuardingNode guard);
 
     /**
      * Changes the stamp of an object to represent a given type and to indicate that the object is
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/ValuePhiNode.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/ValuePhiNode.java	Wed Nov 08 16:03:35 2017 -0500
@@ -22,6 +22,8 @@
  */
 package org.graalvm.compiler.nodes;
 
+import java.util.Map;
+
 import org.graalvm.compiler.core.common.type.Stamp;
 import org.graalvm.compiler.core.common.type.StampFactory;
 import org.graalvm.compiler.graph.NodeClass;
@@ -35,7 +37,7 @@
 /**
  * Value {@link PhiNode}s merge data flow values at control flow merges.
  */
-@NodeInfo(nameTemplate = "Phi({i#values})")
+@NodeInfo(nameTemplate = "Phi({i#values}, {p#valueDescription})")
 public class ValuePhiNode extends PhiNode implements ArrayLengthProvider {
 
     public static final NodeClass<ValuePhiNode> TYPE = NodeClass.create(ValuePhiNode.class);
@@ -113,4 +115,16 @@
         }
         return super.verify();
     }
+
+    @Override
+    protected String valueDescription() {
+        return stamp().unrestricted().toString();
+    }
+
+    @Override
+    public Map<Object, Object> getDebugProperties(Map<Object, Object> map) {
+        Map<Object, Object> properties = super.getDebugProperties(map);
+        properties.put("valueDescription", valueDescription());
+        return properties;
+    }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/BinaryArithmeticNode.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/BinaryArithmeticNode.java	Wed Nov 08 16:03:35 2017 -0500
@@ -91,7 +91,9 @@
     public static <OP> ConstantNode tryConstantFold(BinaryOp<OP> op, ValueNode forX, ValueNode forY, Stamp stamp) {
         if (forX.isConstant() && forY.isConstant()) {
             Constant ret = op.foldConstant(forX.asConstant(), forY.asConstant());
-            return ConstantNode.forPrimitive(stamp, ret);
+            if (ret != null) {
+                return ConstantNode.forPrimitive(stamp, ret);
+            }
         }
         return null;
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/ConditionalNode.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/ConditionalNode.java	Wed Nov 08 16:03:35 2017 -0500
@@ -22,7 +22,7 @@
  */
 package org.graalvm.compiler.nodes.calc;
 
-import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_0;
+import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_1;
 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_2;
 import static org.graalvm.compiler.nodes.calc.CompareNode.createCompareNode;
 
@@ -47,10 +47,10 @@
 import jdk.vm.ci.meta.JavaConstant;
 
 /**
- * The {@code ConditionalNode} class represents a comparison that yields one of two values. Note
- * that these nodes are not built directly from the bytecode but are introduced by canonicalization.
+ * The {@code ConditionalNode} class represents a comparison that yields one of two (eagerly
+ * evaluated) values.
  */
-@NodeInfo(cycles = CYCLES_0, size = SIZE_2)
+@NodeInfo(cycles = CYCLES_1, size = SIZE_2)
 public final class ConditionalNode extends FloatingNode implements Canonicalizable, LIRLowerable {
 
     public static final NodeClass<ConditionalNode> TYPE = NodeClass.create(ConditionalNode.class);
@@ -116,7 +116,6 @@
                     valueStamp = valueStamp.join(bounds);
                 }
             }
-
         }
         return updateStamp(valueStamp);
     }
@@ -145,49 +144,10 @@
     }
 
     public static ValueNode canonicalizeConditional(LogicNode condition, ValueNode trueValue, ValueNode falseValue, Stamp stamp) {
-        // this optimizes the case where a value from the range 0 - 1 is mapped to the range 0 - 1
-        if (trueValue.isConstant() && falseValue.isConstant() && trueValue.stamp() instanceof IntegerStamp && falseValue.stamp() instanceof IntegerStamp) {
-            long constTrueValue = trueValue.asJavaConstant().asLong();
-            long constFalseValue = falseValue.asJavaConstant().asLong();
-            if (condition instanceof IntegerEqualsNode) {
-                IntegerEqualsNode equals = (IntegerEqualsNode) condition;
-                if (equals.getY().isConstant() && equals.getX().stamp() instanceof IntegerStamp) {
-                    IntegerStamp equalsXStamp = (IntegerStamp) equals.getX().stamp();
-                    if (equalsXStamp.upMask() == 1) {
-                        long equalsY = equals.getY().asJavaConstant().asLong();
-                        if (equalsY == 0) {
-                            if (constTrueValue == 0 && constFalseValue == 1) {
-                                // return x when: x == 0 ? 0 : 1;
-                                return IntegerConvertNode.convertUnsigned(equals.getX(), stamp);
-                            } else if (constTrueValue == 1 && constFalseValue == 0) {
-                                // negate a boolean value via xor
-                                return IntegerConvertNode.convertUnsigned(XorNode.create(equals.getX(), ConstantNode.forIntegerStamp(equals.getX().stamp(), 1)), stamp);
-                            }
-                        } else if (equalsY == 1) {
-                            if (constTrueValue == 1 && constFalseValue == 0) {
-                                // return x when: x == 1 ? 1 : 0;
-                                return IntegerConvertNode.convertUnsigned(equals.getX(), stamp);
-                            } else if (constTrueValue == 0 && constFalseValue == 1) {
-                                // negate a boolean value via xor
-                                return IntegerConvertNode.convertUnsigned(XorNode.create(equals.getX(), ConstantNode.forIntegerStamp(equals.getX().stamp(), 1)), stamp);
-                            }
-                        }
-                    }
-                }
-            } else if (condition instanceof IntegerTestNode) {
-                // replace IntegerTestNode with AndNode for the following patterns:
-                // (value & 1) == 0 ? 0 : 1
-                // (value & 1) == 1 ? 1 : 0
-                IntegerTestNode integerTestNode = (IntegerTestNode) condition;
-                if (integerTestNode.getY().isConstant()) {
-                    assert integerTestNode.getX().stamp() instanceof IntegerStamp;
-                    long testY = integerTestNode.getY().asJavaConstant().asLong();
-                    if (testY == 1 && constTrueValue == 0 && constFalseValue == 1) {
-                        return IntegerConvertNode.convertUnsigned(AndNode.create(integerTestNode.getX(), integerTestNode.getY()), stamp);
-                    }
-                }
-            }
+        if (trueValue == falseValue) {
+            return trueValue;
         }
+
         if (condition instanceof CompareNode && ((CompareNode) condition).isIdentityComparison()) {
             // optimize the pattern (x == y) ? x : y
             CompareNode compare = (CompareNode) condition;
@@ -195,25 +155,87 @@
                 return falseValue;
             }
         }
-        if (trueValue == falseValue) {
-            return trueValue;
-        }
+
+        if (trueValue.stamp() instanceof IntegerStamp) {
+            // check if the conditional is redundant
+            if (condition instanceof IntegerLessThanNode) {
+                IntegerLessThanNode lessThan = (IntegerLessThanNode) condition;
+                IntegerStamp falseValueStamp = (IntegerStamp) falseValue.stamp();
+                IntegerStamp trueValueStamp = (IntegerStamp) trueValue.stamp();
+                if (lessThan.getX() == trueValue && lessThan.getY() == falseValue) {
+                    // return "x" for "x < y ? x : y" in case that we know "x <= y"
+                    if (trueValueStamp.upperBound() <= falseValueStamp.lowerBound()) {
+                        return trueValue;
+                    }
+                } else if (lessThan.getX() == falseValue && lessThan.getY() == trueValue) {
+                    // return "x" for "x < y ? y : x" in case that we know "x <= y"
+                    if (falseValueStamp.upperBound() <= trueValueStamp.lowerBound()) {
+                        return falseValue;
+                    }
+                }
+            }
 
-        if (condition instanceof IntegerLessThanNode && trueValue.stamp() instanceof IntegerStamp) {
-            /*
-             * Convert a conditional add ((x < 0) ? (x + y) : x) into (x + (y & (x >> (bits - 1))))
-             * to avoid the test.
-             */
-            IntegerLessThanNode lt = (IntegerLessThanNode) condition;
-            if (lt.getY().isConstant() && lt.getY().asConstant().isDefaultForKind()) {
-                if (falseValue == lt.getX()) {
-                    if (trueValue instanceof AddNode) {
-                        AddNode add = (AddNode) trueValue;
-                        if (add.getX() == falseValue) {
-                            int bits = ((IntegerStamp) trueValue.stamp()).getBits();
-                            ValueNode shift = new RightShiftNode(lt.getX(), ConstantNode.forIntegerBits(32, bits - 1));
-                            ValueNode and = new AndNode(shift, add.getY());
-                            return new AddNode(add.getX(), and);
+            // this optimizes the case where a value from the range 0 - 1 is mapped to the
+            // range 0 - 1
+            if (trueValue.isConstant() && falseValue.isConstant()) {
+                long constTrueValue = trueValue.asJavaConstant().asLong();
+                long constFalseValue = falseValue.asJavaConstant().asLong();
+                if (condition instanceof IntegerEqualsNode) {
+                    IntegerEqualsNode equals = (IntegerEqualsNode) condition;
+                    if (equals.getY().isConstant() && equals.getX().stamp() instanceof IntegerStamp) {
+                        IntegerStamp equalsXStamp = (IntegerStamp) equals.getX().stamp();
+                        if (equalsXStamp.upMask() == 1) {
+                            long equalsY = equals.getY().asJavaConstant().asLong();
+                            if (equalsY == 0) {
+                                if (constTrueValue == 0 && constFalseValue == 1) {
+                                    // return x when: x == 0 ? 0 : 1;
+                                    return IntegerConvertNode.convertUnsigned(equals.getX(), stamp);
+                                } else if (constTrueValue == 1 && constFalseValue == 0) {
+                                    // negate a boolean value via xor
+                                    return IntegerConvertNode.convertUnsigned(XorNode.create(equals.getX(), ConstantNode.forIntegerStamp(equals.getX().stamp(), 1)), stamp);
+                                }
+                            } else if (equalsY == 1) {
+                                if (constTrueValue == 1 && constFalseValue == 0) {
+                                    // return x when: x == 1 ? 1 : 0;
+                                    return IntegerConvertNode.convertUnsigned(equals.getX(), stamp);
+                                } else if (constTrueValue == 0 && constFalseValue == 1) {
+                                    // negate a boolean value via xor
+                                    return IntegerConvertNode.convertUnsigned(XorNode.create(equals.getX(), ConstantNode.forIntegerStamp(equals.getX().stamp(), 1)), stamp);
+                                }
+                            }
+                        }
+                    }
+                } else if (condition instanceof IntegerTestNode) {
+                    // replace IntegerTestNode with AndNode for the following patterns:
+                    // (value & 1) == 0 ? 0 : 1
+                    // (value & 1) == 1 ? 1 : 0
+                    IntegerTestNode integerTestNode = (IntegerTestNode) condition;
+                    if (integerTestNode.getY().isConstant()) {
+                        assert integerTestNode.getX().stamp() instanceof IntegerStamp;
+                        long testY = integerTestNode.getY().asJavaConstant().asLong();
+                        if (testY == 1 && constTrueValue == 0 && constFalseValue == 1) {
+                            return IntegerConvertNode.convertUnsigned(AndNode.create(integerTestNode.getX(), integerTestNode.getY()), stamp);
+                        }
+                    }
+                }
+            }
+
+            if (condition instanceof IntegerLessThanNode) {
+                /*
+                 * Convert a conditional add ((x < 0) ? (x + y) : x) into (x + (y & (x >> (bits -
+                 * 1)))) to avoid the test.
+                 */
+                IntegerLessThanNode lt = (IntegerLessThanNode) condition;
+                if (lt.getY().isConstant() && lt.getY().asConstant().isDefaultForKind()) {
+                    if (falseValue == lt.getX()) {
+                        if (trueValue instanceof AddNode) {
+                            AddNode add = (AddNode) trueValue;
+                            if (add.getX() == falseValue) {
+                                int bits = ((IntegerStamp) trueValue.stamp()).getBits();
+                                ValueNode shift = new RightShiftNode(lt.getX(), ConstantNode.forIntegerBits(32, bits - 1));
+                                ValueNode and = new AndNode(shift, add.getY());
+                                return new AddNode(add.getX(), and);
+                            }
                         }
                     }
                 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/DivNode.java	Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,109 +0,0 @@
-/*
- * 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
- * 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 org.graalvm.compiler.nodes.calc;
-
-import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_32;
-
-import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
-import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp;
-import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp.Div;
-import org.graalvm.compiler.core.common.type.Stamp;
-import org.graalvm.compiler.graph.NodeClass;
-import org.graalvm.compiler.graph.spi.CanonicalizerTool;
-import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool;
-import org.graalvm.compiler.nodeinfo.NodeInfo;
-import org.graalvm.compiler.nodes.ConstantNode;
-import org.graalvm.compiler.nodes.ValueNode;
-import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
-
-import jdk.vm.ci.code.CodeUtil;
-import jdk.vm.ci.meta.Constant;
-import jdk.vm.ci.meta.PrimitiveConstant;
-
-@NodeInfo(shortName = "/", cycles = CYCLES_32)
-public class DivNode extends BinaryArithmeticNode<Div> {
-
-    public static final NodeClass<DivNode> TYPE = NodeClass.create(DivNode.class);
-
-    public DivNode(ValueNode x, ValueNode y) {
-        super(TYPE, ArithmeticOpTable::getDiv, x, y);
-    }
-
-    protected DivNode(NodeClass<? extends DivNode> c, ValueNode x, ValueNode y) {
-        super(c, ArithmeticOpTable::getDiv, x, y);
-    }
-
-    public static ValueNode create(ValueNode x, ValueNode y) {
-        BinaryOp<Div> op = ArithmeticOpTable.forStamp(x.stamp()).getDiv();
-        Stamp stamp = op.foldStamp(x.stamp(), y.stamp());
-        ConstantNode tryConstantFold = tryConstantFold(op, x, y, stamp);
-        if (tryConstantFold != null) {
-            return tryConstantFold;
-        }
-        return canonical(null, op, x, y);
-    }
-
-    @Override
-    public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
-        ValueNode ret = super.canonical(tool, forX, forY);
-        if (ret != this) {
-            return ret;
-        }
-
-        return canonical(this, getOp(forX, forY), forX, forY);
-    }
-
-    private static ValueNode canonical(DivNode self, BinaryOp<Div> op, ValueNode forX, ValueNode forY) {
-        if (forY.isConstant()) {
-            Constant c = forY.asConstant();
-            if (op.isNeutral(c)) {
-                return forX;
-            }
-            if (c instanceof PrimitiveConstant && ((PrimitiveConstant) c).getJavaKind().isNumericInteger()) {
-                long i = ((PrimitiveConstant) c).asLong();
-                boolean signFlip = false;
-                if (i < 0) {
-                    i = -i;
-                    signFlip = true;
-                }
-                ValueNode divResult = null;
-                if (CodeUtil.isPowerOf2(i)) {
-                    divResult = new RightShiftNode(forX, ConstantNode.forInt(CodeUtil.log2(i)));
-                }
-                if (divResult != null) {
-                    if (signFlip) {
-                        return NegateNode.create(divResult);
-                    } else {
-                        return divResult;
-                    }
-                }
-            }
-        }
-        return self != null ? self : new DivNode(forX, forY);
-    }
-
-    @Override
-    public void generate(NodeLIRBuilderTool nodeValueMap, ArithmeticLIRGeneratorTool gen) {
-        nodeValueMap.setResult(this, gen.emitDiv(nodeValueMap.operand(getX()), nodeValueMap.operand(getY()), null));
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/FloatDivNode.java	Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,90 @@
+/*
+ * 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
+ * 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 org.graalvm.compiler.nodes.calc;
+
+import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_32;
+
+import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
+import org.graalvm.compiler.core.common.type.FloatStamp;
+import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp;
+import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp.Div;
+import org.graalvm.compiler.core.common.type.Stamp;
+import org.graalvm.compiler.graph.NodeClass;
+import org.graalvm.compiler.graph.spi.CanonicalizerTool;
+import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool;
+import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.ValueNode;
+import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
+
+import jdk.vm.ci.meta.Constant;
+
+@NodeInfo(shortName = "/", cycles = CYCLES_32)
+public class FloatDivNode extends BinaryArithmeticNode<Div> {
+
+    public static final NodeClass<FloatDivNode> TYPE = NodeClass.create(FloatDivNode.class);
+
+    public FloatDivNode(ValueNode x, ValueNode y) {
+        this(TYPE, x, y);
+    }
+
+    protected FloatDivNode(NodeClass<? extends FloatDivNode> c, ValueNode x, ValueNode y) {
+        super(c, ArithmeticOpTable::getDiv, x, y);
+        assert stamp instanceof FloatStamp;
+    }
+
+    public static ValueNode create(ValueNode x, ValueNode y) {
+        BinaryOp<Div> op = ArithmeticOpTable.forStamp(x.stamp()).getDiv();
+        Stamp stamp = op.foldStamp(x.stamp(), y.stamp());
+        ConstantNode tryConstantFold = tryConstantFold(op, x, y, stamp);
+        if (tryConstantFold != null) {
+            return tryConstantFold;
+        }
+        return canonical(null, op, x, y);
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
+        ValueNode ret = super.canonical(tool, forX, forY);
+        if (ret != this) {
+            return ret;
+        }
+
+        return canonical(this, getOp(forX, forY), forX, forY);
+    }
+
+    private static ValueNode canonical(FloatDivNode self, BinaryOp<Div> op, ValueNode forX, ValueNode forY) {
+        if (forY.isConstant()) {
+            Constant c = forY.asConstant();
+            if (op.isNeutral(c)) {
+                return forX;
+            }
+        }
+        return self != null ? self : new FloatDivNode(forX, forY);
+    }
+
+    @Override
+    public void generate(NodeLIRBuilderTool nodeValueMap, ArithmeticLIRGeneratorTool gen) {
+        nodeValueMap.setResult(this, gen.emitDiv(nodeValueMap.operand(getX()), nodeValueMap.operand(getY()), null));
+    }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerConvertNode.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerConvertNode.java	Wed Nov 08 16:03:35 2017 -0500
@@ -129,7 +129,7 @@
         ValueNode convert = convert(input, stamp, false);
         if (!convert.isAlive()) {
             assert !convert.isDeleted();
-            convert = graph.addOrUnique(convert);
+            convert = graph.addOrUniqueWithInputs(convert);
         }
         return convert;
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerLessThanNode.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerLessThanNode.java	Wed Nov 08 16:03:35 2017 -0500
@@ -52,7 +52,7 @@
 @NodeInfo(shortName = "<")
 public final class IntegerLessThanNode extends IntegerLowerThanNode {
     public static final NodeClass<IntegerLessThanNode> TYPE = NodeClass.create(IntegerLessThanNode.class);
-    public static final LessThanOp OP = new LessThanOp();
+    private static final LessThanOp OP = new LessThanOp();
 
     public IntegerLessThanNode(ValueNode x, ValueNode y) {
         super(TYPE, x, y, OP);
@@ -203,49 +203,52 @@
                 }
             }
 
-            int bits = ((IntegerStamp) forX.stamp()).getBits();
-            assert ((IntegerStamp) forY.stamp()).getBits() == bits;
-            long min = OP.minValue(bits);
-            long xResidue = 0;
-            ValueNode left = null;
-            JavaConstant leftCst = null;
-            if (forX instanceof AddNode) {
-                AddNode xAdd = (AddNode) forX;
-                if (xAdd.getY().isJavaConstant()) {
-                    long xCst = xAdd.getY().asJavaConstant().asLong();
-                    xResidue = xCst - min;
-                    left = xAdd.getX();
+            if (forX.stamp() instanceof IntegerStamp) {
+                assert forY.stamp() instanceof IntegerStamp;
+                int bits = ((IntegerStamp) forX.stamp()).getBits();
+                assert ((IntegerStamp) forY.stamp()).getBits() == bits;
+                long min = OP.minValue(bits);
+                long xResidue = 0;
+                ValueNode left = null;
+                JavaConstant leftCst = null;
+                if (forX instanceof AddNode) {
+                    AddNode xAdd = (AddNode) forX;
+                    if (xAdd.getY().isJavaConstant()) {
+                        long xCst = xAdd.getY().asJavaConstant().asLong();
+                        xResidue = xCst - min;
+                        left = xAdd.getX();
+                    }
+                } else if (forX.isJavaConstant()) {
+                    leftCst = forX.asJavaConstant();
                 }
-            } else if (forX.isJavaConstant()) {
-                leftCst = forX.asJavaConstant();
-            }
-            if (left != null || leftCst != null) {
-                long yResidue = 0;
-                ValueNode right = null;
-                JavaConstant rightCst = null;
-                if (forY instanceof AddNode) {
-                    AddNode yAdd = (AddNode) forY;
-                    if (yAdd.getY().isJavaConstant()) {
-                        long yCst = yAdd.getY().asJavaConstant().asLong();
-                        yResidue = yCst - min;
-                        right = yAdd.getX();
+                if (left != null || leftCst != null) {
+                    long yResidue = 0;
+                    ValueNode right = null;
+                    JavaConstant rightCst = null;
+                    if (forY instanceof AddNode) {
+                        AddNode yAdd = (AddNode) forY;
+                        if (yAdd.getY().isJavaConstant()) {
+                            long yCst = yAdd.getY().asJavaConstant().asLong();
+                            yResidue = yCst - min;
+                            right = yAdd.getX();
+                        }
+                    } else if (forY.isJavaConstant()) {
+                        rightCst = forY.asJavaConstant();
                     }
-                } else if (forY.isJavaConstant()) {
-                    rightCst = forY.asJavaConstant();
-                }
-                if (right != null || rightCst != null) {
-                    if ((xResidue == 0 && left != null) || (yResidue == 0 && right != null)) {
-                        if (left == null) {
-                            left = ConstantNode.forIntegerBits(bits, leftCst.asLong() - min);
-                        } else if (xResidue != 0) {
-                            left = AddNode.create(left, ConstantNode.forIntegerBits(bits, xResidue));
+                    if (right != null || rightCst != null) {
+                        if ((xResidue == 0 && left != null) || (yResidue == 0 && right != null)) {
+                            if (left == null) {
+                                left = ConstantNode.forIntegerBits(bits, leftCst.asLong() - min);
+                            } else if (xResidue != 0) {
+                                left = AddNode.create(left, ConstantNode.forIntegerBits(bits, xResidue));
+                            }
+                            if (right == null) {
+                                right = ConstantNode.forIntegerBits(bits, rightCst.asLong() - min);
+                            } else if (yResidue != 0) {
+                                right = AddNode.create(right, ConstantNode.forIntegerBits(bits, yResidue));
+                            }
+                            return new IntegerBelowNode(left, right);
                         }
-                        if (right == null) {
-                            right = ConstantNode.forIntegerBits(bits, rightCst.asLong() - min);
-                        } else if (yResidue != 0) {
-                            right = AddNode.create(right, ConstantNode.forIntegerBits(bits, yResidue));
-                        }
-                        return new IntegerBelowNode(left, right);
                     }
                 }
             }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IsNullNode.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IsNullNode.java	Wed Nov 08 16:03:35 2017 -0500
@@ -121,7 +121,8 @@
 
     @Override
     public Stamp getSucceedingStampForValue(boolean negated) {
-        AbstractPointerStamp pointerStamp = (AbstractPointerStamp) getValue().stamp();
+        // Ignore any more precise input stamp since canonicalization will skip through PiNodes
+        AbstractPointerStamp pointerStamp = (AbstractPointerStamp) getValue().stamp().unrestricted();
         return negated ? pointerStamp.asNonNull() : pointerStamp.asAlwaysNull();
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/SignedDivNode.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/SignedDivNode.java	Wed Nov 08 16:03:35 2017 -0500
@@ -63,29 +63,9 @@
             return ConstantNode.forIntegerStamp(stamp(), forX.asJavaConstant().asLong() / y);
         } else if (forY.isConstant()) {
             long c = forY.asJavaConstant().asLong();
-            if (c == 1) {
-                return forX;
-            }
-            if (c == -1) {
-                return NegateNode.create(forX);
-            }
-            long abs = Math.abs(c);
-            if (CodeUtil.isPowerOf2(abs) && forX.stamp() instanceof IntegerStamp) {
-                ValueNode dividend = forX;
-                IntegerStamp stampX = (IntegerStamp) forX.stamp();
-                int log2 = CodeUtil.log2(abs);
-                // no rounding if dividend is positive or if its low bits are always 0
-                if (stampX.canBeNegative() || (stampX.upMask() & (abs - 1)) != 0) {
-                    int bits = PrimitiveStamp.getBits(stamp());
-                    RightShiftNode sign = new RightShiftNode(forX, ConstantNode.forInt(bits - 1));
-                    UnsignedRightShiftNode round = new UnsignedRightShiftNode(sign, ConstantNode.forInt(bits - log2));
-                    dividend = BinaryArithmeticNode.add(dividend, round);
-                }
-                RightShiftNode shift = new RightShiftNode(dividend, ConstantNode.forInt(log2));
-                if (c < 0) {
-                    return NegateNode.create(shift);
-                }
-                return shift;
+            ValueNode v = canonical(forX, c);
+            if (v != null) {
+                return v;
             }
         }
 
@@ -113,6 +93,34 @@
         return this;
     }
 
+    public static ValueNode canonical(ValueNode forX, long c) {
+        if (c == 1) {
+            return forX;
+        }
+        if (c == -1) {
+            return NegateNode.create(forX);
+        }
+        long abs = Math.abs(c);
+        if (CodeUtil.isPowerOf2(abs) && forX.stamp() instanceof IntegerStamp) {
+            ValueNode dividend = forX;
+            IntegerStamp stampX = (IntegerStamp) forX.stamp();
+            int log2 = CodeUtil.log2(abs);
+            // no rounding if dividend is positive or if its low bits are always 0
+            if (stampX.canBeNegative() || (stampX.upMask() & (abs - 1)) != 0) {
+                int bits = PrimitiveStamp.getBits(forX.stamp());
+                RightShiftNode sign = new RightShiftNode(forX, ConstantNode.forInt(bits - 1));
+                UnsignedRightShiftNode round = new UnsignedRightShiftNode(sign, ConstantNode.forInt(bits - log2));
+                dividend = BinaryArithmeticNode.add(dividend, round);
+            }
+            RightShiftNode shift = new RightShiftNode(dividend, ConstantNode.forInt(log2));
+            if (c < 0) {
+                return NegateNode.create(shift);
+            }
+            return shift;
+        }
+        return null;
+    }
+
     @Override
     public void generate(NodeLIRBuilderTool gen) {
         gen.setResult(this, gen.getLIRGeneratorTool().getArithmetic().emitDiv(gen.operand(getX()), gen.operand(getY()), gen.state(this)));
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/SignedRemNode.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/SignedRemNode.java	Wed Nov 08 16:03:35 2017 -0500
@@ -72,13 +72,14 @@
                 return ConstantNode.forIntegerStamp(stamp(), 0);
             } else if (CodeUtil.isPowerOf2(constY)) {
                 if (xStamp.isPositive()) {
+                    // x & (y - 1)
                     return new AndNode(forX, ConstantNode.forIntegerStamp(stamp(), constY - 1));
                 } else if (xStamp.isNegative()) {
+                    // -((-x) & (y - 1))
                     return new NegateNode(new AndNode(new NegateNode(forX), ConstantNode.forIntegerStamp(stamp(), constY - 1)));
                 } else {
-                    return new ConditionalNode(IntegerLessThanNode.create(forX, ConstantNode.forIntegerStamp(forX.stamp(), 0)),
-                                    new NegateNode(new AndNode(new NegateNode(forX), ConstantNode.forIntegerStamp(stamp(), constY - 1))),
-                                    new AndNode(forX, ConstantNode.forIntegerStamp(stamp(), constY - 1)));
+                    // x - ((x / y) << log2(y))
+                    return SubNode.create(forX, LeftShiftNode.create(SignedDivNode.canonical(forX, constY), ConstantNode.forInt(CodeUtil.log2(constY))));
                 }
             }
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/UnaryNode.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/UnaryNode.java	Wed Nov 08 16:03:35 2017 -0500
@@ -45,6 +45,11 @@
         return value;
     }
 
+    public void setValue(ValueNode value) {
+        updateUsages(this.value, value);
+        this.value = value;
+    }
+
     /**
      * Creates a new UnaryNode instance.
      *
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/UnpackEndianHalfNode.java	Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 org.graalvm.compiler.nodes.calc;
+
+import java.nio.ByteOrder;
+
+import org.graalvm.compiler.core.common.type.StampFactory;
+import org.graalvm.compiler.graph.Node;
+import org.graalvm.compiler.graph.NodeClass;
+import org.graalvm.compiler.graph.spi.CanonicalizerTool;
+import org.graalvm.compiler.nodeinfo.NodeCycles;
+import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.ValueNode;
+import org.graalvm.compiler.nodes.spi.Lowerable;
+import org.graalvm.compiler.nodes.spi.LoweringTool;
+
+import jdk.vm.ci.meta.JavaKind;
+
+/**
+ * Produces the platform dependent first or second half of a long or double value as an int.
+ */
+@NodeInfo(cycles = NodeCycles.CYCLES_2)
+public final class UnpackEndianHalfNode extends UnaryNode implements Lowerable {
+    public static final NodeClass<UnpackEndianHalfNode> TYPE = NodeClass.create(UnpackEndianHalfNode.class);
+
+    private final boolean firstHalf;
+
+    protected UnpackEndianHalfNode(ValueNode value, boolean firstHalf) {
+        super(TYPE, StampFactory.forKind(JavaKind.Int), value);
+        assert value.getStackKind() == JavaKind.Double || value.getStackKind() == JavaKind.Long : "unexpected kind " + value.getStackKind();
+        this.firstHalf = firstHalf;
+    }
+
+    public static ValueNode create(ValueNode value, boolean firstHalf) {
+        if (value.isConstant() && value.asConstant().isDefaultForKind()) {
+            return ConstantNode.defaultForKind(JavaKind.Int);
+        }
+        return new UnpackEndianHalfNode(value, firstHalf);
+    }
+
+    public boolean isFirstHalf() {
+        return firstHalf;
+    }
+
+    @Override
+    public Node canonical(CanonicalizerTool tool, ValueNode forValue) {
+        if (forValue.isConstant() && forValue.asConstant().isDefaultForKind()) {
+            return ConstantNode.defaultForKind(stamp.getStackKind());
+        }
+        return this;
+    }
+
+    @Override
+    public void lower(LoweringTool tool) {
+        tool.getLowerer().lower(this, tool);
+    }
+
+    public void lower(ByteOrder byteOrder) {
+        ValueNode result = value;
+        if (value.getStackKind() == JavaKind.Double) {
+            result = graph().unique(new ReinterpretNode(JavaKind.Long, value));
+        }
+        if ((byteOrder == ByteOrder.BIG_ENDIAN) == firstHalf) {
+            result = graph().unique(new UnsignedRightShiftNode(result, ConstantNode.forInt(32, graph())));
+        }
+        result = IntegerConvertNode.convert(result, StampFactory.forKind(JavaKind.Int), graph());
+        replaceAtUsagesAndDelete(result);
+    }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/cfg/ControlFlowGraph.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/cfg/ControlFlowGraph.java	Wed Nov 08 16:03:35 2017 -0500
@@ -592,7 +592,11 @@
             for (Block block : reversePostOrder) {
                 AbstractBeginNode beginNode = block.getBeginNode();
                 if (beginNode instanceof LoopBeginNode) {
-                    Loop<Block> loop = new HIRLoop(block.getLoop(), loops.size(), block);
+                    Loop<Block> parent = block.getLoop();
+                    Loop<Block> loop = new HIRLoop(parent, loops.size(), block);
+                    if (parent != null) {
+                        parent.getChildren().add(loop);
+                    }
                     loops.add(loop);
                     block.setLoop(loop);
                     loop.getBlocks().add(block);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/BranchProbabilityNode.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/BranchProbabilityNode.java	Wed Nov 08 16:03:35 2017 -0500
@@ -82,6 +82,9 @@
 
     @Override
     public void simplify(SimplifierTool tool) {
+        if (!hasUsages()) {
+            return;
+        }
         if (probability.isConstant()) {
             double probabilityValue = probability.asJavaConstant().asDouble();
             if (probabilityValue < 0.0) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/RawLoadNode.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/RawLoadNode.java	Wed Nov 08 16:03:35 2017 -0500
@@ -79,7 +79,7 @@
         super(TYPE, stamp, object, offset, accessKind, locationIdentity, false);
     }
 
-    public RawLoadNode(NodeClass<? extends RawLoadNode> c, ValueNode object, ValueNode offset, JavaKind accessKind, LocationIdentity locationIdentity) {
+    protected RawLoadNode(NodeClass<? extends RawLoadNode> c, ValueNode object, ValueNode offset, JavaKind accessKind, LocationIdentity locationIdentity) {
         super(c, StampFactory.forKind(accessKind.getStackKind()), object, offset, accessKind, locationIdentity, false);
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/RawStoreNode.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/RawStoreNode.java	Wed Nov 08 16:03:35 2017 -0500
@@ -29,7 +29,6 @@
 import org.graalvm.compiler.core.common.type.StampFactory;
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
-import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.nodes.FrameState;
 import org.graalvm.compiler.nodes.StateSplit;
 import org.graalvm.compiler.nodes.ValueNode;
@@ -39,12 +38,10 @@
 import org.graalvm.compiler.nodes.spi.LoweringTool;
 import org.graalvm.compiler.nodes.spi.Virtualizable;
 import org.graalvm.compiler.nodes.spi.VirtualizerTool;
-import org.graalvm.compiler.nodes.type.StampTool;
 import org.graalvm.compiler.nodes.virtual.VirtualObjectNode;
 import org.graalvm.word.LocationIdentity;
 
 import jdk.vm.ci.meta.Assumptions;
-import jdk.vm.ci.meta.JavaConstant;
 import jdk.vm.ci.meta.JavaKind;
 import jdk.vm.ci.meta.ResolvedJavaField;
 
@@ -123,41 +120,8 @@
             if (indexValue.isConstant()) {
                 long off = indexValue.asJavaConstant().asLong();
                 int entryIndex = virtual.entryIndexForOffset(off, accessKind());
-                if (entryIndex != -1) {
-                    JavaKind entryKind = virtual.entryKind(entryIndex);
-                    boolean canVirtualize = entryKind == accessKind() || (entryKind == accessKind().getStackKind() && !StampTool.typeOrNull(object()).isArray());
-                    if (!canVirtualize) {
-                        /*
-                         * Special case: If the entryKind is long, allow arbitrary kinds as long as
-                         * a value of the same kind is already there. This can only happen if some
-                         * other node initialized the entry with a value of a different kind. One
-                         * example where this happens is the Truffle NewFrameNode.
-                         */
-                        ValueNode entry = tool.getEntry(virtual, entryIndex);
-                        if (entryKind == JavaKind.Long && entry.getStackKind() == value.getStackKind()) {
-                            canVirtualize = true;
-                        }
-                    }
-                    if (canVirtualize) {
-                        tool.setVirtualEntry(virtual, entryIndex, value(), true);
-                        tool.delete();
-                    } else {
-                        /*
-                         * Special case: Allow storing a single long or double value into two
-                         * consecutive int slots.
-                         */
-                        if ((accessKind() == JavaKind.Long || accessKind() == JavaKind.Double) && entryKind == JavaKind.Int) {
-                            int nextIndex = virtual.entryIndexForOffset(off + 4, entryKind);
-                            if (nextIndex != -1) {
-                                JavaKind nextKind = virtual.entryKind(nextIndex);
-                                if (nextKind == JavaKind.Int) {
-                                    tool.setVirtualEntry(virtual, entryIndex, value(), true);
-                                    tool.setVirtualEntry(virtual, nextIndex, ConstantNode.forConstant(JavaConstant.forIllegal(), tool.getMetaAccessProvider(), graph()), true);
-                                    tool.delete();
-                                }
-                            }
-                        }
-                    }
+                if (entryIndex != -1 && tool.setVirtualEntry(virtual, entryIndex, value(), accessKind(), off)) {
+                    tool.delete();
                 }
             }
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/GraphBuilderContext.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/GraphBuilderContext.java	Wed Nov 08 16:03:35 2017 -0500
@@ -280,7 +280,7 @@
             ObjectStamp receiverStamp = (ObjectStamp) value.stamp();
             Stamp stamp = receiverStamp.join(objectNonNull());
             FixedGuardNode fixedGuard = append(new FixedGuardNode(condition, NullCheckException, action, true));
-            ValueNode nonNullReceiver = getGraph().addOrUnique(PiNode.create(value, stamp, fixedGuard));
+            ValueNode nonNullReceiver = getGraph().addOrUniqueWithInputs(PiNode.create(value, stamp, fixedGuard));
             // TODO: Propogating the non-null into the frame state would
             // remove subsequent null-checks on the same value. However,
             // it currently causes an assertion failure when merging states.
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/InlineInvokePlugin.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/InlineInvokePlugin.java	Wed Nov 08 16:03:35 2017 -0500
@@ -53,6 +53,12 @@
          */
         public static final InlineInfo DO_NOT_INLINE_NO_EXCEPTION = new InlineInfo(null, null);
 
+        /**
+         * Denotes a call site must not be inlined and the execution should be transferred to
+         * interpreter in case of an exception.
+         */
+        public static final InlineInfo DO_NOT_INLINE_DEOPTIMIZE_ON_EXCEPTION = new InlineInfo(null, null);
+
         private final ResolvedJavaMethod methodToInline;
         private final BytecodeProvider intrinsicBytecodeProvider;
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/IntrinsicContext.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/IntrinsicContext.java	Wed Nov 08 16:03:35 2017 -0500
@@ -66,6 +66,34 @@
      */
     final BytecodeProvider bytecodeProvider;
 
+    final CompilationContext compilationContext;
+
+    final boolean allowPartialIntrinsicArgumentMismatch;
+
+    public IntrinsicContext(ResolvedJavaMethod method, ResolvedJavaMethod intrinsic, BytecodeProvider bytecodeProvider, CompilationContext compilationContext) {
+        this(method, intrinsic, bytecodeProvider, compilationContext, false);
+    }
+
+    public IntrinsicContext(ResolvedJavaMethod method, ResolvedJavaMethod intrinsic, BytecodeProvider bytecodeProvider, CompilationContext compilationContext,
+                    boolean allowPartialIntrinsicArgumentMismatch) {
+        this.method = method;
+        this.intrinsic = intrinsic;
+        this.bytecodeProvider = bytecodeProvider;
+        assert bytecodeProvider != null;
+        this.compilationContext = compilationContext;
+        this.allowPartialIntrinsicArgumentMismatch = allowPartialIntrinsicArgumentMismatch;
+        assert !isCompilationRoot() || method.hasBytecodes() : "Cannot root compile intrinsic for native or abstract method " + method.format("%H.%n(%p)");
+    }
+
+    /**
+     * A partial intrinsic exits by (effectively) calling the intrinsified method. Normally, this
+     * call must use exactly the same arguments as the call that is being intrinsified. This allows
+     * to override this behavior.
+     */
+    public boolean allowPartialIntrinsicArgumentMismatch() {
+        return allowPartialIntrinsicArgumentMismatch;
+    }
+
     /**
      * Gets the method being intrinsified.
      */
@@ -96,17 +124,6 @@
         return method.equals(targetMethod) || intrinsic.equals(targetMethod);
     }
 
-    final CompilationContext compilationContext;
-
-    public IntrinsicContext(ResolvedJavaMethod method, ResolvedJavaMethod intrinsic, BytecodeProvider bytecodeProvider, CompilationContext compilationContext) {
-        this.method = method;
-        this.intrinsic = intrinsic;
-        this.bytecodeProvider = bytecodeProvider;
-        assert bytecodeProvider != null;
-        this.compilationContext = compilationContext;
-        assert !isCompilationRoot() || method.hasBytecodes() : "Cannot root compile intrinsic for native or abstract method " + method.format("%H.%n(%p)");
-    }
-
     public boolean isPostParseInlined() {
         return compilationContext.equals(INLINE_AFTER_PARSING);
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/InstanceOfNode.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/InstanceOfNode.java	Wed Nov 08 16:03:35 2017 -0500
@@ -49,6 +49,8 @@
 import jdk.vm.ci.meta.JavaTypeProfile;
 import jdk.vm.ci.meta.TriState;
 
+import java.util.Objects;
+
 /**
  * The {@code InstanceOfNode} represents an instanceof test.
  */
@@ -56,7 +58,7 @@
 public class InstanceOfNode extends UnaryOpLogicNode implements Lowerable, Virtualizable {
     public static final NodeClass<InstanceOfNode> TYPE = NodeClass.create(InstanceOfNode.class);
 
-    protected final ObjectStamp checkedStamp;
+    private ObjectStamp checkedStamp;
 
     private JavaTypeProfile profile;
     @OptionalInput(Anchor) protected AnchoringNode anchor;
@@ -126,7 +128,9 @@
                 // The check will always succeed, the union of the two stamps is equal to the
                 // checked stamp.
                 return LogicConstantNode.tautology();
-            } else if (checkedStamp.type().equals(meetStamp.type()) && checkedStamp.isExactType() == meetStamp.isExactType() && checkedStamp.alwaysNull() == meetStamp.alwaysNull()) {
+            } else if (checkedStamp.alwaysNull()) {
+                return IsNullNode.create(object);
+            } else if (Objects.equals(checkedStamp.type(), meetStamp.type()) && checkedStamp.isExactType() == meetStamp.isExactType() && checkedStamp.alwaysNull() == meetStamp.alwaysNull()) {
                 assert checkedStamp.nonNull() != inputStamp.nonNull();
                 // The only difference makes the null-ness of the value => simplify the check.
                 if (checkedStamp.nonNull()) {
@@ -135,8 +139,8 @@
                     return IsNullNode.create(object);
                 }
             }
+            assert checkedStamp.type() != null;
         }
-
         return null;
     }
 
@@ -204,4 +208,13 @@
     public AnchoringNode getAnchor() {
         return anchor;
     }
+
+    public ObjectStamp getCheckedStamp() {
+        return checkedStamp;
+    }
+
+    public void strengthenCheckedStamp(ObjectStamp newCheckedStamp) {
+        assert this.checkedStamp.join(newCheckedStamp).equals(newCheckedStamp) : "stamp can only improve";
+        this.checkedStamp = newCheckedStamp;
+    }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/LoadFieldNode.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/LoadFieldNode.java	Wed Nov 08 16:03:35 2017 -0500
@@ -25,7 +25,6 @@
 import static org.graalvm.compiler.graph.iterators.NodePredicates.isNotA;
 import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_2;
 
-import jdk.vm.ci.meta.ConstantReflectionProvider;
 import org.graalvm.compiler.core.common.spi.ConstantFieldProvider;
 import org.graalvm.compiler.core.common.type.Stamp;
 import org.graalvm.compiler.core.common.type.StampFactory;
@@ -47,15 +46,16 @@
 import org.graalvm.compiler.nodes.util.ConstantFoldUtil;
 import org.graalvm.compiler.nodes.virtual.VirtualInstanceNode;
 import org.graalvm.compiler.nodes.virtual.VirtualObjectNode;
+import org.graalvm.compiler.options.OptionValues;
 
 import jdk.vm.ci.meta.Assumptions;
+import jdk.vm.ci.meta.ConstantReflectionProvider;
 import jdk.vm.ci.meta.DeoptimizationAction;
 import jdk.vm.ci.meta.DeoptimizationReason;
 import jdk.vm.ci.meta.JavaConstant;
 import jdk.vm.ci.meta.JavaKind;
 import jdk.vm.ci.meta.MetaAccessProvider;
 import jdk.vm.ci.meta.ResolvedJavaField;
-import org.graalvm.compiler.options.OptionValues;
 
 /**
  * The {@code LoadFieldNode} represents a read of a static or instance field.
@@ -150,7 +150,7 @@
     }
 
     public ConstantNode asConstant(CanonicalizerTool tool, JavaConstant constant) {
-        return ConstantFoldUtil.tryConstantFold(tool.getConstantFieldProvider(), tool.getConstantReflection(), tool.getMetaAccess(), field(), constant, getOptions());
+        return ConstantFoldUtil.tryConstantFold(tool.getConstantFieldProvider(), tool.getConstantReflection(), tool.getMetaAccess(), field(), constant, tool.getOptions());
     }
 
     private static PhiNode asPhi(ConstantFieldProvider constantFields, ConstantReflectionProvider constantReflection,
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/StoreFieldNode.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/StoreFieldNode.java	Wed Nov 08 16:03:35 2017 -0500
@@ -29,7 +29,6 @@
 import org.graalvm.compiler.nodeinfo.InputType;
 import org.graalvm.compiler.nodeinfo.NodeCycles;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
-import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.nodes.FrameState;
 import org.graalvm.compiler.nodes.StateSplit;
 import org.graalvm.compiler.nodes.ValueNode;
@@ -38,7 +37,6 @@
 import org.graalvm.compiler.nodes.virtual.VirtualInstanceNode;
 import org.graalvm.compiler.nodes.virtual.VirtualObjectNode;
 
-import jdk.vm.ci.meta.JavaConstant;
 import jdk.vm.ci.meta.ResolvedJavaField;
 
 /**
@@ -90,15 +88,8 @@
             VirtualInstanceNode virtual = (VirtualInstanceNode) alias;
             int fieldIndex = virtual.fieldIndex(field());
             if (fieldIndex != -1) {
-                ValueNode existing = tool.getEntry((VirtualObjectNode) alias, fieldIndex);
-                if (existing.stamp().isCompatible(value().stamp())) {
-                    tool.setVirtualEntry(virtual, fieldIndex, value(), false);
-                    tool.delete();
-                } else {
-                    // stamp of the value is not compatible with the value in the virtualizer
-                    // can only happen with unsafe two slot writes on one slot fields
-                    assert existing instanceof ConstantNode && ((ConstantNode) existing).asConstant().equals(JavaConstant.forIllegal()) : value.stamp() + " vs " + existing.stamp();
-                }
+                tool.setVirtualEntry(virtual, fieldIndex, value());
+                tool.delete();
             }
         }
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/StoreIndexedNode.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/StoreIndexedNode.java	Wed Nov 08 16:03:35 2017 -0500
@@ -89,7 +89,7 @@
                 ResolvedJavaType componentType = virtual.type().getComponentType();
                 if (componentType.isPrimitive() || StampTool.isPointerAlwaysNull(value) || componentType.getSuperclass() == null ||
                                 (StampTool.typeReferenceOrNull(value) != null && componentType.isAssignableFrom(StampTool.typeOrNull(value)))) {
-                    tool.setVirtualEntry(virtual, idx, value(), false);
+                    tool.setVirtualEntry(virtual, idx, value());
                     tool.delete();
                 }
             }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/MemoryPhiNode.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/MemoryPhiNode.java	Wed Nov 08 16:03:35 2017 -0500
@@ -62,4 +62,9 @@
     public NodeInputList<ValueNode> values() {
         return values;
     }
+
+    @Override
+    protected String valueDescription() {
+        return locationIdentity.toString();
+    }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/address/OffsetAddressNode.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/address/OffsetAddressNode.java	Wed Nov 08 16:03:35 2017 -0500
@@ -22,6 +22,7 @@
  */
 package org.graalvm.compiler.nodes.memory.address;
 
+import org.graalvm.compiler.core.common.type.AbstractPointerStamp;
 import org.graalvm.compiler.core.common.type.IntegerStamp;
 import org.graalvm.compiler.core.common.type.Stamp;
 import org.graalvm.compiler.graph.Node;
@@ -52,6 +53,9 @@
         super(TYPE);
         this.base = base;
         this.offset = offset;
+
+        assert base != null && (base.stamp() instanceof AbstractPointerStamp || IntegerStamp.getBits(base.stamp()) == 64) &&
+                        offset != null && IntegerStamp.getBits(offset.stamp()) == 64 : "both values must have 64 bits";
     }
 
     @Override
@@ -62,6 +66,7 @@
     public void setBase(ValueNode base) {
         updateUsages(this.base, base);
         this.base = base;
+        assert base != null && (base.stamp() instanceof AbstractPointerStamp || IntegerStamp.getBits(base.stamp()) == 64);
     }
 
     public ValueNode getOffset() {
@@ -71,6 +76,7 @@
     public void setOffset(ValueNode offset) {
         updateUsages(this.offset, offset);
         this.offset = offset;
+        assert offset != null && IntegerStamp.getBits(offset.stamp()) == 64;
     }
 
     @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/VirtualizerTool.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/VirtualizerTool.java	Wed Nov 08 16:03:35 2017 -0500
@@ -25,6 +25,7 @@
 import java.util.List;
 
 import org.graalvm.compiler.debug.DebugContext;
+import org.graalvm.compiler.debug.GraalError;
 import org.graalvm.compiler.graph.Node;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.java.MonitorIdNode;
@@ -91,9 +92,17 @@
      *
      * @param index the index to be set.
      * @param value the new value for the given index.
-     * @param unsafe if true, then mismatching value {@link JavaKind}s will be accepted.
+     * @param accessKind the kind of the store which might be different than
+     *            {@link VirtualObjectNode#entryKind(int)}.
+     * @return true if the operation was permitted
      */
-    void setVirtualEntry(VirtualObjectNode virtualObject, int index, ValueNode value, boolean unsafe);
+    boolean setVirtualEntry(VirtualObjectNode virtualObject, int index, ValueNode value, JavaKind accessKind, long offset);
+
+    default void setVirtualEntry(VirtualObjectNode virtualObject, int index, ValueNode value) {
+        if (!setVirtualEntry(virtualObject, index, value, null, 0)) {
+            throw new GraalError("unexpected failure when updating virtual entry");
+        }
+    }
 
     ValueNode getEntry(VirtualObjectNode virtualObject, int index);
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/util/GraphUtil.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/util/GraphUtil.java	Wed Nov 08 16:03:35 2017 -0500
@@ -242,7 +242,7 @@
                 EconomicSet<Node> collectedUnusedNodes = unusedNodes = EconomicSet.create(Equivalence.IDENTITY);
                 nodeEventScope = node.graph().trackNodeEvents(new Graph.NodeEventListener() {
                     @Override
-                    public void event(Graph.NodeEvent e, Node n) {
+                    public void changed(Graph.NodeEvent e, Node n) {
                         if (e == Graph.NodeEvent.ZERO_USAGES && isFloatingNode(n) && !(n instanceof GuardNode)) {
                             collectedUnusedNodes.add(n);
                         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/util/JavaConstantFormattable.java	Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 org.graalvm.compiler.nodes.util;
+
+/**
+ * Performs special formatting of values involving {@link jdk.vm.ci.meta.JavaConstant JavaConstants}
+ * when they are being dumped.
+ */
+public interface JavaConstantFormattable {
+    String format(JavaConstantFormatter formatter);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/util/JavaConstantFormatter.java	Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 org.graalvm.compiler.nodes.util;
+
+import jdk.vm.ci.meta.JavaConstant;
+
+public interface JavaConstantFormatter {
+    String format(JavaConstant constant);
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/virtual/VirtualArrayNode.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/virtual/VirtualArrayNode.java	Wed Nov 08 16:03:35 2017 -0500
@@ -37,7 +37,7 @@
 import jdk.vm.ci.meta.ResolvedJavaType;
 import sun.misc.Unsafe;
 
-@NodeInfo(nameTemplate = "VirtualArray {p#componentType/s}[{p#length}]")
+@NodeInfo(nameTemplate = "VirtualArray({p#objectId}) {p#componentType/s}[{p#length}]")
 public class VirtualArrayNode extends VirtualObjectNode implements ArrayLengthProvider {
 
     public static final NodeClass<VirtualArrayNode> TYPE = NodeClass.create(VirtualArrayNode.class);
@@ -76,7 +76,7 @@
     @Override
     public String toString(Verbosity verbosity) {
         if (verbosity == Verbosity.Name) {
-            return super.toString(Verbosity.Name) + " " + componentType.getName() + "[" + length + "]";
+            return super.toString(Verbosity.Name) + "(" + getObjectId() + ") " + componentType.getName() + "[" + length + "]";
         } else {
             return super.toString(verbosity);
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/virtual/VirtualInstanceNode.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/virtual/VirtualInstanceNode.java	Wed Nov 08 16:03:35 2017 -0500
@@ -32,7 +32,7 @@
 import jdk.vm.ci.meta.ResolvedJavaField;
 import jdk.vm.ci.meta.ResolvedJavaType;
 
-@NodeInfo(nameTemplate = "VirtualInstance {p#type/s}")
+@NodeInfo(nameTemplate = "VirtualInstance({p#objectId}) {p#type/s}")
 public class VirtualInstanceNode extends VirtualObjectNode {
 
     public static final NodeClass<VirtualInstanceNode> TYPE = NodeClass.create(VirtualInstanceNode.class);
@@ -78,7 +78,7 @@
     @Override
     public String toString(Verbosity verbosity) {
         if (verbosity == Verbosity.Name) {
-            return super.toString(Verbosity.Name) + " " + type.toJavaName(false);
+            return super.toString(Verbosity.Name) + "(" + getObjectId() + ") " + type.toJavaName(false);
         } else {
             return super.toString(verbosity);
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options.processor/src/org/graalvm/compiler/options/processor/OptionProcessor.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options.processor/src/org/graalvm/compiler/options/processor/OptionProcessor.java	Wed Nov 08 16:03:35 2017 -0500
@@ -394,6 +394,9 @@
                     options = new OptionsInfo(topDeclaringType);
                     map.put(topDeclaringType, options);
                 }
+                if (!element.getEnclosingElement().getSimpleName().toString().endsWith("Options")) {
+                    processingEnv.getMessager().printMessage(Kind.ERROR, "Option declaring classes must have a name that ends with 'Options'", element.getEnclosingElement());
+                }
                 processElement(element, options);
             }
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/ConditionalEliminationPhase.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/ConditionalEliminationPhase.java	Wed Nov 08 16:03:35 2017 -0500
@@ -248,7 +248,7 @@
         /**
          * Tests which may be eliminated because post dominating tests to prove a broader condition.
          */
-        private Deque<PendingTest> pendingTests;
+        private Deque<DeoptimizingGuard> pendingTests;
 
         public Instance(StructuredGraph graph, BlockMap<List<Node>> blockToNodes, PhaseContext context) {
             this.graph = graph;
@@ -555,7 +555,8 @@
                 }
             }
             if (guard instanceof DeoptimizingGuard) {
-                pendingTests.push(new PendingTest(condition, (DeoptimizingGuard) guard));
+                assert ((DeoptimizingGuard) guard).getCondition() == condition;
+                pendingTests.push((DeoptimizingGuard) guard);
             }
             registerCondition(condition, negated, guard);
         }
@@ -628,15 +629,16 @@
         }
 
         protected boolean foldPendingTest(DeoptimizingGuard thisGuard, ValueNode original, Stamp newStamp, GuardRewirer rewireGuardFunction) {
-            for (PendingTest pending : pendingTests) {
+            for (DeoptimizingGuard pendingGuard : pendingTests) {
+                LogicNode pendingCondition = pendingGuard.getCondition();
                 TriState result = TriState.UNKNOWN;
-                if (pending.condition instanceof UnaryOpLogicNode) {
-                    UnaryOpLogicNode unaryLogicNode = (UnaryOpLogicNode) pending.condition;
+                if (pendingCondition instanceof UnaryOpLogicNode) {
+                    UnaryOpLogicNode unaryLogicNode = (UnaryOpLogicNode) pendingCondition;
                     if (unaryLogicNode.getValue() == original) {
                         result = unaryLogicNode.tryFold(newStamp);
                     }
-                } else if (pending.condition instanceof BinaryOpLogicNode) {
-                    BinaryOpLogicNode binaryOpLogicNode = (BinaryOpLogicNode) pending.condition;
+                } else if (pendingCondition instanceof BinaryOpLogicNode) {
+                    BinaryOpLogicNode binaryOpLogicNode = (BinaryOpLogicNode) pendingCondition;
                     ValueNode x = binaryOpLogicNode.getX();
                     ValueNode y = binaryOpLogicNode.getY();
                     if (x == original) {
@@ -659,7 +661,7 @@
                      */
                     InputFilter v = new InputFilter(original);
                     thisGuard.getCondition().applyInputs(v);
-                    if (v.ok && foldGuard(thisGuard, pending.guard, newStamp, rewireGuardFunction)) {
+                    if (v.ok && foldGuard(thisGuard, pendingGuard, newStamp, rewireGuardFunction)) {
                         return true;
                     }
                 }
@@ -1026,16 +1028,6 @@
         boolean rewire(GuardingNode guard, boolean result, Stamp guardedValueStamp, ValueNode newInput);
     }
 
-    protected static class PendingTest {
-        private final LogicNode condition;
-        private final DeoptimizingGuard guard;
-
-        public PendingTest(LogicNode condition, DeoptimizingGuard guard) {
-            this.condition = condition;
-            this.guard = guard;
-        }
-    }
-
     protected static final class InfoElement {
         private final Stamp stamp;
         private final GuardingNode guard;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/FixReadsPhase.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/FixReadsPhase.java	Wed Nov 08 16:03:35 2017 -0500
@@ -221,7 +221,12 @@
             EconomicMap<ValueNode, Stamp> endMap = endMaps.get(node);
             MapCursor<ValueNode, Stamp> entries = endMap.getEntries();
             while (entries.advance()) {
-                if (registerNewValueStamp(entries.getKey(), entries.getValue())) {
+                ValueNode value = entries.getKey();
+                if (value.isDeleted()) {
+                    // nodes from this map can be deleted when a loop dies
+                    continue;
+                }
+                if (registerNewValueStamp(value, entries.getValue())) {
                     counterBetterMergedStamps.increment(debug);
                 }
             }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/ProfileCompiledMethodsPhase.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/ProfileCompiledMethodsPhase.java	Wed Nov 08 16:03:35 2017 -0500
@@ -48,7 +48,7 @@
 import org.graalvm.compiler.nodes.VirtualState;
 import org.graalvm.compiler.nodes.calc.BinaryNode;
 import org.graalvm.compiler.nodes.calc.ConvertNode;
-import org.graalvm.compiler.nodes.calc.DivNode;
+import org.graalvm.compiler.nodes.calc.FloatDivNode;
 import org.graalvm.compiler.nodes.calc.IntegerDivRemNode;
 import org.graalvm.compiler.nodes.calc.MulNode;
 import org.graalvm.compiler.nodes.calc.NotNode;
@@ -162,7 +162,7 @@
             return 2;
         } else if (node instanceof LogicNode || node instanceof ConvertNode || node instanceof BinaryNode || node instanceof NotNode) {
             return 1;
-        } else if (node instanceof IntegerDivRemNode || node instanceof DivNode || node instanceof RemNode) {
+        } else if (node instanceof IntegerDivRemNode || node instanceof FloatDivNode || node instanceof RemNode) {
             return 10;
         } else if (node instanceof MulNode) {
             return 3;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/info/elem/InlineableGraph.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/info/elem/InlineableGraph.java	Wed Nov 08 16:03:35 2017 -0500
@@ -43,7 +43,6 @@
 import org.graalvm.compiler.phases.graph.FixedNodeProbabilityCache;
 import org.graalvm.compiler.phases.tiers.HighTierContext;
 
-import jdk.vm.ci.meta.Constant;
 import jdk.vm.ci.meta.ResolvedJavaMethod;
 
 /**
@@ -159,11 +158,11 @@
             if (param.usages().isNotEmpty()) {
                 ValueNode arg = args.get(param.index());
                 if (arg.isConstant()) {
-                    Constant constant = arg.asConstant();
+                    ConstantNode constant = (ConstantNode) arg;
                     parameterUsages = trackParameterUsages(param, parameterUsages);
                     // collect param usages before replacing the param
                     param.replaceAtUsagesAndDelete(graph.unique(
-                                    ConstantNode.forConstant(arg.stamp(), constant, ((ConstantNode) arg).getStableDimension(), ((ConstantNode) arg).isDefaultStable(), context.getMetaAccess())));
+                                    ConstantNode.forConstant(arg.stamp(), constant.getValue(), constant.getStableDimension(), constant.isDefaultStable(), context.getMetaAccess())));
                     // param-node gone, leaving a gap in the sequence given by param.index()
                 } else {
                     Stamp impro = improvedStamp(arg, param);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/util/HashSetNodeEventListener.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/util/HashSetNodeEventListener.java	Wed Nov 08 16:03:35 2017 -0500
@@ -37,7 +37,7 @@
  * A simple {@link NodeEventListener} implementation that accumulates event nodes in a
  * {@link HashSet}.
  */
-public class HashSetNodeEventListener implements NodeEventListener {
+public class HashSetNodeEventListener extends NodeEventListener {
 
     private final EconomicSet<Node> nodes;
     private final Set<NodeEvent> filter;
@@ -68,7 +68,7 @@
     }
 
     @Override
-    public void event(NodeEvent e, Node node) {
+    public void changed(NodeEvent e, Node node) {
         if (filter.contains(e)) {
             nodes.add(node);
             if (node instanceof IndirectCanonicalization) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/BasePhase.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/BasePhase.java	Wed Nov 08 16:03:35 2017 -0500
@@ -258,7 +258,7 @@
         return false;
     }
 
-    private final class GraphChangeListener implements NodeEventListener {
+    private final class GraphChangeListener extends NodeEventListener {
         boolean changed;
         private StructuredGraph graph;
         private Mark mark;
@@ -269,7 +269,7 @@
         }
 
         @Override
-        public void event(NodeEvent e, Node node) {
+        public void changed(NodeEvent e, Node node) {
             if (!graph.isNew(mark, node) && node.isAlive()) {
                 if (e == NodeEvent.INPUT_CHANGED || e == NodeEvent.ZERO_USAGES) {
                     changed = true;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/schedule/SchedulePhase.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/schedule/SchedulePhase.java	Wed Nov 08 16:03:35 2017 -0500
@@ -109,7 +109,7 @@
         if (immutableGraph && Assertions.assertionsEnabled()) {
             return graph.trackNodeEvents(new NodeEventListener() {
                 @Override
-                public void event(NodeEvent e, Node node) {
+                public void changed(NodeEvent e, Node node) {
                     assert false : "graph changed: " + e + " on node " + node;
                 }
             });
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/verify/VerifyGetOptionsUsage.java	Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 org.graalvm.compiler.phases.verify;
+
+import java.lang.reflect.MalformedParametersException;
+import java.lang.reflect.Method;
+
+import org.graalvm.compiler.graph.Node;
+import org.graalvm.compiler.graph.spi.CanonicalizerTool;
+import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.java.MethodCallTargetNode;
+import org.graalvm.compiler.phases.VerifyPhase;
+import org.graalvm.compiler.phases.tiers.PhaseContext;
+
+import jdk.vm.ci.meta.MetaAccessProvider;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.meta.ResolvedJavaType;
+
+/**
+ * {@link Node#getOptions()} is unsafe for use during canonicalization so try to verify that it
+ * isn't used when a {@link CanonicalizerTool} is available in the arguments. This is slightly more
+ * general but since there are several canonical methods with varying signatures this covers more
+ * cases.
+ */
+public class VerifyGetOptionsUsage extends VerifyPhase<PhaseContext> {
+    static Method lookupMethod(Class<?> klass, String name) {
+        for (Method m : klass.getDeclaredMethods()) {
+            if (m.getName().equals(name)) {
+                return m;
+            }
+        }
+        throw new InternalError();
+    }
+
+    @Override
+    protected boolean verify(StructuredGraph graph, PhaseContext context) {
+        MetaAccessProvider metaAccess = context.getMetaAccess();
+        ResolvedJavaType canonicalizerToolClass = metaAccess.lookupJavaType(CanonicalizerTool.class);
+        boolean hasTool = false;
+        try {
+            for (ResolvedJavaMethod.Parameter parameter : graph.method().getParameters()) {
+                if (parameter.getType().getName().equals(canonicalizerToolClass.getName())) {
+                    hasTool = true;
+                    break;
+                }
+            }
+        } catch (MalformedParametersException e) {
+            // Lambdas sometimes have malformed parameters so ignore this.
+        }
+        if (hasTool) {
+            ResolvedJavaMethod getOptionsMethod = metaAccess.lookupJavaMethod(lookupMethod(Node.class, "getOptions"));
+            for (MethodCallTargetNode t : graph.getNodes(MethodCallTargetNode.TYPE)) {
+                ResolvedJavaMethod callee = t.targetMethod();
+                if (callee.equals(getOptionsMethod)) {
+                    if (hasTool) {
+                        throw new VerificationError("Must use CanonicalizerTool.getOptions() instead of Node.getOptions() in method '%s' of class '%s'.",
+                                        graph.method().getName(), graph.method().getDeclaringClass().getName());
+                    }
+                }
+            }
+        }
+
+        return true;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/verify/VerifyGraphAddUsage.java	Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 org.graalvm.compiler.phases.verify;
+
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.meta.ResolvedJavaType;
+import org.graalvm.compiler.debug.GraalError;
+import org.graalvm.compiler.graph.Graph;
+import org.graalvm.compiler.graph.Node;
+import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.Invoke;
+import org.graalvm.compiler.nodes.ParameterNode;
+import org.graalvm.compiler.nodes.PiNode;
+import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.ValueNode;
+import org.graalvm.compiler.nodes.ValuePhiNode;
+import org.graalvm.compiler.nodes.ValueProxyNode;
+import org.graalvm.compiler.nodes.java.MethodCallTargetNode;
+import org.graalvm.compiler.nodes.java.NewInstanceNode;
+import org.graalvm.compiler.nodes.spi.LoweringProvider;
+import org.graalvm.compiler.phases.VerifyPhase;
+import org.graalvm.compiler.phases.tiers.PhaseContext;
+import org.graalvm.util.EconomicSet;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+
+public class VerifyGraphAddUsage extends VerifyPhase<PhaseContext> {
+    private static final Method ADD_OR_UNIQUE;
+    private static final Method CONSTRUCTOR_NEW_INSTANCE;
+    private static final EconomicSet<Class<?>> ALLOWED_CLASSES = EconomicSet.create();
+
+    static {
+        try {
+            ADD_OR_UNIQUE = Graph.class.getDeclaredMethod("addOrUnique", Node.class);
+            CONSTRUCTOR_NEW_INSTANCE = Constructor.class.getDeclaredMethod("newInstance", Object[].class);
+        } catch (NoSuchMethodException e) {
+            throw new GraalError(e);
+        }
+
+        ALLOWED_CLASSES.add(Graph.class);
+        ALLOWED_CLASSES.add(LoweringProvider.class);
+    }
+
+    @Override
+    protected boolean verify(StructuredGraph graph, PhaseContext context) {
+        boolean allowed = false;
+        for (Class<?> cls : ALLOWED_CLASSES) {
+            ResolvedJavaType declaringClass = graph.method().getDeclaringClass();
+            if (context.getMetaAccess().lookupJavaType(cls).isAssignableFrom(declaringClass)) {
+                allowed = true;
+            }
+        }
+        if (!allowed) {
+            ResolvedJavaMethod addOrUniqueMethod = context.getMetaAccess().lookupJavaMethod(ADD_OR_UNIQUE);
+            for (MethodCallTargetNode t : graph.getNodes(MethodCallTargetNode.TYPE)) {
+                ResolvedJavaMethod callee = t.targetMethod();
+                if (callee.equals(addOrUniqueMethod)) {
+                    ValueNode nodeArgument = t.arguments().get(1);
+                    EconomicSet<Node> seen = EconomicSet.create();
+                    checkNonFactory(graph, seen, context, nodeArgument);
+                }
+            }
+        }
+
+        return true;
+    }
+
+    private void checkNonFactory(StructuredGraph graph, EconomicSet<Node> seen, PhaseContext context, ValueNode node) {
+        if (seen.contains(node)) {
+            return;
+        }
+        seen.add(node);
+
+        // Check where the value came from recursively, or if it is allowed.
+        if (node instanceof ValuePhiNode) {
+            for (ValueNode input : ((ValuePhiNode) node).values()) {
+                checkNonFactory(graph, seen, context, input);
+            }
+        } else if (node instanceof PiNode) {
+            checkNonFactory(graph, seen, context, ((PiNode) node).object());
+        } else if (node instanceof ParameterNode) {
+            return;
+        } else if (node instanceof ConstantNode) {
+            return;
+        } else if (node instanceof ValueProxyNode) {
+            checkNonFactory(graph, seen, context, ((ValueProxyNode) node).value());
+        } else if (node instanceof Invoke && ((Invoke) node).callTarget().targetMethod().equals(context.getMetaAccess().lookupJavaMethod(CONSTRUCTOR_NEW_INSTANCE))) {
+            return;
+        } else if (!(node instanceof NewInstanceNode)) {
+            // In all other cases, the argument must be a new instance.
+            throw new VerificationError("Must add node '%s' with inputs in method '%s' of class '%s'.",
+                            node, graph.method().getName(), graph.method().getDeclaringClass().getName());
+        }
+    }
+
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/BasicIdealGraphPrinter.java	Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,366 +0,0 @@
-/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
- * 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 org.graalvm.compiler.printer;
-
-import java.io.BufferedOutputStream;
-import java.io.OutputStream;
-import java.io.PrintStream;
-import java.io.UnsupportedEncodingException;
-import java.nio.charset.Charset;
-import java.util.Map;
-import java.util.Map.Entry;
-
-/**
- * Elementary, generic generator of Ideal Graph Visualizer input for use in printers for specific
- * data structures.
- */
-class BasicIdealGraphPrinter {
-
-    /**
-     * Edge between two nodes.
-     */
-    protected static class Edge {
-
-        final String from;
-        final int fromIndex;
-        final String to;
-        final int toIndex;
-        final String label;
-
-        public Edge(String from, int fromIndex, String to, int toIndex, String label) {
-            assert (from != null && to != null);
-            this.from = from;
-            this.fromIndex = fromIndex;
-            this.to = to;
-            this.toIndex = toIndex;
-            this.label = label;
-        }
-
-        @Override
-        public int hashCode() {
-            int h = from.hashCode() ^ to.hashCode();
-            h = 3 * h + fromIndex;
-            h = 5 * h + toIndex;
-            if (label != null) {
-                h ^= label.hashCode();
-            }
-            return h;
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (obj == this) {
-                return true;
-            }
-            if (obj instanceof Edge) {
-                Edge other = (Edge) obj;
-                return from.equals(other.from) && fromIndex == other.fromIndex && to.equals(other.to) && toIndex == other.toIndex &&
-                                (label == other.label || (label != null && label.equals(other.label)));
-            }
-            return false;
-        }
-    }
-
-    private final PrintStream stream;
-
-    /**
-     * Creates a new {@link IdealGraphPrinter} that writes to the specified output stream.
-     */
-    protected BasicIdealGraphPrinter(OutputStream stream) {
-        try {
-            OutputStream buffered;
-            if (stream instanceof BufferedOutputStream) {
-                buffered = stream;
-            } else {
-                buffered = new BufferedOutputStream(stream, 256 * 1024);
-            }
-            this.stream = new PrintStream(buffered, false, Charset.defaultCharset().name());
-        } catch (UnsupportedEncodingException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Flushes any buffered output.
-     */
-    protected void flush() {
-        stream.flush();
-    }
-
-    /**
-     * Starts a new graph document.
-     */
-    protected void begin() {
-        stream.println("<graphDocument>");
-    }
-
-    protected void beginGroup() {
-        stream.println("<group>");
-    }
-
-    protected void beginMethod(String name, String shortName, int bci) {
-        stream.printf(" <method name='%s' shortName='%s' bci='%d'>%n", escape(name), escape(shortName), bci);
-    }
-
-    protected void beginBytecodes() {
-        stream.println("  <bytecodes>\n<![CDATA[");
-    }
-
-    protected void printBytecode(int bci, String mnemonic, int[] extra) {
-        stream.print(bci);
-        stream.print(' ');
-        stream.print(mnemonic);
-        if (extra != null) {
-            for (int b : extra) {
-                stream.print(' ');
-                stream.print(b);
-            }
-        }
-        stream.println();
-    }
-
-    protected void endBytecodes() {
-        stream.println("  ]]></bytecodes>");
-    }
-
-    protected void printBytecodes(String disassembly) {
-        beginBytecodes();
-        stream.println(disassembly);
-        endBytecodes();
-    }
-
-    protected void endMethod() {
-        stream.println(" </method>");
-    }
-
-    protected void beginGraph(String title) {
-        stream.printf(" <graph name='%s'>%n", escape(title));
-    }
-
-    protected void beginProperties() {
-        stream.print("<properties>");
-    }
-
-    protected void printProperty(String name, String value) {
-        stream.printf("<p name='%s'>%s</p>", escape(name), escape(value));
-    }
-
-    protected void endProperties() {
-        stream.print("</properties>");
-    }
-
-    protected void printProperties(Map<String, String> properties) {
-        beginProperties();
-        for (Entry<String, String> entry : properties.entrySet()) {
-            printProperty(entry.getKey(), entry.getValue());
-        }
-        endProperties();
-    }
-
-    protected void beginNodes() {
-        stream.println("  <nodes>");
-    }
-
-    protected void beginNode(String id) {
-        stream.printf("   <node id='%s'>", escape(id));
-    }
-
-    protected void endNode() {
-        stream.println("   </node>");
-    }
-
-    protected void printNode(String id, Map<String, String> properties) {
-        beginNode(id);
-        if (properties != null) {
-            printProperties(properties);
-        }
-        endNode();
-    }
-
-    protected void endNodes() {
-        stream.println("  </nodes>");
-    }
-
-    protected void beginEdges() {
-        stream.println("  <edges>");
-    }
-
-    protected void printEdge(Edge edge) {
-        stream.printf("   <edge from='%s' fromIndex='%d' to='%s' toIndex='%d' label='%s' />%n", escape(edge.from), edge.fromIndex, escape(edge.to), edge.toIndex, escape(edge.label));
-    }
-
-    protected void endEdges() {
-        stream.println("  </edges>");
-    }
-
-    protected void beginControlFlow() {
-        stream.println("  <controlFlow>");
-    }
-
-    protected void beginBlock(String name) {
-        stream.printf("   <block name='%s'>%n", escape(name));
-    }
-
-    protected void beginSuccessors() {
-        stream.println("    <successors>");
-    }
-
-    protected void printSuccessor(String name) {
-        stream.printf("     <successor name='%s'/>%n", escape(name));
-    }
-
-    protected void endSuccessors() {
-        stream.println("    </successors>");
-    }
-
-    protected void beginBlockNodes() {
-        stream.println("    <nodes>");
-    }
-
-    protected void printBlockNode(String nodeId) {
-        stream.printf("     <node id='%s'/>%n", escape(nodeId));
-    }
-
-    protected void endBlockNodes() {
-        stream.println("    </nodes>");
-    }
-
-    protected void endBlock() {
-        stream.println("   </block>");
-    }
-
-    protected void endControlFlow() {
-        stream.println("  </controlFlow>");
-    }
-
-    protected void endGraph() {
-        stream.println(" </graph>");
-    }
-
-    /**
-     * Ends the current group.
-     */
-    public void endGroup() {
-        stream.println("</group>");
-    }
-
-    /**
-     * Finishes the graph document and flushes the output stream.
-     */
-    protected void end() {
-        stream.println("</graphDocument>");
-        flush();
-    }
-
-    public void close() {
-        end();
-        stream.close();
-    }
-
-    public boolean isValid() {
-        return !stream.checkError();
-    }
-
-    private static String escape(String s) {
-        StringBuilder str = null;
-        for (int i = 0; i < s.length(); i++) {
-            char c = s.charAt(i);
-            switch (c) {
-                case '&':
-                case '<':
-                case '>':
-                case '"':
-                case '\'':
-                    if (str == null) {
-                        str = new StringBuilder();
-                        str.append(s, 0, i);
-                    }
-                    switch (c) {
-                        case '&':
-                            str.append("&amp;");
-                            break;
-                        case '<':
-                            str.append("&lt;");
-                            break;
-                        case '>':
-                            str.append("&gt;");
-                            break;
-                        case '"':
-                            str.append("&quot;");
-                            break;
-                        case '\'':
-                            str.append("&apos;");
-                            break;
-                        default:
-                            assert false;
-                    }
-                    break;
-                case '\u0000':
-                case '\u0001':
-                case '\u0002':
-                case '\u0003':
-                case '\u0004':
-                case '\u0005':
-                case '\u0006':
-                case '\u0007':
-                case '\u0008':
-                case '\u000b':
-                case '\u000c':
-                case '\u000e':
-                case '\u000f':
-                case '\u0010':
-                case '\u0011':
-                case '\u0012':
-                case '\u0013':
-                case '\u0014':
-                case '\u0015':
-                case '\u0016':
-                case '\u0017':
-                case '\u0018':
-                case '\u0019':
-                case '\u001a':
-                case '\u001b':
-                case '\u001c':
-                case '\u001d':
-                case '\u001e':
-                case '\u001f':
-                    if (str == null) {
-                        str = new StringBuilder();
-                        str.append(s, 0, i);
-                    }
-                    str.append("'0x").append(Integer.toHexString(c));
-                    break;
-                default:
-                    if (str != null) {
-                        str.append(c);
-                    }
-                    break;
-            }
-        }
-        if (str == null) {
-            return s;
-        } else {
-            return str.toString();
-        }
-    }
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/BinaryGraphPrinter.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/BinaryGraphPrinter.java	Wed Nov 08 16:03:35 2017 -0500
@@ -26,18 +26,17 @@
 import static org.graalvm.compiler.graph.Edges.Type.Successors;
 
 import java.io.IOException;
-import java.nio.channels.WritableByteChannel;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
-import jdk.vm.ci.meta.ResolvedJavaField;
 
 import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
 import org.graalvm.compiler.bytecode.Bytecode;
 import org.graalvm.compiler.core.common.cfg.BlockMap;
+import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.debug.DebugOptions;
 import org.graalvm.compiler.graph.CachedGraph;
 import org.graalvm.compiler.graph.Edges;
@@ -46,6 +45,7 @@
 import org.graalvm.compiler.graph.Node;
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.graph.NodeMap;
+import org.graalvm.compiler.graph.NodeSourcePosition;
 import org.graalvm.compiler.nodes.AbstractBeginNode;
 import org.graalvm.compiler.nodes.AbstractEndNode;
 import org.graalvm.compiler.nodes.AbstractMergeNode;
@@ -55,15 +55,11 @@
 import org.graalvm.compiler.nodes.FixedNode;
 import org.graalvm.compiler.nodes.PhiNode;
 import org.graalvm.compiler.nodes.ProxyNode;
+import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.VirtualState;
 import org.graalvm.compiler.nodes.cfg.Block;
 import org.graalvm.compiler.nodes.cfg.ControlFlowGraph;
-import jdk.vm.ci.meta.ResolvedJavaMethod;
-import jdk.vm.ci.meta.ResolvedJavaType;
-import jdk.vm.ci.meta.Signature;
-import org.graalvm.compiler.debug.DebugContext;
-import org.graalvm.compiler.graph.NodeSourcePosition;
-import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.util.JavaConstantFormattable;
 import org.graalvm.compiler.phases.schedule.SchedulePhase;
 import org.graalvm.graphio.GraphBlocks;
 import org.graalvm.graphio.GraphElements;
@@ -71,6 +67,11 @@
 import org.graalvm.graphio.GraphStructure;
 import org.graalvm.graphio.GraphTypes;
 
+import jdk.vm.ci.meta.ResolvedJavaField;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.meta.ResolvedJavaType;
+import jdk.vm.ci.meta.Signature;
+
 public class BinaryGraphPrinter implements
                 GraphStructure<BinaryGraphPrinter.GraphInfo, Node, NodeClass<?>, Edges>,
                 GraphBlocks<BinaryGraphPrinter.GraphInfo, Block, Node>,
@@ -79,8 +80,8 @@
     private final SnippetReflectionProvider snippetReflection;
     private final GraphOutput<BinaryGraphPrinter.GraphInfo, ResolvedJavaMethod> output;
 
-    public BinaryGraphPrinter(WritableByteChannel channel, SnippetReflectionProvider snippetReflection) throws IOException {
-        this.output = GraphOutput.newBuilder(this).blocks(this).elements(this).types(this).build(channel);
+    public BinaryGraphPrinter(DebugContext ctx, SnippetReflectionProvider snippetReflection) throws IOException {
+        this.output = ctx.buildOutput(GraphOutput.newBuilder(this).protocolVersion(5, 0).blocks(this).elements(this).types(this));
         this.snippetReflection = snippetReflection;
     }
 
@@ -116,17 +117,24 @@
     }
 
     @Override
+    public Node node(Object obj) {
+        return obj instanceof Node ? (Node) obj : null;
+    }
+
+    @Override
     public NodeClass<?> nodeClass(Object obj) {
         if (obj instanceof NodeClass<?>) {
             return (NodeClass<?>) obj;
         }
-        if (obj instanceof Node) {
-            return ((Node) obj).getNodeClass();
-        }
         return null;
     }
 
     @Override
+    public NodeClass<?> classForNode(Node node) {
+        return node.getNodeClass();
+    }
+
+    @Override
     public Object nodeClassType(NodeClass<?> node) {
         return node.getJavaClass();
     }
@@ -257,6 +265,13 @@
             }
             props.put("category", "floating");
         }
+        if (getSnippetReflectionProvider() != null) {
+            for (Map.Entry<String, Object> prop : props.entrySet()) {
+                if (prop.getValue() instanceof JavaConstantFormattable) {
+                    props.put(prop.getKey(), ((JavaConstantFormattable) prop.getValue()).format(this));
+                }
+            }
+        }
     }
 
     private Object getBlockForNode(Node node, NodeMap<Block> nodeToBlocks) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/CFGPrinterObserver.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/CFGPrinterObserver.java	Wed Nov 08 16:03:35 2017 -0500
@@ -23,13 +23,13 @@
 package org.graalvm.compiler.printer;
 
 import static org.graalvm.compiler.debug.DebugOptions.PrintCFG;
-import static org.graalvm.compiler.printer.GraalDebugHandlersFactory.createDumpPath;
 
 import java.io.BufferedOutputStream;
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
+import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -153,8 +153,8 @@
 
         if (cfgPrinter == null) {
             try {
-                Graph graph = debug.contextLookupTopdown(Graph.class);
-                cfgFile = createDumpPath(options, graph, "cfg", false).toFile();
+                Path dumpFile = debug.getDumpPath(".cfg", false);
+                cfgFile = dumpFile.toFile();
                 OutputStream out = new BufferedOutputStream(new FileOutputStream(cfgFile));
                 cfgPrinter = new CFGPrinter(out);
             } catch (IOException e) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/CanonicalStringGraphPrinter.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/CanonicalStringGraphPrinter.java	Wed Nov 08 16:03:35 2017 -0500
@@ -26,7 +26,6 @@
 import static org.graalvm.compiler.debug.DebugOptions.CanonicalGraphStringsExcludeVirtuals;
 import static org.graalvm.compiler.debug.DebugOptions.CanonicalGraphStringsRemoveIdentities;
 import static org.graalvm.compiler.debug.DebugOptions.PrintCanonicalGraphStringFlavor;
-import static org.graalvm.compiler.printer.GraalDebugHandlersFactory.sanitizedFileName;
 
 import java.io.BufferedWriter;
 import java.io.FileWriter;
@@ -44,6 +43,7 @@
 import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
 import org.graalvm.compiler.core.common.Fields;
 import org.graalvm.compiler.debug.DebugContext;
+import org.graalvm.compiler.debug.PathUtilities;
 import org.graalvm.compiler.graph.Graph;
 import org.graalvm.compiler.graph.Node;
 import org.graalvm.compiler.graph.NodeMap;
@@ -260,11 +260,11 @@
     private StructuredGraph currentGraph;
     private Path currentDirectory;
 
-    private Path getDirectory(StructuredGraph graph) throws IOException {
+    private Path getDirectory(DebugContext debug, StructuredGraph graph) {
         if (graph == currentGraph) {
             return currentDirectory;
         }
-        currentDirectory = GraalDebugHandlersFactory.createDumpPath(graph.getOptions(), graph, "graph-strings", true);
+        currentDirectory = debug.getDumpPath(".graph-strings", true);
         currentGraph = graph;
         return currentDirectory;
     }
@@ -274,9 +274,9 @@
         if (graph instanceof StructuredGraph) {
             OptionValues options = graph.getOptions();
             StructuredGraph structuredGraph = (StructuredGraph) graph;
-            Path outDirectory = getDirectory(structuredGraph);
+            Path outDirectory = getDirectory(debug, structuredGraph);
             String title = String.format("%03d-%s.txt", id, String.format(format, simplifyClassArgs(args)));
-            Path filePath = outDirectory.resolve(sanitizedFileName(title));
+            Path filePath = outDirectory.resolve(PathUtilities.sanitizeFileName(title));
             try (PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(filePath.toFile())))) {
                 switch (PrintCanonicalGraphStringFlavor.getValue(options)) {
                     case 1:
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/GraalDebugHandlersFactory.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/GraalDebugHandlersFactory.java	Wed Nov 08 16:03:35 2017 -0500
@@ -22,44 +22,18 @@
  */
 package org.graalvm.compiler.printer;
 
-import static org.graalvm.compiler.debug.DebugOptions.PrintBinaryGraphPort;
-import static org.graalvm.compiler.debug.DebugOptions.PrintBinaryGraphs;
-import static org.graalvm.compiler.debug.DebugOptions.PrintGraphHost;
-import static org.graalvm.compiler.debug.DebugOptions.PrintXmlGraphPort;
-import static org.graalvm.compiler.debug.DebugOptions.ShowDumpFiles;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InterruptedIOException;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-import java.nio.channels.ClosedByInterruptException;
-import java.nio.channels.FileChannel;
-import java.nio.channels.SocketChannel;
-import java.nio.file.FileAlreadyExistsException;
-import java.nio.file.Files;
-import java.nio.file.InvalidPathException;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.nio.file.StandardOpenOption;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.concurrent.atomic.AtomicInteger;
 
 import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
-import org.graalvm.compiler.core.common.CompilationIdentifier;
-import org.graalvm.compiler.debug.Assertions;
 import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.debug.DebugDumpHandler;
 import org.graalvm.compiler.debug.DebugHandler;
 import org.graalvm.compiler.debug.DebugHandlersFactory;
 import org.graalvm.compiler.debug.DebugOptions;
 import org.graalvm.compiler.debug.TTY;
-import org.graalvm.compiler.debug.PathUtilities;
-import org.graalvm.compiler.graph.Graph;
 import org.graalvm.compiler.graph.Node;
 import org.graalvm.compiler.nodeinfo.Verbosity;
-import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.util.GraphUtil;
 import org.graalvm.compiler.options.OptionValues;
 import org.graalvm.compiler.serviceprovider.ServiceProvider;
@@ -80,17 +54,13 @@
     @Override
     public List<DebugHandler> createHandlers(OptionValues options) {
         List<DebugHandler> handlers = new ArrayList<>();
-        if (DebugOptions.PrintGraphFile.getValue(options)) {
-            handlers.add(new GraphPrinterDumpHandler((graph) -> createFilePrinter(graph, options, snippetReflection)));
-        } else {
-            handlers.add(new GraphPrinterDumpHandler((graph) -> createNetworkPrinter(graph, options, snippetReflection)));
-        }
+        handlers.add(new GraphPrinterDumpHandler((debug, graph) -> new BinaryGraphPrinter(debug, snippetReflection)));
         if (DebugOptions.PrintCanonicalGraphStrings.getValue(options)) {
-            handlers.add(new GraphPrinterDumpHandler((graph) -> createStringPrinter(snippetReflection)));
+            handlers.add(new GraphPrinterDumpHandler((debug, graph) -> createStringPrinter(snippetReflection)));
         }
         handlers.add(new NodeDumper());
         if (DebugOptions.PrintCFG.getValue(options) || DebugOptions.PrintBackendCFG.getValue(options)) {
-            if (DebugOptions.PrintBinaryGraphs.getValue(options) && DebugOptions.PrintCFG.getValue(options)) {
+            if (DebugOptions.PrintCFG.getValue(options)) {
                 TTY.out.println("Complete C1Visualizer dumping slows down PrintBinaryGraphs: use -Dgraal.PrintCFG=false to disable it");
             }
             handlers.add(new CFGPrinterObserver());
@@ -119,162 +89,4 @@
         return new CanonicalStringGraphPrinter(snippetReflection);
     }
 
-    public static String sanitizedFileName(String n) {
-        /*
-         * First ensure that the name does not contain the directory separator (which would be
-         * considered a valid path).
-         */
-        String name = n.replace(File.separatorChar, '_');
-
-        try {
-            Paths.get(name);
-            return name;
-        } catch (InvalidPathException e) {
-            // fall through
-        }
-        StringBuilder buf = new StringBuilder(name.length());
-        for (int i = 0; i < name.length(); i++) {
-            char c = name.charAt(i);
-            try {
-                Paths.get(String.valueOf(c));
-            } catch (InvalidPathException e) {
-                buf.append('_');
-            }
-            buf.append(c);
-        }
-        return buf.toString();
-    }
-
-    private static GraphPrinter createNetworkPrinter(Graph graph, OptionValues options, SnippetReflectionProvider snippetReflection) throws IOException {
-        String host = PrintGraphHost.getValue(options);
-        int port = PrintBinaryGraphs.getValue(options) ? PrintBinaryGraphPort.getValue(options) : PrintXmlGraphPort.getValue(options);
-        try {
-            GraphPrinter printer;
-            if (DebugOptions.PrintBinaryGraphs.getValue(options)) {
-                printer = new BinaryGraphPrinter(SocketChannel.open(new InetSocketAddress(host, port)), snippetReflection);
-            } else {
-                printer = new IdealGraphPrinter(new Socket(host, port).getOutputStream(), true, snippetReflection);
-            }
-            TTY.println("Connected to the IGV on %s:%d", host, port);
-            return printer;
-        } catch (ClosedByInterruptException | InterruptedIOException e) {
-            /*
-             * Interrupts should not count as errors because they may be caused by a cancelled Graal
-             * compilation. ClosedByInterruptException occurs if the SocketChannel could not be
-             * opened. InterruptedIOException occurs if new Socket(..) was interrupted.
-             */
-            return null;
-        } catch (IOException e) {
-            if (!DebugOptions.PrintGraphFile.hasBeenSet(options)) {
-                return createFilePrinter(graph, options, snippetReflection);
-            } else {
-                throw new IOException(String.format("Could not connect to the IGV on %s:%d", host, port), e);
-            }
-        }
-    }
-
-    private static final AtomicInteger unknownCompilationId = new AtomicInteger();
-
-    /**
-     * Creates a new file or directory for dumping based on a given graph and a file extension.
-     *
-     * @param graph a base path name is derived from {@code graph}
-     * @param extension a suffix which if non-null and non-empty added to the end of the returned
-     *            path separated by a {@code "."}
-     * @param createDirectory specifies if this is a request to create a directory instead of a file
-     * @return the created directory or file
-     * @throws IOException if there was an error creating the directory or file
-     */
-    static Path createDumpPath(OptionValues options, Graph graph, String extension, boolean createDirectory) throws IOException {
-        CompilationIdentifier compilationId = CompilationIdentifier.INVALID_COMPILATION_ID;
-        String id = null;
-        String label = null;
-        if (graph instanceof StructuredGraph) {
-            StructuredGraph sgraph = (StructuredGraph) graph;
-            label = getGraphName(sgraph);
-            compilationId = sgraph.compilationId();
-            if (compilationId == CompilationIdentifier.INVALID_COMPILATION_ID) {
-                id = graph.getClass().getSimpleName() + "-" + sgraph.graphId();
-            } else {
-                id = compilationId.toString(CompilationIdentifier.Verbosity.ID);
-            }
-        } else {
-            label = graph == null ? null : graph.name != null ? graph.name : graph.toString();
-            id = "UnknownCompilation-" + unknownCompilationId.incrementAndGet();
-        }
-        String ext = PathUtilities.formatExtension(extension);
-        Path result = createUnique(DebugOptions.getDumpDirectory(options), id, label, ext, createDirectory);
-        if (ShowDumpFiles.getValue(options) || Assertions.assertionsEnabled()) {
-            TTY.println("Dumping debug output to %s", result.toAbsolutePath().toString());
-        }
-        return result;
-    }
-
-    /**
-     * A maximum file name length supported by most file systems. There is no platform independent
-     * way to get this in Java.
-     */
-    private static final int MAX_FILE_NAME_LENGTH = 255;
-
-    private static final String ELLIPSIS = "...";
-
-    private static Path createUnique(Path dumpDir, String id, String label, String ext, boolean createDirectory) throws IOException {
-        String timestamp = "";
-        for (;;) {
-            int fileNameLengthWithoutLabel = timestamp.length() + ext.length() + id.length() + "[]".length();
-            int labelLengthLimit = MAX_FILE_NAME_LENGTH - fileNameLengthWithoutLabel;
-            String fileName;
-            if (labelLengthLimit < ELLIPSIS.length()) {
-                // This means `id` is very long
-                String suffix = timestamp + ext;
-                int idLengthLimit = Math.min(MAX_FILE_NAME_LENGTH - suffix.length(), id.length());
-                fileName = sanitizedFileName(id.substring(0, idLengthLimit) + suffix);
-            } else {
-                if (label == null) {
-                    fileName = sanitizedFileName(id + timestamp + ext);
-                } else {
-                    String adjustedLabel = label;
-                    if (label.length() > labelLengthLimit) {
-                        adjustedLabel = label.substring(0, labelLengthLimit - ELLIPSIS.length()) + ELLIPSIS;
-                    }
-                    fileName = sanitizedFileName(id + '[' + adjustedLabel + ']' + timestamp + ext);
-                }
-            }
-            Path result = dumpDir.resolve(fileName);
-            try {
-                if (createDirectory) {
-                    return Files.createDirectory(result);
-                } else {
-                    return Files.createFile(result);
-                }
-            } catch (FileAlreadyExistsException e) {
-                timestamp = "_" + Long.toString(System.currentTimeMillis());
-            }
-        }
-    }
-
-    private static String getGraphName(StructuredGraph graph) {
-        if (graph.name != null) {
-            return graph.name;
-        } else if (graph.method() != null) {
-            return graph.method().format("%h.%n(%p)").replace(" ", "");
-        } else {
-            return graph.toString();
-        }
-    }
-
-    private static GraphPrinter createFilePrinter(Graph graph, OptionValues options, SnippetReflectionProvider snippetReflection) throws IOException {
-        Path path = createDumpPath(options, graph, PrintBinaryGraphs.getValue(options) ? "bgv" : "gv.xml", false);
-        try {
-            GraphPrinter printer;
-            if (DebugOptions.PrintBinaryGraphs.getValue(options)) {
-                printer = new BinaryGraphPrinter(FileChannel.open(path, StandardOpenOption.WRITE), snippetReflection);
-            } else {
-                printer = new IdealGraphPrinter(Files.newOutputStream(path), true, snippetReflection);
-            }
-            return printer;
-        } catch (IOException e) {
-            throw new IOException(String.format("Failed to open %s to dump IGV graphs", path), e);
-        }
-    }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/GraphPrinter.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/GraphPrinter.java	Wed Nov 08 16:03:35 2017 -0500
@@ -35,6 +35,7 @@
 import org.graalvm.compiler.graph.Graph;
 import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.util.JavaConstantFormatter;
 import org.graalvm.compiler.phases.schedule.SchedulePhase;
 import org.graalvm.compiler.serviceprovider.JDK9Method;
 
@@ -46,7 +47,7 @@
 import jdk.vm.ci.runtime.JVMCI;
 import jdk.vm.ci.services.Services;
 
-interface GraphPrinter extends Closeable {
+interface GraphPrinter extends Closeable, JavaConstantFormatter {
 
     /**
      * Starts a new group of graphs with the given name, short name and method byte code index (BCI)
@@ -116,30 +117,44 @@
                 return true;
             }
         }
+        if (c.getClassLoader() == GraphPrinter.class.getClassLoader()) {
+            return true;
+        }
         return false;
     }
 
     /**
+     * Use the real {@link Object#toString()} method for {@link JavaConstant JavaConstants} that are
+     * wrapping trusted types, other just return the results of {@link JavaConstant#toString()}.
+     */
+    @Override
+    default String format(JavaConstant constant) {
+        SnippetReflectionProvider snippetReflection = getSnippetReflectionProvider();
+        if (snippetReflection != null) {
+            if (constant.getJavaKind() == JavaKind.Object) {
+                Object obj = snippetReflection.asObject(Object.class, constant);
+                if (obj != null) {
+                    return GraphPrinter.constantToString(obj);
+                }
+            }
+        }
+        return constant.toString();
+    }
+
+    /**
      * Sets or updates the {@code "rawvalue"} and {@code "toString"} properties in {@code props} for
      * {@code cn} if it's a boxed Object value and {@code snippetReflection} can access the raw
      * value.
      */
     default void updateStringPropertiesForConstant(Map<Object, Object> props, ConstantNode cn) {
-        SnippetReflectionProvider snippetReflection = getSnippetReflectionProvider();
-        if (snippetReflection != null && cn.getValue() instanceof JavaConstant) {
-            JavaConstant constant = (JavaConstant) cn.getValue();
-            if (constant.getJavaKind() == JavaKind.Object) {
-                Object obj = snippetReflection.asObject(Object.class, constant);
-                if (obj != null) {
-                    String toString = GraphPrinter.constantToString(obj);
-                    String rawvalue = GraphPrinter.truncate(toString);
-                    // Overwrite the value inserted by
-                    // ConstantNode.getDebugProperties()
-                    props.put("rawvalue", rawvalue);
-                    if (!rawvalue.equals(toString)) {
-                        props.put("toString", toString);
-                    }
-                }
+        if (cn.isJavaConstant() && cn.getStackKind().isObject()) {
+            String toString = format(cn.asJavaConstant());
+            String rawvalue = GraphPrinter.truncate(toString);
+            // Overwrite the value inserted by
+            // ConstantNode.getDebugProperties()
+            props.put("rawvalue", rawvalue);
+            if (!rawvalue.equals(toString)) {
+                props.put("toString", toString);
             }
         }
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/GraphPrinterDumpHandler.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/GraphPrinterDumpHandler.java	Wed Nov 08 16:03:35 2017 -0500
@@ -52,8 +52,8 @@
 //JaCoCo Exclude
 
 /**
- * Observes compilation events and uses {@link IdealGraphPrinter} to generate a graph representation
- * that can be inspected with the Graph Visualizer.
+ * Observes compilation events and uses {@link BinaryGraphPrinter} to generate a graph
+ * representation that can be inspected with the Graph Visualizer.
  */
 public class GraphPrinterDumpHandler implements DebugDumpHandler {
 
@@ -69,7 +69,7 @@
 
     @FunctionalInterface
     public interface GraphPrinterSupplier {
-        GraphPrinter get(Graph graph) throws IOException;
+        GraphPrinter get(DebugContext ctx, Graph graph) throws IOException;
     }
 
     /**
@@ -93,7 +93,7 @@
         }
     }
 
-    private void ensureInitialized(Graph graph) {
+    private void ensureInitialized(DebugContext ctx, Graph graph) {
         if (printer == null) {
             if (failuresCount >= FAILURE_LIMIT) {
                 return;
@@ -102,7 +102,7 @@
             inlineContextMap = new WeakHashMap<>();
             DebugContext debug = graph.getDebug();
             try {
-                printer = printerSupplier.get(graph);
+                printer = printerSupplier.get(ctx, graph);
             } catch (IOException e) {
                 handleException(debug, e);
             }
@@ -123,7 +123,7 @@
         OptionValues options = debug.getOptions();
         if (object instanceof Graph && DebugOptions.PrintGraph.getValue(options)) {
             final Graph graph = (Graph) object;
-            ensureInitialized(graph);
+            ensureInitialized(debug, graph);
             if (printer == null) {
                 return;
             }
@@ -168,11 +168,13 @@
             // Save inline context for next dump.
             previousInlineContext = inlineContext;
 
+            // Capture before creating the sandbox
+            String currentScopeName = debug.getCurrentScopeName();
             try (DebugContext.Scope s = debug.sandbox("PrintingGraph", null)) {
                 // Finally, output the graph.
                 Map<Object, Object> properties = new HashMap<>();
                 properties.put("graph", graph.toString());
-                properties.put("scope", debug.getCurrentScopeName());
+                properties.put("scope", currentScopeName);
                 if (graph instanceof StructuredGraph) {
                     properties.put("compilationIdentifier", ((StructuredGraph) graph).compilationId());
                     try {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/IdealGraphPrinter.java	Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,356 +0,0 @@
-/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
- * 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 org.graalvm.compiler.printer;
-
-import java.io.OutputStream;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
-import org.graalvm.compiler.bytecode.BytecodeDisassembler;
-import org.graalvm.compiler.debug.DebugContext;
-import org.graalvm.compiler.debug.DebugOptions;
-import org.graalvm.compiler.graph.Graph;
-import org.graalvm.compiler.graph.Node;
-import org.graalvm.compiler.graph.NodeMap;
-import org.graalvm.compiler.graph.Position;
-import org.graalvm.compiler.nodeinfo.Verbosity;
-import org.graalvm.compiler.nodes.AbstractMergeNode;
-import org.graalvm.compiler.nodes.BeginNode;
-import org.graalvm.compiler.nodes.ConstantNode;
-import org.graalvm.compiler.nodes.EndNode;
-import org.graalvm.compiler.nodes.ParameterNode;
-import org.graalvm.compiler.nodes.PhiNode;
-import org.graalvm.compiler.nodes.StateSplit;
-import org.graalvm.compiler.nodes.StructuredGraph;
-import org.graalvm.compiler.nodes.StructuredGraph.ScheduleResult;
-import org.graalvm.compiler.nodes.cfg.Block;
-import org.graalvm.compiler.nodes.cfg.ControlFlowGraph;
-import org.graalvm.compiler.options.OptionValues;
-import org.graalvm.compiler.phases.schedule.SchedulePhase;
-import org.graalvm.util.EconomicSet;
-import org.graalvm.util.Equivalence;
-
-import jdk.vm.ci.meta.ResolvedJavaMethod;
-
-/**
- * Generates a representation of {@link Graph Graphs} that can be visualized and inspected with the
- * <a href="http://kenai.com/projects/igv">Ideal Graph Visualizer</a>.
- */
-public class IdealGraphPrinter extends BasicIdealGraphPrinter implements GraphPrinter {
-
-    private final boolean tryToSchedule;
-    private final SnippetReflectionProvider snippetReflection;
-
-    /**
-     * Creates a new {@link IdealGraphPrinter} that writes to the specified output stream.
-     *
-     * @param tryToSchedule If false, no scheduling is done, which avoids exceptions for
-     *            non-schedulable graphs.
-     */
-    public IdealGraphPrinter(OutputStream stream, boolean tryToSchedule, SnippetReflectionProvider snippetReflection) {
-        super(stream);
-        this.snippetReflection = snippetReflection;
-        this.begin();
-        this.tryToSchedule = tryToSchedule;
-    }
-
-    @Override
-    public SnippetReflectionProvider getSnippetReflectionProvider() {
-        return snippetReflection;
-    }
-
-    /**
-     * Starts a new group of graphs with the given name, short name and method byte code index (BCI)
-     * as properties.
-     */
-    @Override
-    public void beginGroup(DebugContext debug, String name, String shortName, ResolvedJavaMethod method, int bci, Map<Object, Object> properties) {
-        beginGroup();
-        beginProperties();
-        printProperty("name", name);
-        if (properties != null) {
-            for (Entry<Object, Object> entry : properties.entrySet()) {
-                printProperty(entry.getKey().toString(), entry.getValue().toString());
-            }
-        }
-        endProperties();
-        beginMethod(name, shortName, bci);
-        if (method != null && method.getCode() != null) {
-            printBytecodes(new BytecodeDisassembler(false).disassemble(method));
-        }
-        endMethod();
-    }
-
-    /**
-     * Prints an entire {@link Graph} with the specified title, optionally using short names for
-     * nodes.
-     */
-    @Override
-    public void print(DebugContext debug, Graph graph, Map<Object, Object> properties, int id, String format, Object... args) {
-        String title = id + ": " + String.format(format, simplifyClassArgs(args));
-        beginGraph(title);
-        EconomicSet<Node> noBlockNodes = EconomicSet.create(Equivalence.IDENTITY);
-        ScheduleResult schedule = null;
-        if (graph instanceof StructuredGraph) {
-            StructuredGraph structuredGraph = (StructuredGraph) graph;
-            schedule = structuredGraph.getLastSchedule();
-            if (schedule == null && tryToSchedule) {
-                OptionValues options = graph.getOptions();
-                if (DebugOptions.PrintGraphWithSchedule.getValue(options)) {
-                    try {
-                        SchedulePhase schedulePhase = new SchedulePhase(options);
-                        schedulePhase.apply(structuredGraph);
-                        schedule = structuredGraph.getLastSchedule();
-                    } catch (Throwable t) {
-                    }
-                }
-            }
-        }
-        ControlFlowGraph cfg = schedule == null ? null : schedule.getCFG();
-
-        if (properties != null) {
-            beginProperties();
-            for (Entry<Object, Object> entry : properties.entrySet()) {
-                printProperty(entry.getKey().toString(), entry.getValue().toString());
-            }
-            endProperties();
-        }
-
-        beginNodes();
-        List<Edge> edges = printNodes(graph, cfg == null ? null : cfg.getNodeToBlock(), noBlockNodes);
-        endNodes();
-
-        beginEdges();
-        for (Edge edge : edges) {
-            printEdge(edge);
-        }
-        endEdges();
-
-        if (cfg != null && cfg.getBlocks() != null) {
-            beginControlFlow();
-            for (Block block : cfg.getBlocks()) {
-                printBlock(graph, block, cfg.getNodeToBlock());
-            }
-            printNoBlock(noBlockNodes);
-            endControlFlow();
-        }
-
-        endGraph();
-        flush();
-    }
-
-    private List<Edge> printNodes(Graph graph, NodeMap<Block> nodeToBlock, EconomicSet<Node> noBlockNodes) {
-        ArrayList<Edge> edges = new ArrayList<>();
-
-        NodeMap<Set<Entry<String, Integer>>> colors = graph.createNodeMap();
-        NodeMap<Set<Entry<String, String>>> colorsToString = graph.createNodeMap();
-        NodeMap<Set<String>> bits = graph.createNodeMap();
-
-        for (Node node : graph.getNodes()) {
-
-            beginNode(node.toString(Verbosity.Id));
-            beginProperties();
-            printProperty("idx", node.toString(Verbosity.Id));
-
-            Map<Object, Object> props = node.getDebugProperties();
-            if (!props.containsKey("name") || props.get("name").toString().trim().length() == 0) {
-                String name = node.toString(Verbosity.Name);
-                printProperty("name", name);
-            }
-            printProperty("class", node.getClass().getSimpleName());
-
-            Block block = nodeToBlock == null || nodeToBlock.isNew(node) ? null : nodeToBlock.get(node);
-            if (block != null) {
-                printProperty("block", Integer.toString(block.getId()));
-                // if (!(node instanceof PhiNode || node instanceof FrameState || node instanceof
-                // ParameterNode) && !block.nodes().contains(node)) {
-                // printProperty("notInOwnBlock", "true");
-                // }
-            } else {
-                printProperty("block", "noBlock");
-                noBlockNodes.add(node);
-            }
-
-            Set<Entry<String, Integer>> nodeColors = colors.get(node);
-            if (nodeColors != null) {
-                for (Entry<String, Integer> color : nodeColors) {
-                    String name = color.getKey();
-                    Integer value = color.getValue();
-                    printProperty(name, Integer.toString(value));
-                }
-            }
-            Set<Entry<String, String>> nodeColorStrings = colorsToString.get(node);
-            if (nodeColorStrings != null) {
-                for (Entry<String, String> color : nodeColorStrings) {
-                    String name = color.getKey();
-                    String value = color.getValue();
-                    printProperty(name, value);
-                }
-            }
-            Set<String> nodeBits = bits.get(node);
-            if (nodeBits != null) {
-                for (String bit : nodeBits) {
-                    printProperty(bit, "true");
-                }
-            }
-            if (node instanceof BeginNode) {
-                printProperty("shortName", "B");
-            } else if (node.getClass() == EndNode.class) {
-                printProperty("shortName", "E");
-            } else if (node instanceof ConstantNode) {
-                ConstantNode cn = (ConstantNode) node;
-                updateStringPropertiesForConstant(props, cn);
-            }
-            if (node.predecessor() != null) {
-                printProperty("hasPredecessor", "true");
-            }
-
-            try {
-                printProperty("NodeCost-Size", node.estimatedNodeSize().toString());
-                printProperty("NodeCost-Cycles", node.estimatedNodeCycles().toString());
-            } catch (Throwable t) {
-                props.put("node-cost-exception", t.getMessage());
-            }
-
-            for (Entry<Object, Object> entry : props.entrySet()) {
-                String key = entry.getKey().toString();
-                Object value = entry.getValue();
-                String valueString;
-                if (value == null) {
-                    valueString = "null";
-                } else {
-                    Class<?> type = value.getClass();
-                    if (type.isArray()) {
-                        if (!type.getComponentType().isPrimitive()) {
-                            valueString = Arrays.toString((Object[]) value);
-                        } else if (type.getComponentType() == Integer.TYPE) {
-                            valueString = Arrays.toString((int[]) value);
-                        } else if (type.getComponentType() == Double.TYPE) {
-                            valueString = Arrays.toString((double[]) value);
-                        } else {
-                            valueString = toString();
-                        }
-                    } else {
-                        valueString = value.toString();
-                    }
-                }
-                printProperty(key, valueString);
-            }
-
-            endProperties();
-            endNode();
-
-            // successors
-            int fromIndex = 0;
-            for (Position position : node.successorPositions()) {
-                Node successor = position.get(node);
-                if (successor != null) {
-                    edges.add(new Edge(node.toString(Verbosity.Id), fromIndex, successor.toString(Verbosity.Id), 0, position.getName()));
-                }
-                fromIndex++;
-            }
-
-            // inputs
-            int toIndex = 1;
-            for (Position position : node.inputPositions()) {
-                Node input = position.get(node);
-                if (input != null) {
-                    edges.add(new Edge(input.toString(Verbosity.Id), input.successors().count(), node.toString(Verbosity.Id), toIndex, position.getName()));
-                }
-                toIndex++;
-            }
-        }
-
-        return edges;
-    }
-
-    private void printBlock(Graph graph, Block block, NodeMap<Block> nodeToBlock) {
-        beginBlock(Integer.toString(block.getId()));
-        beginSuccessors();
-        for (Block sux : block.getSuccessors()) {
-            if (sux != null) {
-                printSuccessor(Integer.toString(sux.getId()));
-            }
-        }
-        endSuccessors();
-        beginBlockNodes();
-
-        EconomicSet<Node> nodes = EconomicSet.create(Equivalence.IDENTITY);
-
-        if (nodeToBlock != null) {
-            for (Node n : graph.getNodes()) {
-                Block blk = nodeToBlock.isNew(n) ? null : nodeToBlock.get(n);
-                if (blk == block) {
-                    nodes.add(n);
-                }
-            }
-        }
-
-        if (nodes.size() > 0) {
-            // if this is the first block: add all locals to this block
-            if (block.getBeginNode() == ((StructuredGraph) graph).start()) {
-                for (Node node : graph.getNodes()) {
-                    if (node instanceof ParameterNode) {
-                        nodes.add(node);
-                    }
-                }
-            }
-
-            EconomicSet<Node> snapshot = EconomicSet.create(Equivalence.IDENTITY, nodes);
-            // add all framestates and phis to their blocks
-            for (Node node : snapshot) {
-                if (node instanceof StateSplit && ((StateSplit) node).stateAfter() != null) {
-                    nodes.add(((StateSplit) node).stateAfter());
-                }
-                if (node instanceof AbstractMergeNode) {
-                    for (PhiNode phi : ((AbstractMergeNode) node).phis()) {
-                        nodes.add(phi);
-                    }
-                }
-            }
-
-            for (Node node : nodes) {
-                printBlockNode(node.toString(Verbosity.Id));
-            }
-        }
-        endBlockNodes();
-        endBlock();
-    }
-
-    private void printNoBlock(EconomicSet<Node> noBlockNodes) {
-        if (!noBlockNodes.isEmpty()) {
-            beginBlock("noBlock");
-            beginBlockNodes();
-            for (Node node : noBlockNodes) {
-                printBlockNode(node.toString(Verbosity.Id));
-            }
-            endBlockNodes();
-            endBlock();
-        }
-    }
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64StringIndexOfNode.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64StringIndexOfNode.java	Wed Nov 08 16:03:35 2017 -0500
@@ -22,13 +22,13 @@
  */
 package org.graalvm.compiler.replacements.amd64;
 
-import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_256;
 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_64;
 
 import org.graalvm.compiler.core.common.type.StampFactory;
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.graph.NodeInputList;
 import org.graalvm.compiler.nodeinfo.InputType;
+import org.graalvm.compiler.nodeinfo.NodeCycles;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.FixedWithNextNode;
 import org.graalvm.compiler.nodes.NamedLocationIdentity;
@@ -44,7 +44,7 @@
 import jdk.vm.ci.meta.JavaKind;
 import jdk.vm.ci.meta.Value;
 
-@NodeInfo(size = SIZE_64, cycles = CYCLES_256)
+@NodeInfo(size = SIZE_64, cycles = NodeCycles.CYCLES_UNKNOWN)
 public class AMD64StringIndexOfNode extends FixedWithNextNode implements LIRLowerable, MemoryAccess {
     public static final NodeClass<AMD64StringIndexOfNode> TYPE = NodeClass.create(AMD64StringIndexOfNode.class);
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/ConstantBindingParameterPlugin.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/ConstantBindingParameterPlugin.java	Wed Nov 08 16:03:35 2017 -0500
@@ -63,7 +63,7 @@
                      * This is a node from another graph, so copy over extra state into a new
                      * ConstantNode.
                      */
-                    constantNode = ConstantNode.forConstant(stamp.getTrustedStamp(), otherCon.asConstant(), otherCon.getStableDimension(), otherCon.isDefaultStable(), metaAccess);
+                    constantNode = ConstantNode.forConstant(stamp.getTrustedStamp(), otherCon.getValue(), otherCon.getStableDimension(), otherCon.isDefaultStable(), metaAccess);
                 } else {
                     constantNode = otherCon;
                 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/DefaultJavaLoweringProvider.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/DefaultJavaLoweringProvider.java	Wed Nov 08 16:03:35 2017 -0500
@@ -33,6 +33,7 @@
 import static org.graalvm.compiler.nodes.java.ArrayLengthNode.readArrayLength;
 import static org.graalvm.compiler.nodes.util.GraphUtil.skipPiWhileNonNull;
 
+import java.nio.ByteOrder;
 import java.util.ArrayList;
 import java.util.BitSet;
 import java.util.List;
@@ -43,6 +44,7 @@
 import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
 import org.graalvm.compiler.core.common.spi.ForeignCallsProvider;
 import org.graalvm.compiler.core.common.type.IntegerStamp;
+import org.graalvm.compiler.core.common.type.ObjectStamp;
 import org.graalvm.compiler.core.common.type.Stamp;
 import org.graalvm.compiler.core.common.type.StampFactory;
 import org.graalvm.compiler.core.common.type.TypeReference;
@@ -50,6 +52,7 @@
 import org.graalvm.compiler.debug.GraalError;
 import org.graalvm.compiler.graph.Node;
 import org.graalvm.compiler.nodeinfo.InputType;
+import org.graalvm.compiler.nodes.CompressionNode.CompressionOp;
 import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.nodes.FieldLocationIdentity;
 import org.graalvm.compiler.nodes.FixedNode;
@@ -69,6 +72,7 @@
 import org.graalvm.compiler.nodes.calc.RightShiftNode;
 import org.graalvm.compiler.nodes.calc.SignExtendNode;
 import org.graalvm.compiler.nodes.calc.SubNode;
+import org.graalvm.compiler.nodes.calc.UnpackEndianHalfNode;
 import org.graalvm.compiler.nodes.calc.ZeroExtendNode;
 import org.graalvm.compiler.nodes.debug.VerifyHeapNode;
 import org.graalvm.compiler.nodes.extended.BoxNode;
@@ -150,14 +154,16 @@
     protected final MetaAccessProvider metaAccess;
     protected final ForeignCallsProvider foreignCalls;
     protected final TargetDescription target;
+    private final boolean useCompressedOops;
 
     private BoxingSnippets.Templates boxingSnippets;
     private ConstantStringIndexOfSnippets.Templates indexOfSnippets;
 
-    public DefaultJavaLoweringProvider(MetaAccessProvider metaAccess, ForeignCallsProvider foreignCalls, TargetDescription target) {
+    public DefaultJavaLoweringProvider(MetaAccessProvider metaAccess, ForeignCallsProvider foreignCalls, TargetDescription target, boolean useCompressedOops) {
         this.metaAccess = metaAccess;
         this.foreignCalls = foreignCalls;
         this.target = target;
+        this.useCompressedOops = useCompressedOops;
     }
 
     public void initialize(OptionValues options, Iterable<DebugHandlersFactory> factories, SnippetCounter.Group.Factory factory, Providers providers, SnippetReflectionProvider snippetReflection) {
@@ -218,11 +224,18 @@
             lowerBinaryMath((BinaryMathIntrinsicNode) n, tool);
         } else if (n instanceof StringIndexOfNode) {
             lowerIndexOf((StringIndexOfNode) n);
+        } else if (n instanceof UnpackEndianHalfNode) {
+            lowerSecondHalf((UnpackEndianHalfNode) n);
         } else {
             throw GraalError.shouldNotReachHere("Node implementing Lowerable not handled: " + n);
         }
     }
 
+    private void lowerSecondHalf(UnpackEndianHalfNode n) {
+        ByteOrder byteOrder = target.arch.getByteOrder();
+        n.lower(byteOrder);
+    }
+
     private void lowerIndexOf(StringIndexOfNode n) {
         if (n.getArgument(3).isConstant()) {
             SnippetLowering lowering = new SnippetLowering() {
@@ -326,19 +339,21 @@
         }
     }
 
+    protected abstract JavaKind getStorageKind(ResolvedJavaField field);
+
     protected void lowerLoadFieldNode(LoadFieldNode loadField, LoweringTool tool) {
         assert loadField.getStackKind() != JavaKind.Illegal;
         StructuredGraph graph = loadField.graph();
         ResolvedJavaField field = loadField.field();
         ValueNode object = loadField.isStatic() ? staticFieldBase(graph, field) : loadField.object();
         object = createNullCheckedValue(object, loadField, tool);
-        Stamp loadStamp = loadStamp(loadField.stamp(), field.getJavaKind());
+        Stamp loadStamp = loadStamp(loadField.stamp(), getStorageKind(field));
 
         AddressNode address = createFieldAddress(graph, object, field);
         assert address != null : "Field that is loaded must not be eliminated: " + field.getDeclaringClass().toJavaName(true) + "." + field.getName();
 
         ReadNode memoryRead = graph.add(new ReadNode(address, fieldLocationIdentity(field), loadStamp, fieldLoadBarrierType(field)));
-        ValueNode readValue = implicitLoadConvert(graph, field.getJavaKind(), memoryRead);
+        ValueNode readValue = implicitLoadConvert(graph, getStorageKind(field), memoryRead);
         loadField.replaceAtUsages(readValue);
         graph.replaceFixed(loadField, memoryRead);
 
@@ -355,7 +370,7 @@
         ResolvedJavaField field = storeField.field();
         ValueNode object = storeField.isStatic() ? staticFieldBase(graph, field) : storeField.object();
         object = createNullCheckedValue(object, storeField, tool);
-        ValueNode value = implicitStoreConvert(graph, storeField.field().getJavaKind(), storeField.value());
+        ValueNode value = implicitStoreConvert(graph, getStorageKind(storeField.field()), storeField.value());
         AddressNode address = createFieldAddress(graph, object, field);
         assert address != null;
 
@@ -651,9 +666,7 @@
 
     protected void lowerJavaWriteNode(JavaWriteNode write) {
         StructuredGraph graph = write.graph();
-        JavaKind valueKind = write.getWriteKind();
-        ValueNode value = implicitStoreConvert(graph, valueKind, write.value(), write.isCompressible());
-
+        ValueNode value = implicitStoreConvert(graph, write.getWriteKind(), write.value(), write.isCompressible());
         WriteNode memoryWrite = graph.add(new WriteNode(write.getAddress(), write.getLocationIdentity(), value, write.getBarrierType()));
         memoryWrite.setStateAfter(write.stateAfter());
         graph.replaceFixedWithFixed(write, memoryWrite);
@@ -918,10 +931,20 @@
         return loadStamp(stamp, kind, true);
     }
 
+    private boolean useCompressedOops(JavaKind kind, boolean compressible) {
+        return kind == JavaKind.Object && compressible && useCompressedOops;
+    }
+
+    protected abstract Stamp loadCompressedStamp(ObjectStamp stamp);
+
     /**
      * @param compressible whether the stamp should be compressible
      */
     protected Stamp loadStamp(Stamp stamp, JavaKind kind, boolean compressible) {
+        if (useCompressedOops(kind, compressible)) {
+            return loadCompressedStamp((ObjectStamp) stamp);
+        }
+
         switch (kind) {
             case Boolean:
             case Byte:
@@ -949,10 +972,16 @@
         return ret;
     }
 
+    protected abstract ValueNode newCompressionNode(CompressionOp op, ValueNode value);
+
     /**
-     * @param compressible whether the covert should be compressible
+     * @param compressible whether the convert should be compressible
      */
     protected ValueNode implicitLoadConvert(JavaKind kind, ValueNode value, boolean compressible) {
+        if (useCompressedOops(kind, compressible)) {
+            return newCompressionNode(CompressionOp.Uncompress, value);
+        }
+
         switch (kind) {
             case Byte:
             case Short:
@@ -984,6 +1013,10 @@
      * @param compressible whether the covert should be compressible
      */
     protected ValueNode implicitStoreConvert(JavaKind kind, ValueNode value, boolean compressible) {
+        if (useCompressedOops(kind, compressible)) {
+            return newCompressionNode(CompressionOp.Compress, value);
+        }
+
         switch (kind) {
             case Boolean:
             case Byte:
@@ -1011,9 +1044,8 @@
         LogicNode boundsCheck = IntegerBelowNode.create(n.index(), arrayLength);
         if (boundsCheck.isTautology()) {
             return null;
-        } else {
-            return tool.createGuard(n, graph.addOrUniqueWithInputs(boundsCheck), BoundsCheckException, InvalidateReprofile);
         }
+        return tool.createGuard(n, graph.addOrUniqueWithInputs(boundsCheck), BoundsCheckException, InvalidateReprofile);
     }
 
     protected GuardingNode createNullCheck(ValueNode object, FixedNode before, LoweringTool tool) {
@@ -1027,9 +1059,8 @@
         GuardingNode nullCheck = createNullCheck(object, before, tool);
         if (nullCheck == null) {
             return object;
-        } else {
-            return before.graph().maybeAddOrUnique(PiNode.create(object, (object.stamp()).join(StampFactory.objectNonNull()), (ValueNode) nullCheck));
         }
+        return before.graph().maybeAddOrUnique(PiNode.create(object, (object.stamp()).join(StampFactory.objectNonNull()), (ValueNode) nullCheck));
     }
 
     @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/GraphKit.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/GraphKit.java	Wed Nov 08 16:03:35 2017 -0500
@@ -75,7 +75,6 @@
 import jdk.vm.ci.meta.JavaType;
 import jdk.vm.ci.meta.MetaAccessProvider;
 import jdk.vm.ci.meta.ResolvedJavaMethod;
-import jdk.vm.ci.meta.ResolvedJavaType;
 import jdk.vm.ci.meta.Signature;
 
 /**
@@ -252,6 +251,10 @@
         return new MethodCallTargetNode(invokeKind, targetMethod, args, returnStamp, null);
     }
 
+    protected final JavaKind asKind(JavaType type) {
+        return wordTypes != null ? wordTypes.asKind(type) : type.getJavaKind();
+    }
+
     /**
      * Determines if a given set of arguments is compatible with the signature of a given method.
      *
@@ -267,14 +270,12 @@
         }
         int argIndex = 0;
         if (!isStatic) {
-            ResolvedJavaType expectedType = method.getDeclaringClass();
-            JavaKind expected = wordTypes == null ? expectedType.getJavaKind() : wordTypes.asKind(expectedType);
+            JavaKind expected = asKind(method.getDeclaringClass());
             JavaKind actual = args[argIndex++].stamp().getStackKind();
             assert expected == actual : graph + ": wrong kind of value for receiver argument of call to " + method + " [" + actual + " != " + expected + "]";
         }
         for (int i = 0; i != signature.getParameterCount(false); i++) {
-            JavaType expectedType = signature.getParameterType(i, method.getDeclaringClass());
-            JavaKind expected = wordTypes == null ? expectedType.getJavaKind().getStackKind() : wordTypes.asKind(expectedType).getStackKind();
+            JavaKind expected = asKind(signature.getParameterType(i, method.getDeclaringClass())).getStackKind();
             JavaKind actual = args[argIndex++].stamp().getStackKind();
             if (expected != actual) {
                 throw new AssertionError(graph + ": wrong kind of value for argument " + i + " of call to " + method + " [" + actual + " != " + expected + "]");
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/ReplacementsImpl.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/ReplacementsImpl.java	Wed Nov 08 16:03:35 2017 -0500
@@ -433,13 +433,14 @@
                 }
 
                 IntrinsicContext initialIntrinsicContext = null;
-                if (method.getAnnotation(Snippet.class) == null) {
+                Snippet snippetAnnotation = method.getAnnotation(Snippet.class);
+                if (snippetAnnotation == null) {
                     // Post-parse inlined intrinsic
                     initialIntrinsicContext = new IntrinsicContext(substitutedMethod, method, bytecodeProvider, INLINE_AFTER_PARSING);
                 } else {
                     // Snippet
                     ResolvedJavaMethod original = substitutedMethod != null ? substitutedMethod : method;
-                    initialIntrinsicContext = new IntrinsicContext(original, method, bytecodeProvider, INLINE_AFTER_PARSING);
+                    initialIntrinsicContext = new IntrinsicContext(original, method, bytecodeProvider, INLINE_AFTER_PARSING, snippetAnnotation.allowPartialIntrinsicArgumentMismatch());
                 }
 
                 createGraphBuilder(metaAccess, replacements.providers.getStampProvider(), replacements.providers.getConstantReflection(), replacements.providers.getConstantFieldProvider(), config,
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetCounter.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetCounter.java	Wed Nov 08 16:03:35 2017 -0500
@@ -93,12 +93,7 @@
      */
     @Override
     public int compareTo(SnippetCounter o) {
-        if (value > o.value) {
-            return -1;
-        } else if (o.value < value) {
-            return 1;
-        }
-        return 0;
+        return Long.signum(o.value - value);
     }
 
     private final Group group;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetIntegerHistogram.java	Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 org.graalvm.compiler.replacements;
+
+/**
+ * A histogram that can (only) be {@linkplain #inc(long) incremented} from within a snippet for
+ * gathering snippet specific metrics.
+ */
+public final class SnippetIntegerHistogram {
+    private final SnippetCounter.Group group;
+    private final String name;
+
+    private final SnippetCounter counter0;
+    private final SnippetCounter counter1;
+    private final SnippetCounter counter2;
+    private final SnippetCounter counter3;
+    private final SnippetCounter counter4;
+    private final SnippetCounter counter5;
+    private final SnippetCounter counter6;
+    private final SnippetCounter counter7;
+    private final SnippetCounter counter8;
+    private final SnippetCounter counter9;
+    private final SnippetCounter counter10;
+
+    private final int counter0UpperBound;
+    private final int counter1UpperBound;
+    private final int counter2UpperBound;
+    private final int counter3UpperBound;
+    private final int counter4UpperBound;
+    private final int counter5UpperBound;
+    private final int counter6UpperBound;
+    private final int counter7UpperBound;
+    private final int counter8UpperBound;
+    private final int counter9UpperBound;
+
+    public SnippetIntegerHistogram(SnippetCounter.Group group, int log2StepLength, String name, String description) {
+        assert log2StepLength > 0;
+
+        this.group = group;
+        this.name = name;
+
+        int lowerBound = 0;
+        counter0UpperBound = 0;
+        counter0 = createCounter(group, name, description, lowerBound, counter0UpperBound);
+
+        lowerBound = counter0UpperBound + 1;
+        counter1UpperBound = Math.max(1, lowerBound - 1) << log2StepLength;
+        counter1 = createCounter(group, name, description, lowerBound, counter1UpperBound);
+
+        lowerBound = counter1UpperBound + 1;
+        counter2UpperBound = Math.max(1, lowerBound - 1) << log2StepLength;
+        counter2 = createCounter(group, name, description, lowerBound, counter2UpperBound);
+
+        lowerBound = counter2UpperBound + 1;
+        counter3UpperBound = Math.max(1, lowerBound - 1) << log2StepLength;
+        counter3 = createCounter(group, name, description, lowerBound, counter3UpperBound);
+
+        lowerBound = counter3UpperBound + 1;
+        counter4UpperBound = Math.max(1, lowerBound - 1) << log2StepLength;
+        counter4 = createCounter(group, name, description, lowerBound, counter4UpperBound);
+
+        lowerBound = counter4UpperBound + 1;
+        counter5UpperBound = Math.max(1, lowerBound - 1) << log2StepLength;
+        counter5 = createCounter(group, name, description, lowerBound, counter5UpperBound);
+
+        lowerBound = counter5UpperBound + 1;
+        counter6UpperBound = Math.max(1, lowerBound - 1) << log2StepLength;
+        counter6 = createCounter(group, name, description, lowerBound, counter6UpperBound);
+
+        lowerBound = counter6UpperBound + 1;
+        counter7UpperBound = Math.max(1, lowerBound - 1) << log2StepLength;
+        counter7 = createCounter(group, name, description, lowerBound, counter7UpperBound);
+
+        lowerBound = counter7UpperBound + 1;
+        counter8UpperBound = Math.max(1, lowerBound - 1) << log2StepLength;
+        counter8 = createCounter(group, name, description, lowerBound, counter8UpperBound);
+
+        lowerBound = counter8UpperBound + 1;
+        counter9UpperBound = Math.max(1, lowerBound - 1) << log2StepLength;
+        counter9 = createCounter(group, name, description, lowerBound, counter9UpperBound);
+
+        lowerBound = counter9UpperBound + 1;
+        counter10 = createCounter(group, name, description, lowerBound, Long.MAX_VALUE);
+    }
+
+    private static SnippetCounter createCounter(SnippetCounter.Group group, String name, String description, long lowerBound, long upperBound) {
+        if (group != null) {
+            SnippetCounter snippetCounter = new SnippetCounter(group, name + "[" + lowerBound + ", " + upperBound + "]", description);
+            return snippetCounter;
+        }
+        return null;
+    }
+
+    /**
+     * Increments the value of the matching histogram element. This method can only be used in a
+     * snippet on a compile-time constant {@link SnippetIntegerHistogram} object.
+     */
+    public void inc(long value) {
+        if (group != null) {
+            if (value <= counter0UpperBound) {
+                counter0.inc();
+            } else if (value <= counter1UpperBound) {
+                counter1.inc();
+            } else if (value <= counter2UpperBound) {
+                counter2.inc();
+            } else if (value <= counter3UpperBound) {
+                counter3.inc();
+            } else if (value <= counter4UpperBound) {
+                counter4.inc();
+            } else if (value <= counter5UpperBound) {
+                counter5.inc();
+            } else if (value <= counter6UpperBound) {
+                counter6.inc();
+            } else if (value <= counter7UpperBound) {
+                counter7.inc();
+            } else if (value <= counter8UpperBound) {
+                counter8.inc();
+            } else if (value <= counter9UpperBound) {
+                counter9.inc();
+            } else {
+                counter10.inc();
+            }
+        }
+    }
+
+    @Override
+    public String toString() {
+        if (group != null) {
+            return "SnippetHistogram-" + group.name + ":" + name;
+        }
+        return super.toString();
+    }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ArrayEqualsNode.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ArrayEqualsNode.java	Wed Nov 08 16:03:35 2017 -0500
@@ -23,15 +23,15 @@
 package org.graalvm.compiler.replacements.nodes;
 
 import static org.graalvm.compiler.nodeinfo.InputType.Memory;
-import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_1024;
-import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1024;
 
 import org.graalvm.compiler.core.common.type.StampFactory;
 import org.graalvm.compiler.graph.Node;
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.graph.spi.Canonicalizable;
 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
+import org.graalvm.compiler.nodeinfo.NodeCycles;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodeinfo.NodeSize;
 import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.nodes.FixedWithNextNode;
 import org.graalvm.compiler.nodes.NamedLocationIdentity;
@@ -57,7 +57,7 @@
 /**
  * Compares two arrays with the same length.
  */
-@NodeInfo(cycles = CYCLES_1024, size = SIZE_1024)
+@NodeInfo(cycles = NodeCycles.CYCLES_UNKNOWN, size = NodeSize.SIZE_128)
 public final class ArrayEqualsNode extends FixedWithNextNode implements LIRLowerable, Canonicalizable, Virtualizable, MemoryAccess {
 
     public static final NodeClass<ArrayEqualsNode> TYPE = NodeClass.create(ArrayEqualsNode.class);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BasicArrayCopyNode.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BasicArrayCopyNode.java	Wed Nov 08 16:03:35 2017 -0500
@@ -24,7 +24,6 @@
 
 import static org.graalvm.compiler.nodeinfo.InputType.Memory;
 import static org.graalvm.compiler.nodeinfo.InputType.State;
-import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_256;
 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_64;
 import static org.graalvm.word.LocationIdentity.any;
 
@@ -32,6 +31,7 @@
 import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.graph.NodeInputList;
+import org.graalvm.compiler.nodeinfo.NodeCycles;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.nodes.DeoptimizingNode;
@@ -56,7 +56,7 @@
 import jdk.vm.ci.meta.JavaKind;
 import jdk.vm.ci.meta.ResolvedJavaType;
 
-@NodeInfo(cycles = CYCLES_256, size = SIZE_64)
+@NodeInfo(cycles = NodeCycles.CYCLES_UNKNOWN, size = SIZE_64)
 public class BasicArrayCopyNode extends AbstractMemoryCheckpoint implements Virtualizable, MemoryCheckpoint.Single, MemoryAccess, Lowerable, DeoptimizingNode.DeoptDuring {
 
     public static final NodeClass<BasicArrayCopyNode> TYPE = NodeClass.create(BasicArrayCopyNode.class);
@@ -215,7 +215,7 @@
                         return;
                     }
                     for (int i = 0; i < len; i++) {
-                        tool.setVirtualEntry(destVirtual, destPosInt + i, tool.getEntry(srcVirtual, srcPosInt + i), false);
+                        tool.setVirtualEntry(destVirtual, destPosInt + i, tool.getEntry(srcVirtual, srcPosInt + i));
                     }
                     tool.delete();
                     DebugContext debug = getDebug();
@@ -235,7 +235,7 @@
                     for (int i = 0; i < len; i++) {
                         LoadIndexedNode load = new LoadIndexedNode(graph().getAssumptions(), srcAlias, ConstantNode.forInt(i + srcPosInt, graph()), destComponentType.getJavaKind());
                         tool.addNode(load);
-                        tool.setVirtualEntry(destVirtual, destPosInt + i, load, false);
+                        tool.setVirtualEntry(destVirtual, destPosInt + i, load);
                     }
                     tool.delete();
                 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BasicObjectCloneNode.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BasicObjectCloneNode.java	Wed Nov 08 16:03:35 2017 -0500
@@ -22,7 +22,6 @@
  */
 package org.graalvm.compiler.replacements.nodes;
 
-import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_8;
 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_8;
 
 import java.util.Collections;
@@ -32,6 +31,7 @@
 import org.graalvm.compiler.core.common.type.StampFactory;
 import org.graalvm.compiler.core.common.type.StampPair;
 import org.graalvm.compiler.graph.NodeClass;
+import org.graalvm.compiler.nodeinfo.NodeCycles;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.CallTargetNode.InvokeKind;
 import org.graalvm.compiler.nodes.ValueNode;
@@ -49,7 +49,7 @@
 import jdk.vm.ci.meta.ResolvedJavaMethod;
 import jdk.vm.ci.meta.ResolvedJavaType;
 
-@NodeInfo(cycles = CYCLES_8, size = SIZE_8)
+@NodeInfo(cycles = NodeCycles.CYCLES_UNKNOWN, size = SIZE_8)
 public abstract class BasicObjectCloneNode extends MacroStateSplitNode implements VirtualizableAllocation, ArrayLengthProvider {
 
     public static final NodeClass<BasicObjectCloneNode> TYPE = NodeClass.create(BasicObjectCloneNode.class);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BinaryMathIntrinsicNode.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BinaryMathIntrinsicNode.java	Wed Nov 08 16:03:35 2017 -0500
@@ -37,7 +37,7 @@
 import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.BinaryNode;
-import org.graalvm.compiler.nodes.calc.DivNode;
+import org.graalvm.compiler.nodes.calc.FloatDivNode;
 import org.graalvm.compiler.nodes.calc.MulNode;
 import org.graalvm.compiler.nodes.calc.SqrtNode;
 import org.graalvm.compiler.nodes.spi.ArithmeticLIRLowerable;
@@ -141,7 +141,7 @@
 
             // x**-1 = 1/x
             if (yValue == -1.0D) {
-                return new DivNode(ConstantNode.forDouble(1), x);
+                return new FloatDivNode(ConstantNode.forDouble(1), x);
             }
 
             // x**2 = x*x
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.test/src/org/graalvm/compiler/test/GraalTest.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.test/src/org/graalvm/compiler/test/GraalTest.java	Wed Nov 08 16:03:35 2017 -0500
@@ -36,6 +36,7 @@
 import java.util.Collections;
 import java.util.List;
 
+import jdk.vm.ci.meta.ResolvedJavaMethod;
 import org.graalvm.compiler.debug.DebugHandlersFactory;
 import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.debug.DebugDumpHandler;
@@ -392,6 +393,20 @@
      * {@link DebugDumpHandler}s closed in {@link #afterTest()}.
      */
     protected DebugContext getDebugContext(OptionValues options) {
+        return getDebugContext(options, null, null);
+    }
+
+    /**
+     * Gets a {@link DebugContext} object corresponding to {@code options}, creating a new one if
+     * none currently exists.Debug contexts created by this method will have their
+     * {@link DebugDumpHandler}s closed in {@link #afterTest()}.
+     *
+     * @param options currently active options
+     * @param id identification of the compilation or {@code null}
+     * @param method method to use for a proper description of the context or {@code null}
+     * @return configured context for compilation
+     */
+    protected DebugContext getDebugContext(OptionValues options, String id, ResolvedJavaMethod method) {
         List<DebugContext> cached = cachedDebugs.get();
         if (cached == null) {
             cached = new ArrayList<>();
@@ -402,7 +417,13 @@
                 return debug;
             }
         }
-        DebugContext debug = DebugContext.create(options, NO_DESCRIPTION, NO_GLOBAL_METRIC_VALUES, DEFAULT_LOG_STREAM, getDebugHandlersFactories());
+        final DebugContext.Description descr;
+        if (method == null) {
+            descr = NO_DESCRIPTION;
+        } else {
+            descr = new DebugContext.Description(method, id == null ? method.getName() : id);
+        }
+        DebugContext debug = DebugContext.create(options, descr, NO_GLOBAL_METRIC_VALUES, DEFAULT_LOG_STREAM, getDebugHandlersFactories());
         cached.add(debug);
         return debug;
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/EffectList.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/EffectList.java	Wed Nov 08 16:03:35 2017 -0500
@@ -171,9 +171,14 @@
     }
 
     public void apply(StructuredGraph graph, ArrayList<Node> obsoleteNodes, boolean cfgKills) {
+        boolean message = false;
         for (int i = 0; i < size(); i++) {
             Effect effect = effects[i];
             if (effect.isCfgKill() == cfgKills) {
+                if (!message) {
+                    message = true;
+                    debug.log(cfgKills ? " ==== cfg kill effects" : " ==== effects");
+                }
                 try {
                     effect.apply(graph, obsoleteNodes);
                 } catch (Throwable t) {
@@ -202,7 +207,7 @@
                     // Inner classes could capture the EffectList itself.
                     continue;
                 }
-                str.append(first ? "" : ", ").append(format(object));
+                str.append(first ? "" : ", ").append(field.getName()).append("=").append(format(object));
                 first = false;
             } catch (SecurityException | IllegalAccessException e) {
                 throw new RuntimeException(e);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/EffectsClosure.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/EffectsClosure.java	Wed Nov 08 16:03:35 2017 -0500
@@ -184,7 +184,6 @@
         };
         ReentrantBlockIterator.apply(closure, cfg.getStartBlock());
         for (GraphEffectList effects : effectList) {
-            debug.log(" ==== effects");
             effects.apply(graph, obsoleteNodes, false);
         }
         /*
@@ -193,7 +192,6 @@
          * indexes.
          */
         for (GraphEffectList effects : effectList) {
-            debug.log(" ==== cfg kill effects");
             effects.apply(graph, obsoleteNodes, true);
         }
         debug.dump(DebugContext.DETAILED_LEVEL, graph, "After applying effects");
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/EffectsPhase.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/EffectsPhase.java	Wed Nov 08 16:03:35 2017 -0500
@@ -99,8 +99,8 @@
                             closure.applyEffects();
                         }
 
-                        if (debug.isDumpEnabled(DebugContext.INFO_LEVEL)) {
-                            debug.dump(DebugContext.DETAILED_LEVEL, graph, "%s iteration", getName());
+                        if (debug.isDumpEnabled(DebugContext.VERBOSE_LEVEL)) {
+                            debug.dump(DebugContext.VERBOSE_LEVEL, graph, "%s iteration", getName());
                         }
 
                         new DeadCodeEliminationPhase(Required).apply(graph);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/ObjectState.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/ObjectState.java	Wed Nov 08 16:03:35 2017 -0500
@@ -68,6 +68,7 @@
     }
 
     public ObjectState(ValueNode[] entries, LockState locks, boolean ensureVirtualized) {
+        assert checkIllegalValues(entries);
         this.entries = entries;
         this.locks = locks;
         this.ensureVirtualized = ensureVirtualized;
@@ -92,6 +93,30 @@
         return new ObjectState(this);
     }
 
+    /**
+     * Ensure that if an {@link JavaConstant#forIllegal() illegal value} is seen that the previous
+     * value is a double word value.
+     */
+    public static boolean checkIllegalValues(ValueNode[] values) {
+        if (values != null) {
+            for (int v = 1; v < values.length; v++) {
+                checkIllegalValue(values, v);
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Ensure that if an {@link JavaConstant#forIllegal() illegal value} is seen that the previous
+     * value is a double word value.
+     */
+    public static boolean checkIllegalValue(ValueNode[] values, int v) {
+        if (v > 0 && values[v].isConstant() && values[v].asConstant().equals(JavaConstant.forIllegal())) {
+            assert values[v - 1].getStackKind().needsTwoSlots();
+        }
+        return true;
+    }
+
     public EscapeObjectState createEscapeObjectState(DebugContext debug, VirtualObjectNode virtual) {
         GET_ESCAPED_OBJECT_STATE.increment(debug);
         if (cachedState == null) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/PartialEscapeClosure.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/PartialEscapeClosure.java	Wed Nov 08 16:03:35 2017 -0500
@@ -854,6 +854,7 @@
                                 ValueNode nextValue = objectState.getEntry(valueIndex + 1);
                                 if (value.isConstant() && value.asConstant().equals(JavaConstant.INT_0) && nextValue.isConstant() && nextValue.asConstant().equals(JavaConstant.INT_0)) {
                                     // rewrite to a zero constant of the larger kind
+                                    debug.log("Rewriting entry %s to constant of larger size", valueIndex);
                                     states[i].setEntry(object, valueIndex, ConstantNode.defaultForKind(twoSlotKinds[valueIndex], graph()));
                                     states[i].setEntry(object, valueIndex + 1, ConstantNode.forConstant(JavaConstant.forIllegal(), tool.getMetaAccessProvider(), graph()));
                                 } else {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/VirtualizerToolImpl.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/VirtualizerToolImpl.java	Wed Nov 08 16:03:35 2017 -0500
@@ -30,18 +30,22 @@
 import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.graph.Node;
 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
+import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.nodes.FixedNode;
 import org.graalvm.compiler.nodes.FixedWithNextNode;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.FloatingNode;
+import org.graalvm.compiler.nodes.calc.UnpackEndianHalfNode;
 import org.graalvm.compiler.nodes.java.MonitorIdNode;
 import org.graalvm.compiler.nodes.spi.LoweringProvider;
 import org.graalvm.compiler.nodes.spi.VirtualizerTool;
+import org.graalvm.compiler.nodes.virtual.VirtualInstanceNode;
 import org.graalvm.compiler.nodes.virtual.VirtualObjectNode;
 import org.graalvm.compiler.options.OptionValues;
 
 import jdk.vm.ci.meta.Assumptions;
 import jdk.vm.ci.meta.ConstantReflectionProvider;
+import jdk.vm.ci.meta.JavaConstant;
 import jdk.vm.ci.meta.JavaKind;
 import jdk.vm.ci.meta.MetaAccessProvider;
 
@@ -58,6 +62,7 @@
     private final OptionValues options;
     private final DebugContext debug;
     private final LoweringProvider loweringProvider;
+    private ConstantNode illegalConstant;
 
     VirtualizerToolImpl(MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, ConstantFieldProvider constantFieldProvider, PartialEscapeClosure<?> closure,
                     Assumptions assumptions, OptionValues options, DebugContext debug, LoweringProvider loweringProvider) {
@@ -125,17 +130,81 @@
     }
 
     @Override
-    public void setVirtualEntry(VirtualObjectNode virtual, int index, ValueNode value, boolean unsafe) {
+    public boolean setVirtualEntry(VirtualObjectNode virtual, int index, ValueNode value, JavaKind theAccessKind, long offset) {
         ObjectState obj = state.getObjectState(virtual);
         assert obj.isVirtual() : "not virtual: " + obj;
         ValueNode newValue;
+        JavaKind entryKind = virtual.entryKind(index);
+        JavaKind accessKind = theAccessKind != null ? theAccessKind : entryKind;
         if (value == null) {
             newValue = null;
         } else {
             newValue = closure.getAliasAndResolve(state, value);
-            assert unsafe || obj.getEntry(index) == null || obj.getEntry(index).getStackKind() == newValue.getStackKind() || (isObjectEntry(obj.getEntry(index)) && isObjectEntry(newValue));
+        }
+        getDebug().log(DebugContext.DETAILED_LEVEL, "Setting entry %d in virtual object %s %s results in %s", index, virtual.getObjectId(), virtual, state.getObjectState(virtual.getObjectId()));
+        ValueNode oldValue = getEntry(virtual, index);
+        boolean canVirtualize = entryKind == accessKind || (entryKind == accessKind.getStackKind() && virtual instanceof VirtualInstanceNode);
+        if (!canVirtualize) {
+            if (entryKind == JavaKind.Long && oldValue.getStackKind() == newValue.getStackKind() && oldValue.getStackKind().isPrimitive()) {
+                /*
+                 * Special case: If the entryKind is long, allow arbitrary kinds as long as a value
+                 * of the same kind is already there. This can only happen if some other node
+                 * initialized the entry with a value of a different kind. One example where this
+                 * happens is the Truffle NewFrameNode.
+                 */
+                getDebug().log(DebugContext.DETAILED_LEVEL, "virtualizing %s with primitive of kind %s in long entry ", current, oldValue.getStackKind());
+                canVirtualize = true;
+            } else if (entryKind == JavaKind.Int && (accessKind == JavaKind.Long || accessKind == JavaKind.Double) && offset % 8 == 0) {
+                /*
+                 * Special case: Allow storing a single long or double value into two consecutive
+                 * int slots.
+                 */
+                int nextIndex = virtual.entryIndexForOffset(offset + 4, JavaKind.Int);
+                if (nextIndex != -1) {
+                    canVirtualize = true;
+                    assert nextIndex == index + 1 : "expected to be sequential";
+                    getDebug().log(DebugContext.DETAILED_LEVEL, "virtualizing %s for double word stored in two ints", current);
+                }
+            }
         }
-        state.setEntry(virtual.getObjectId(), index, newValue);
+
+        if (canVirtualize) {
+            getDebug().log(DebugContext.DETAILED_LEVEL, "virtualizing %s for entryKind %s and access kind %s", current, entryKind, accessKind);
+            state.setEntry(virtual.getObjectId(), index, newValue);
+            if (entryKind == JavaKind.Int) {
+                if (accessKind.needsTwoSlots()) {
+                    // Storing double word value two int slots
+                    assert virtual.entryKind(index + 1) == JavaKind.Int;
+                    state.setEntry(virtual.getObjectId(), index + 1, getIllegalConstant());
+                } else if (oldValue.getStackKind() == JavaKind.Double || oldValue.getStackKind() == JavaKind.Long) {
+                    // Splitting double word constant by storing over it with an int
+                    getDebug().log(DebugContext.DETAILED_LEVEL, "virtualizing %s producing second half of double word value %s", current, oldValue);
+                    ValueNode secondHalf = UnpackEndianHalfNode.create(oldValue, false);
+                    addNode(secondHalf);
+                    state.setEntry(virtual.getObjectId(), index + 1, secondHalf);
+                }
+            }
+            if (oldValue.isConstant() && oldValue.asConstant().equals(JavaConstant.forIllegal())) {
+                // Storing into second half of double, so replace previous value
+                ValueNode previous = getEntry(virtual, index - 1);
+                getDebug().log(DebugContext.DETAILED_LEVEL, "virtualizing %s producing first half of double word value %s", current, previous);
+                ValueNode firstHalf = UnpackEndianHalfNode.create(previous, true);
+                addNode(firstHalf);
+                state.setEntry(virtual.getObjectId(), index - 1, firstHalf);
+            }
+            return true;
+        }
+        // Should only occur if there are mismatches between the entry and access kind
+        assert entryKind != accessKind;
+        return false;
+    }
+
+    private ValueNode getIllegalConstant() {
+        if (illegalConstant == null) {
+            illegalConstant = ConstantNode.forConstant(JavaConstant.forIllegal(), getMetaAccessProvider());
+            addNode(illegalConstant);
+        }
+        return illegalConstant;
     }
 
     @Override
@@ -149,10 +218,6 @@
         return state.getObjectState(virtualObject).getEnsureVirtualized();
     }
 
-    private static boolean isObjectEntry(ValueNode value) {
-        return value.getStackKind() == JavaKind.Object || value instanceof VirtualObjectNode;
-    }
-
     @Override
     public void replaceWithVirtual(VirtualObjectNode virtual) {
         closure.addVirtualAlias(virtual, current);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/GraphOutput.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/GraphOutput.java	Wed Nov 08 16:03:35 2017 -0500
@@ -113,12 +113,30 @@
         private GraphElements<M, ?, ?, ?> elements = null;
         private GraphTypes types = DefaultGraphTypes.DEFAULT;
         private GraphBlocks<G, ?, N> blocks = DefaultGraphBlocks.empty();
+        private int major = 4;
+        private int minor = 0;
 
         Builder(GraphStructure<G, N, ?, ?> structure) {
             this.structure = structure;
         }
 
         /**
+         * Chooses which version of the protocol to use. The default version is <code>4.0</code>
+         * (when the {@link GraphOutput} & co. classes were introduced). The default can be changed
+         * to other known versions manually by calling this method.
+         *
+         * @param majorVersion by default 4, newer version may be known
+         * @param minorVersion usually 0
+         * @return this builder
+         * @since 0.28
+         */
+        public Builder<G, N, M> protocolVersion(int majorVersion, int minorVersion) {
+            this.major = majorVersion;
+            this.minor = minorVersion;
+            return this;
+        }
+
+        /**
          * Associates different implementation of types.
          *
          * @param graphTypes implementation of types and enum recognition
@@ -161,7 +179,28 @@
          * @throws IOException if something goes wrong when writing to the channel
          */
         public GraphOutput<G, M> build(WritableByteChannel channel) throws IOException {
-            ProtocolImpl<G, N, ?, ?, ?, M, ?, ?, ?> p = new ProtocolImpl<>(structure, types, blocks, elements, channel);
+            ProtocolImpl<G, N, ?, ?, ?, M, ?, ?, ?> p = new ProtocolImpl<>(major, minor, structure, types, blocks, elements, channel);
+            return new GraphOutput<>(p);
+        }
+
+        /**
+         * Support for nesting heterogenous graphs. The newly created output uses all the interfaces
+         * currently associated with this builder, but shares with {@code parent} the output
+         * {@code channel}, internal constant pool and {@link #protocolVersion(int, int) protocol
+         * version}.
+         * <p>
+         * Both GraphOutput (the {@code parent} and the returned one) has to be used in
+         * synchronization - e.g. only one
+         * {@link #beginGroup(java.lang.Object, java.lang.String, java.lang.String, java.lang.Object, int, java.util.Map)
+         * begin}, {@link #endGroup() end} of group or
+         * {@link #print(java.lang.Object, java.util.Map, int, java.lang.String, java.lang.Object...)
+         * printing} can be on at a given moment.
+         *
+         * @param parent the output to inherit {@code channel} and protocol version from
+         * @return new output sharing {@code channel} and other internals with {@code parent}
+         */
+        public GraphOutput<G, M> build(GraphOutput<?, ?> parent) {
+            ProtocolImpl<G, N, ?, ?, ?, M, ?, ?, ?> p = new ProtocolImpl<>(parent.printer, structure, types, blocks, elements);
             return new GraphOutput<>(p);
         }
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/GraphProtocol.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/GraphProtocol.java	Wed Nov 08 16:03:35 2017 -0500
@@ -52,6 +52,7 @@
     private static final int POOL_FIELD = 0x07;
     private static final int POOL_SIGNATURE = 0x08;
     private static final int POOL_NODE_SOURCE_POSITION = 0x09;
+    private static final int POOL_NODE = 0x0a;
 
     private static final int PROPERTY_POOL = 0x00;
     private static final int PROPERTY_INT = 0x01;
@@ -71,19 +72,12 @@
     private final ConstantPool constantPool;
     private final ByteBuffer buffer;
     private final WritableByteChannel channel;
-    private final int versionMajor;
-    private final int versionMinor;
-
-    protected GraphProtocol(WritableByteChannel channel) throws IOException {
-        this(channel, 4, 0);
-    }
+    final int versionMajor;
+    final int versionMinor;
 
-    private GraphProtocol(WritableByteChannel channel, int major, int minor) throws IOException {
-        if (major > 4) {
-            throw new IllegalArgumentException();
-        }
-        if (major == 4 && minor > 0) {
-            throw new IllegalArgumentException();
+    GraphProtocol(WritableByteChannel channel, int major, int minor) throws IOException {
+        if (major > 5 || (major == 5 && minor > 0)) {
+            throw new IllegalArgumentException("Unrecognized version " + major + "." + minor);
         }
         this.versionMajor = major;
         this.versionMinor = minor;
@@ -93,6 +87,14 @@
         writeVersion();
     }
 
+    GraphProtocol(GraphProtocol<?, ?, ?, ?, ?, ?, ?, ?, ?> parent) {
+        this.versionMajor = parent.versionMajor;
+        this.versionMinor = parent.versionMinor;
+        this.constantPool = parent.constantPool;
+        this.buffer = parent.buffer;
+        this.channel = parent.channel;
+    }
+
     @SuppressWarnings("all")
     public final void print(Graph graph, Map<? extends Object, ? extends Object> properties, int id, String format, Object... args) throws IOException {
         writeByte(BEGIN_GRAPH);
@@ -137,9 +139,33 @@
 
     protected abstract ResolvedJavaMethod findMethod(Object obj);
 
+    /**
+     * Attempts to recognize the provided object as a node. Used to encode it with
+     * {@link #POOL_NODE} pool type.
+     *
+     * @param obj any object
+     * @return <code>null</code> if it is not a node object, non-null otherwise
+     */
+    protected abstract Node findNode(Object obj);
+
+    /**
+     * Determines whether the provided object is node class or not.
+     *
+     * @param obj object to check
+     * @return {@code null} if {@code obj} does not represent a NodeClass otherwise the NodeClass
+     *         represented by {@code obj}
+     */
     protected abstract NodeClass findNodeClass(Object obj);
 
     /**
+     * Returns the NodeClass for a given Node {@code obj}.
+     *
+     * @param obj instance of node
+     * @return non-{@code null} instance of the node's class object
+     */
+    protected abstract NodeClass findClassForNode(Node obj);
+
+    /**
      * Find a Java class. The returned object must be acceptable by
      * {@link #findJavaTypeName(java.lang.Object)} and return valid name for the class.
      *
@@ -239,7 +265,7 @@
     private void flush() throws IOException {
         buffer.flip();
         /*
-         * Try not to let interrupted threads aborting the write. There's still a race here but an
+         * Try not to let interrupted threads abort the write. There's still a race here but an
          * interrupt that's been pending for a long time shouldn't stop this writing.
          */
         boolean interrupted = Thread.interrupted();
@@ -338,7 +364,8 @@
         }
     }
 
-    private void writePoolObject(Object object) throws IOException {
+    private void writePoolObject(Object obj) throws IOException {
+        Object object = obj;
         if (object == null) {
             writeByte(POOL_NULL);
             return;
@@ -347,23 +374,31 @@
         if (id == null) {
             addPoolEntry(object);
         } else {
-            if (object instanceof Enum<?> || findEnumOrdinal(object) >= 0) {
-                writeByte(POOL_ENUM);
-            } else if (object instanceof Class<?> || findJavaTypeName(object) != null) {
-                writeByte(POOL_CLASS);
-            } else if (findJavaField(object) != null) {
+            if (findJavaField(object) != null) {
                 writeByte(POOL_FIELD);
             } else if (findSignature(object) != null) {
                 writeByte(POOL_SIGNATURE);
             } else if (versionMajor >= 4 && findNodeSourcePosition(object) != null) {
                 writeByte(POOL_NODE_SOURCE_POSITION);
             } else {
+                final Node node = findNode(object);
+                if (versionMajor == 4 && node != null) {
+                    object = classForNode(node);
+                }
                 if (findNodeClass(object) != null) {
                     writeByte(POOL_NODE_CLASS);
+                } else if (versionMajor >= 5 && node != null) {
+                    writeByte(POOL_NODE);
                 } else if (findMethod(object) != null) {
                     writeByte(POOL_METHOD);
                 } else {
-                    writeByte(POOL_STRING);
+                    if (object instanceof Enum<?> || findEnumOrdinal(object) >= 0) {
+                        writeByte(POOL_ENUM);
+                    } else if (object instanceof Class<?> || findJavaTypeName(object) != null) {
+                        writeByte(POOL_CLASS);
+                    } else {
+                        writeByte(POOL_STRING);
+                    }
                 }
             }
             writeShort(id.charValue());
@@ -383,10 +418,7 @@
         writeInt(size);
         int cnt = 0;
         for (Node node : findNodes(info)) {
-            NodeClass nodeClass = findNodeClass(node);
-            if (nodeClass == null) {
-                throw new IOException("No class for " + node);
-            }
+            NodeClass nodeClass = classForNode(node);
             findNodeProperties(node, props, info);
 
             writeInt(findNodeId(node));
@@ -405,7 +437,7 @@
     }
 
     private void writeEdges(Graph graph, Node node, boolean dumpInputs) throws IOException {
-        NodeClass clazz = findNodeClass(node);
+        NodeClass clazz = classForNode(node);
         Edges edges = findClassEdges(clazz, dumpInputs);
         int size = findSize(edges);
         for (int i = 0; i < size; i++) {
@@ -434,6 +466,14 @@
         }
     }
 
+    private NodeClass classForNode(Node node) throws IOException {
+        NodeClass clazz = findClassForNode(node);
+        if (clazz == null) {
+            throw new IOException("No class for " + node);
+        }
+        return clazz;
+    }
+
     private void writeNodeRef(Node node) throws IOException {
         writeInt(findNodeId(node));
     }
@@ -480,7 +520,8 @@
     }
 
     @SuppressWarnings("all")
-    private void addPoolEntry(Object object) throws IOException {
+    private void addPoolEntry(Object obj) throws IOException {
+        Object object = obj;
         ResolvedJavaField field;
         String typeName;
         Signature signature;
@@ -489,24 +530,7 @@
         char index = constantPool.add(object);
         writeByte(POOL_NEW);
         writeShort(index);
-        if ((typeName = findJavaTypeName(object)) != null) {
-            writeByte(POOL_CLASS);
-            writeString(typeName);
-            String[] enumValueNames = findEnumTypeValues(object);
-            if (enumValueNames != null) {
-                writeByte(ENUM_KLASS);
-                writeInt(enumValueNames.length);
-                for (String o : enumValueNames) {
-                    writePoolObject(o);
-                }
-            } else {
-                writeByte(KLASS);
-            }
-        } else if ((enumOrdinal = findEnumOrdinal(object)) >= 0) {
-            writeByte(POOL_ENUM);
-            writePoolObject(findEnumClass(object));
-            writeInt(enumOrdinal);
-        } else if ((field = findJavaField(object)) != null) {
+        if ((field = findJavaField(object)) != null) {
             writeByte(POOL_FIELD);
             writePoolObject(findFieldDeclaringClass(field));
             writePoolObject(findFieldName(field));
@@ -535,6 +559,18 @@
             }
             writePoolObject(findNodeSourcePositionCaller(pos));
         } else {
+            Node node = findNode(object);
+            if (node != null) {
+                if (versionMajor >= 5) {
+                    writeByte(POOL_NODE);
+                    writeInt(findNodeId(node));
+                    writePoolObject(classForNode(node));
+                    return;
+                }
+                if (versionMajor == 4) {
+                    object = classForNode(node);
+                }
+            }
             NodeClass nodeClass = findNodeClass(object);
             if (nodeClass != null) {
                 writeByte(POOL_NODE_CLASS);
@@ -553,8 +589,27 @@
             }
             ResolvedJavaMethod method = findMethod(object);
             if (method == null) {
-                writeByte(POOL_STRING);
-                writeString(object.toString());
+                if ((typeName = findJavaTypeName(object)) != null) {
+                    writeByte(POOL_CLASS);
+                    writeString(typeName);
+                    String[] enumValueNames = findEnumTypeValues(object);
+                    if (enumValueNames != null) {
+                        writeByte(ENUM_KLASS);
+                        writeInt(enumValueNames.length);
+                        for (String o : enumValueNames) {
+                            writePoolObject(o);
+                        }
+                    } else {
+                        writeByte(KLASS);
+                    }
+                } else if ((enumOrdinal = findEnumOrdinal(object)) >= 0) {
+                    writeByte(POOL_ENUM);
+                    writePoolObject(findEnumClass(object));
+                    writeInt(enumOrdinal);
+                } else {
+                    writeByte(POOL_STRING);
+                    writeString(object.toString());
+                }
                 return;
             }
             writeByte(POOL_METHOD);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/GraphSnippets.java	Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,285 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 org.graalvm.graphio;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.channels.FileChannel;
+import java.nio.channels.WritableByteChannel;
+import java.util.Collection;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
+
+final class GraphSnippets {
+    static GraphStructure<AcmeGraph, AcmeNode, AcmeNodeType, AcmePorts> acmeGraphStructure() {
+        // @formatter:off
+        // BEGIN: org.graalvm.graphio.GraphSnippets#acmeGraphStructure
+        class AcmeGraphStructure implements
+        GraphStructure<AcmeGraph, AcmeNode, AcmeNodeType, AcmePorts> {
+
+            @Override
+            public AcmeGraph graph(AcmeGraph currentGraph, Object obj) {
+                return obj instanceof AcmeGraph ? (AcmeGraph) obj : null;
+            }
+
+            @Override
+            public Iterable<? extends AcmeNode> nodes(AcmeGraph graph) {
+                return graph.allNodes();
+            }
+
+            @Override
+            public int nodesCount(AcmeGraph graph) {
+                return graph.allNodes().size();
+            }
+
+            @Override
+            public int nodeId(AcmeNode node) {
+                return node.id;
+            }
+
+            @Override
+            public boolean nodeHasPredecessor(AcmeNode node) {
+                return node.id > 0;
+            }
+
+            @Override
+            public void nodeProperties(
+                AcmeGraph graph, AcmeNode node, Map<String, ? super Object> properties
+            ) {
+                properties.put("id", node.id);
+            }
+
+            @Override
+            public AcmeNodeType nodeClass(Object obj) {
+                return obj instanceof AcmeNodeType ? (AcmeNodeType) obj : null;
+            }
+
+            @Override
+            public AcmeNode node(Object obj) {
+                return obj instanceof AcmeNode ? (AcmeNode) obj : null;
+            }
+
+            @Override
+            public AcmeNodeType classForNode(AcmeNode node) {
+                // we have only one type of nodes
+                return AcmeNodeType.STANDARD;
+            }
+
+
+            @Override
+            public String nameTemplate(AcmeNodeType nodeClass) {
+                return "Acme ({p#id})";
+            }
+
+            @Override
+            public Object nodeClassType(AcmeNodeType nodeClass) {
+                return nodeClass.getClass();
+            }
+
+            @Override
+            public AcmePorts portInputs(AcmeNodeType nodeClass) {
+                return AcmePorts.INPUT;
+            }
+
+            @Override
+            public AcmePorts portOutputs(AcmeNodeType nodeClass) {
+                return AcmePorts.OUTPUT;
+            }
+
+            @Override
+            public int portSize(AcmePorts port) {
+                return port == AcmePorts.OUTPUT ? 1 : 0;
+            }
+
+            @Override
+            public boolean edgeDirect(AcmePorts port, int index) {
+                return false;
+            }
+
+            @Override
+            public String edgeName(AcmePorts port, int index) {
+                return port.name();
+            }
+
+            @Override
+            public Object edgeType(AcmePorts port, int index) {
+                return port;
+            }
+
+            @Override
+            public Collection<? extends AcmeNode> edgeNodes(
+                AcmeGraph graph, AcmeNode node, AcmePorts port, int index
+            ) {
+                if (port == AcmePorts.OUTPUT) {
+                    return node.outgoing.targets;
+                }
+                return null;
+            }
+        }
+
+        // END: org.graalvm.graphio.GraphSnippets#acmeGraphStructure
+
+        return new AcmeGraphStructure();
+    }
+
+    // BEGIN: org.graalvm.graphio.GraphSnippets#buildOutput
+    static GraphOutput<AcmeGraph, ?> buildOutput(WritableByteChannel channel)
+    throws IOException {
+        return GraphOutput.newBuilder(acmeGraphStructure()).
+            // use the latest version; currently 5.0
+            protocolVersion(5, 0).
+            build(channel);
+    }
+    // END: org.graalvm.graphio.GraphSnippets#buildOutput
+
+    // BEGIN: org.graalvm.graphio.GraphSnippets#buildAll
+    static GraphOutput<AcmeGraph, ?> buildAll(WritableByteChannel channel)
+    throws IOException {
+        GraphBlocks<AcmeGraph, AcmeBlocks, AcmeNode> graphBlocks = acmeBlocks();
+        GraphElements<AcmeMethod, AcmeField,
+            AcmeSignature, AcmeCodePosition> graphElements = acmeElements();
+        GraphTypes graphTypes = acmeTypes();
+
+        return GraphOutput.newBuilder(acmeGraphStructure()).
+            protocolVersion(5, 0).
+            blocks(graphBlocks).
+            elements(graphElements).
+            types(graphTypes).
+            build(channel);
+    }
+    // END: org.graalvm.graphio.GraphSnippets#buildAll
+
+    private static GraphTypes acmeTypes() {
+        GraphTypes graphTypes = null;
+        // in real world don't return null
+        return graphTypes;
+    }
+
+    private static GraphElements<AcmeMethod, AcmeField, AcmeSignature, AcmeCodePosition> acmeElements() {
+        GraphElements<AcmeMethod, AcmeField, AcmeSignature, AcmeCodePosition> graphElements = null;
+        // in real world don't return null
+        return graphElements;
+    }
+
+    private static GraphBlocks<AcmeGraph, AcmeBlocks, AcmeNode> acmeBlocks() {
+        GraphBlocks<AcmeGraph, AcmeBlocks, AcmeNode> graphBlocks = null;
+        // in real world don't return null
+        return graphBlocks;
+    }
+
+    private static class AcmeGraph {
+        final AcmeNode root;
+
+        AcmeGraph(AcmeNode root) {
+            this.root = root;
+        }
+
+        Set<AcmeNode> allNodes() {
+            return allNodes(root, new LinkedHashSet<>());
+        }
+
+        private static Set<AcmeNode> allNodes(AcmeNode node, Set<AcmeNode> collectTo) {
+            if (collectTo.add(node)) {
+                for (AcmeNode target : node.outgoing.targets) {
+                    allNodes(target, collectTo);
+                }
+            }
+            return collectTo;
+        }
+    }
+
+    private static class AcmeNode {
+        final int id;
+        final AcmeEdges outgoing;
+
+        AcmeNode(int id) {
+            this.id = id;
+            this.outgoing = new AcmeEdges();
+        }
+
+        void linkTo(AcmeNode target) {
+            outgoing.targets.add(target);
+        }
+    }
+
+    private enum AcmeNodeType {
+        STANDARD
+    }
+
+    private enum AcmePorts {
+        INPUT,
+        OUTPUT;
+    }
+
+    private static class AcmeEdges {
+        final Set<AcmeNode> targets;
+
+        AcmeEdges() {
+            this.targets = new LinkedHashSet<>();
+        }
+    }
+
+    private static class AcmeBlocks {
+    }
+
+    private static class AcmeMethod {
+    }
+
+    private static class AcmeField {
+    }
+
+    private static class AcmeSignature {
+    }
+
+    private static class AcmeCodePosition {
+    }
+
+    // BEGIN: org.graalvm.graphio.GraphSnippets#dump
+    static void dump(File toFile) throws IOException {
+        try (
+            FileChannel ch = new FileOutputStream(toFile).getChannel();
+            GraphOutput<AcmeGraph, ?> output = buildOutput(ch);
+        ) {
+            AcmeNode root = new AcmeNode(0);
+            AcmeNode n1 = new AcmeNode(1);
+            AcmeNode n2 = new AcmeNode(2);
+            AcmeNode n3 = new AcmeNode(3);
+
+            root.linkTo(n1);
+            root.linkTo(n2);
+            n1.linkTo(n3);
+            n2.linkTo(n3);
+
+            AcmeGraph diamondGraph = new AcmeGraph(root);
+
+            output.beginGroup(diamondGraph, "Diamond", "dia", null, 0, null);
+            output.print(diamondGraph, null, 0, "Diamond graph #%d", 1);
+            output.endGroup();
+        }
+    }
+    // END: org.graalvm.graphio.GraphSnippets#dump
+
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/GraphStructure.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/GraphStructure.java	Wed Nov 08 16:03:35 2017 -0500
@@ -38,9 +38,9 @@
  */
 public interface GraphStructure<G, N, C, P> {
     /**
-     * Casts the provided object to graph, if possible. If the given object <code>obj</code> can be
-     * seen as a graph or sub-graph of a graph, then return the properly typed instance. Otherwise
-     * return <code>null</code>
+     * Casts {@code obj} to graph, if possible. If the given object <code>obj</code> can be seen as
+     * a graph or sub-graph of a graph, then return the properly typed instance. Otherwise return
+     * <code>null</code>
      *
      * @param currentGraph the currently processed graph
      * @param obj an object to check and view as a graph
@@ -69,8 +69,8 @@
     int nodesCount(G graph);
 
     /**
-     * Id of a node. Each node in the graph is uniquely identified by a integer value. If two nodes
-     * have the same id, then they shall be <code>==</code> to each other.
+     * Id of {@code node}. Each node in the graph is uniquely identified by an integer value. If two
+     * nodes have the same id, then they shall be <code>==</code> to each other.
      *
      * @param node the node to query for an id
      * @return the id of the node
@@ -96,16 +96,35 @@
     void nodeProperties(G graph, N node, Map<String, ? super Object> properties);
 
     /**
-     * Finds the node class for the provided object, if possible. If the given object
-     * <code>obj</code> can be seen as an instance of node class or it is a node in this graph,
-     * return the properly typed instance of the node class. Otherwise return <code>null</code>
+     * Finds a node for {@code obj}, if possible. If the given object <code>obj</code> can be seen
+     * as an instance of node return the properly typed instance of the node class. Otherwise return
+     * <code>null</code>.
+     *
+     * @param obj an object to find node for
+     * @return appropriate graph object or <code>null</code> if the object doesn't represent a node
+     */
+    N node(Object obj);
+
+    /**
+     * Finds a node class for {@code obj}, if possible. If the given object <code>obj</code> can be
+     * seen as an instance of node class return the properly typed instance of the node class.
+     * Otherwise return <code>null</code>.
      *
      * @param obj an object to find node class for
-     * @return appropriate graph object or <code>null</code> if the object doesn't represent a graph
+     * @return appropriate graph object or <code>null</code> if the object doesn't represent a node
+     *         class
      */
     C nodeClass(Object obj);
 
     /**
+     * Finds a node class for {@code node}.
+     *
+     * @param node an instance of node in this graph
+     * @return the node's node class, never <code>null</code>
+     */
+    C classForNode(N node);
+
+    /**
      * The template used to build the name of nodes of this class. The template may use references
      * to inputs (&#123;i#inputName&#125;) and its properties (&#123;p#propertyName&#125;).
      *
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/ProtocolImpl.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/ProtocolImpl.java	Wed Nov 08 16:03:35 2017 -0500
@@ -34,9 +34,18 @@
     private final GraphBlocks<Graph, Block, Node> blocks;
     private final GraphElements<ResolvedJavaMethod, ResolvedJavaField, Signature, NodeSourcePosition> elements;
 
-    ProtocolImpl(GraphStructure<Graph, Node, NodeClass, Port> structure, GraphTypes enums, GraphBlocks<Graph, Block, Node> blocks,
+    ProtocolImpl(int major, int minor, GraphStructure<Graph, Node, NodeClass, Port> structure, GraphTypes enums, GraphBlocks<Graph, Block, Node> blocks,
                     GraphElements<ResolvedJavaMethod, ResolvedJavaField, Signature, NodeSourcePosition> elements, WritableByteChannel channel) throws IOException {
-        super(channel);
+        super(channel, major, minor);
+        this.structure = structure;
+        this.types = enums;
+        this.blocks = blocks;
+        this.elements = elements;
+    }
+
+    ProtocolImpl(GraphProtocol<?, ?, ?, ?, ?, ?, ?, ?, ?> parent, GraphStructure<Graph, Node, NodeClass, Port> structure, GraphTypes enums, GraphBlocks<Graph, Block, Node> blocks,
+                    GraphElements<ResolvedJavaMethod, ResolvedJavaField, Signature, NodeSourcePosition> elements) {
+        super(parent);
         this.structure = structure;
         this.types = enums;
         this.blocks = blocks;
@@ -49,11 +58,21 @@
     }
 
     @Override
+    protected Node findNode(Object obj) {
+        return structure.node(obj);
+    }
+
+    @Override
     protected NodeClass findNodeClass(Object obj) {
         return structure.nodeClass(obj);
     }
 
     @Override
+    protected NodeClass findClassForNode(Node obj) {
+        return structure.classForNode(obj);
+    }
+
+    @Override
     protected String findNameTemplate(NodeClass clazz) {
         return structure.nameTemplate(clazz);
     }
Binary file src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/doc-files/diamond.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/package-info.java	Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,86 @@
+
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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.
+ */
+
+/**
+ * Send your graphs to <b>IGV</b> via a socket or a file. This package allows one to easily encode
+ * any graph-like data structure and send it for visualization to
+ * <em>OracleLab's Ideal Graph Visualizer</em> tool. Assuming you already have your own data
+ * structure that contains <b>nodes</b> and <b>edges</b> among them, creating a
+ * {@link org.graalvm.graphio.GraphOutput} specialized for your data is a matter of implementing a
+ * single interface:
+ *
+ * {@link org.graalvm.graphio.GraphSnippets#acmeGraphStructure}
+ *
+ * The {@link org.graalvm.graphio.GraphStructure} interface defines the set of operations that are
+ * needed by the <em>graph protocol</em> to encode a graph into the <b>IGV</b> expected format. The
+ * graph structure is implemented as a so called
+ * <a href="http://wiki.apidesign.org/wiki/Singletonizer">singletonizer</a> API pattern: there is no
+ * need to change your data structures or implement some special interfaces - everything needed is
+ * provided by implementing the {@link org.graalvm.graphio.GraphStructure} operations.
+ * <p>
+ * The next step is to turn this graph structure into an instance of
+ * {@link org.graalvm.graphio.GraphOutput}. To do so use the associated
+ * {@link org.graalvm.graphio.GraphOutput.Builder builder} just like shown in the following method:
+ *
+ * {@link org.graalvm.graphio.GraphSnippets#buildOutput}
+ *
+ * Now you are ready to dump your graph into <b>IGV</b>. Where to obtain the right channel? One
+ * option is to create a {@link java.nio.channels.FileChannel} and dump the data into a file
+ * (preferrably with <code>.bgv</code> extension). The other is to open a socket to port
+ * <code>4445</code> (the default port <b>IGV</b> listens to) and dump the data there. Here is an
+ * example:
+ *
+ * {@link org.graalvm.graphio.GraphSnippets#dump}
+ *
+ * Call the {@code dump} method with pointer to file {@code diamond.bgv} and then you can open the
+ * file in <b>IGV</b>. The result will look like this:
+ * <p>
+ * <img src="doc-files/diamond.png">
+ * <p>
+ * You can verify the behavior directly in the <b>IGV</b> by downloading
+ * <a href="doc-files/diamond.bgv">diamond.bgv</a> file generated from the above diamond structure
+ * graph.
+ * <p>
+ * The primary <b>IGV</b> focus is on graphs used by Graal compiler. As such they aren't plain
+ * graphs, but contain various compiler oriented attributes:
+ * <ul>
+ * <li>{@linkplain org.graalvm.graphio.GraphBlocks code blocks} information</li>
+ * <li>{@linkplain org.graalvm.graphio.GraphElements method and fields} information</li>
+ * <li>Advanced support for {@linkplain org.graalvm.graphio.GraphTypes recognizing types}</li>
+ * </ul>
+ * all these additional interfaces ({@link org.graalvm.graphio.GraphBlocks},
+ * {@link org.graalvm.graphio.GraphElements} and {@link org.graalvm.graphio.GraphTypes}) are
+ * optional - they don't have to be provided. As such they can be specified via
+ * {@link org.graalvm.graphio.GraphOutput.Builder} instance methods, which may, but need not be
+ * called at all. Here is an example:
+ *
+ * {@link org.graalvm.graphio.GraphSnippets#buildAll}
+ *
+ * All these interfaces follow the
+ * <a href="http://wiki.apidesign.org/wiki/Singletonizer">singletonizer</a> API pattern again - e.g.
+ * no need to change your existing data structures, just implement the operations provided by the
+ * interfaces you pass into the builder. By combining these interfaces together you can get as rich,
+ * colorful, source linked graphs as Graal compiler produces to describe its optimizations.
+ */
+package org.graalvm.graphio;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.word/.checkstyle_checks.xml	Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,240 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE module PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.3//EN" "http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
+
+<!--
+    This configuration file was written by the eclipse-cs plugin configuration editor
+-->
+<!--
+    Checkstyle-Configuration: Checks
+    Description: none
+-->
+<module name="Checker">
+  <property name="severity" value="error"/>
+  <module name="TreeWalker">
+    <module name="AvoidStarImport">
+      <property name="allowClassImports" value="false"/>
+      <property name="allowStaticMemberImports" value="false"/>
+    </module>
+    <property name="tabWidth" value="4"/>
+    <module name="FileContentsHolder"/>
+    <module name="JavadocStyle">
+      <property name="checkHtml" value="false"/>
+    </module>
+    <module name="LocalFinalVariableName"/>
+    <module name="LocalVariableName"/>
+    <module name="MemberName">
+      <property name="format" value="^(([a-z][a-zA-Z0-9]*$)|(_[A-Z][a-zA-Z0-9]*_[a-z][a-zA-Z0-9]*$))"/>
+    </module>
+    <module name="MethodName"/>
+    <module name="PackageName"/>
+    <module name="ParameterName"/>
+    <module name="TypeName">
+      <property name="format" value="^[A-Z][_a-zA-Z0-9]*$"/>
+    </module>
+    <module name="RedundantImport"/>
+    <module name="LineLength">
+      <property name="max" value="250"/>
+    </module>
+    <module name="MethodParamPad"/>
+    <module name="NoWhitespaceAfter">
+      <property name="tokens" value="ARRAY_INIT,BNOT,DEC,DOT,INC,LNOT,UNARY_MINUS,UNARY_PLUS"/>
+    </module>
+    <module name="NoWhitespaceBefore">
+      <property name="tokens" value="SEMI,DOT,POST_DEC,POST_INC"/>
+    </module>
+    <module name="ParenPad"/>
+    <module name="TypecastParenPad">
+      <property name="tokens" value="RPAREN,TYPECAST"/>
+    </module>
+    <module name="WhitespaceAfter"/>
+    <module name="WhitespaceAround">
+      <property name="tokens" value="ASSIGN,BAND,BAND_ASSIGN,BOR,BOR_ASSIGN,BSR,BSR_ASSIGN,BXOR,BXOR_ASSIGN,COLON,DIV,DIV_ASSIGN,EQUAL,GE,GT,LAND,LE,LITERAL_ASSERT,LITERAL_CATCH,LITERAL_DO,LITERAL_ELSE,LITERAL_FINALLY,LITERAL_FOR,LITERAL_IF,LITERAL_RETURN,LITERAL_SYNCHRONIZED,LITERAL_TRY,LITERAL_WHILE,LOR,LT,MINUS,MINUS_ASSIGN,MOD,MOD_ASSIGN,NOT_EQUAL,PLUS,PLUS_ASSIGN,QUESTION,SL,SLIST,SL_ASSIGN,SR,SR_ASSIGN,STAR,STAR_ASSIGN,LITERAL_ASSERT,TYPE_EXTENSION_AND"/>
+    </module>
+    <module name="RedundantModifier"/>
+    <module name="AvoidNestedBlocks">
+      <property name="allowInSwitchCase" value="true"/>
+    </module>
+    <module name="EmptyBlock">
+      <property name="option" value="text"/>
+      <property name="tokens" value="LITERAL_DO,LITERAL_ELSE,LITERAL_FINALLY,LITERAL_IF,LITERAL_TRY,LITERAL_WHILE,STATIC_INIT"/>
+    </module>
+    <module name="LeftCurly"/>
+    <module name="NeedBraces"/>
+    <module name="RightCurly"/>
+    <module name="EmptyStatement"/>
+    <module name="HiddenField">
+      <property name="severity" value="ignore"/>
+      <property name="ignoreConstructorParameter" value="true"/>
+      <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
+    </module>
+    <module name="FinalClass"/>
+    <module name="HideUtilityClassConstructor">
+      <property name="severity" value="ignore"/>
+      <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
+    </module>
+    <module name="ArrayTypeStyle"/>
+    <module name="UpperEll"/>
+    <module name="FallThrough"/>
+    <module name="FinalLocalVariable">
+      <property name="severity" value="ignore"/>
+      <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
+    </module>
+    <module name="MultipleVariableDeclarations"/>
+    <module name="StringLiteralEquality">
+      <property name="severity" value="error"/>
+    </module>
+    <module name="SuperFinalize"/>
+    <module name="UnnecessaryParentheses">
+      <property name="severity" value="ignore"/>
+      <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
+    </module>
+    <module name="Indentation">
+      <property name="severity" value="ignore"/>
+      <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
+    </module>
+    <module name="StaticVariableName">
+      <property name="format" value="^[A-Za-z][a-zA-Z0-9]*$"/>
+    </module>
+    <module name="EmptyForInitializerPad"/>
+    <module name="EmptyForIteratorPad"/>
+    <module name="ModifierOrder"/>
+    <module name="DefaultComesLast"/>
+    <module name="InnerAssignment">
+      <property name="severity" value="ignore"/>
+      <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
+    </module>
+    <module name="ModifiedControlVariable"/>
+    <module name="MutableException">
+      <property name="severity" value="ignore"/>
+      <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
+    </module>
+    <module name="ParameterAssignment">
+      <property name="severity" value="ignore"/>
+      <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
+    </module>
+    <module name="RegexpSinglelineJava">
+      <metadata name="net.sf.eclipsecs.core.comment" value="Illegal trailing whitespace(s) at the end of the line."/>
+      <property name="format" value="\s$"/>
+      <property name="message" value="Illegal trailing whitespace(s) at the end of the line."/>
+      <property name="ignoreComments" value="true"/>
+      <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Checks for trailing spaces at the end of a line"/>
+    </module>
+    <module name="RegexpSinglelineJava">
+      <metadata name="net.sf.eclipsecs.core.comment" value="illegal space before a comma"/>
+      <property name="format" value=" ,"/>
+      <property name="message" value="illegal space before a comma"/>
+      <property name="ignoreComments" value="true"/>
+      <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Checks for whitespace before a comma."/>
+      <metadata name="com.atlassw.tools.eclipse.checkstyle.customMessage" value="Illegal whitespace before a comma."/>
+    </module>
+    <module name="RegexpSinglelineJava">
+      <property name="format" value="[^\x00-\x7F]"/>
+      <property name="message" value="Only use ASCII characters."/>
+    </module>
+    <module name="RegexpSinglelineJava">
+      <property name="format" value="new (Hashtable|Vector|Stack|StringBuffer)[^\w]"/>
+      <property name="message" value="Don't use old synchronized collection classes"/>
+    </module>
+    <module name="RegexpSinglelineJava">
+      <property name="format" value="instanceof MoveOp"/>
+      <property name="message" value="Do not use `op instanceof MoveOp`. Use `MoveOp.isMoveOp(op)` instead!"/>
+    </module>
+    <module name="RegexpSinglelineJava">
+      <property name="format" value="instanceof ValueMoveOp"/>
+      <property name="message" value="Do not use `op instanceof ValueMoveOp`. Use `ValueMoveOp.isValueMoveOp(op)` instead!"/>
+    </module>
+    <module name="RegexpSinglelineJava">
+      <property name="format" value="instanceof LoadConstantOp"/>
+      <property name="message" value="Do not use `op instanceof LoadConstantOp`. Use `LoadConstantOp.isLoadConstantOp(op)` instead!"/>
+    </module>
+    <module name="RegexpSinglelineJava">
+      <property name="format" value="\(MoveOp\)"/>
+      <property name="message" value="Do not cast directly to `MoveOp`. Use `MoveOp.asMoveOp(op)` instead!"/>
+    </module>
+    <module name="RegexpSinglelineJava">
+      <property name="format" value="\(ValueMoveOp\)"/>
+      <property name="message" value="Do not cast directly to `ValueMoveOp`. Use `ValueMoveOp.asValueMoveOp(op)` instead!"/>
+    </module>
+    <module name="RegexpSinglelineJava">
+      <property name="format" value="\(LoadConstantOp\)"/>
+      <property name="message" value="Do not cast directly to `LoadConstantOp`. Use `LoadConstantOp.asLoadConstantOp(op)` instead!"/>
+    </module>
+  </module>
+  <module name="RegexpHeader">
+    <property name="header" value="/\*\n \* Copyright \(c\) (20[0-9][0-9], )?20[0-9][0-9], Oracle and/or its affiliates. All rights reserved.\n \* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n \*\n \* This code is free software; you can redistribute it and/or modify it\n \* under the terms of the GNU General Public License version 2 only, as\n \* published by the Free Software Foundation.  Oracle designates this\n \* particular file as subject to the &quot;Classpath&quot; exception as provided\n \* by Oracle in the LICENSE file that accompanied this code.\n \*\n \* This code is distributed in the hope that it will be useful, but WITHOUT\n \* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n \* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n \* version 2 for more details \(a copy is included in the LICENSE file that\n \* accompanied this code\).\n \*\n \* You should have received a copy of the GNU General Public License version\n \* 2 along with this work; if not, write to the Free Software Foundation,\n \* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n \*\n \* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n \* or visit www.oracle.com if you need additional information or have any\n \* questions.\n \*/\n"/>
+    <property name="fileExtensions" value="java"/>
+  </module>
+  <module name="FileTabCharacter">
+    <property name="severity" value="error"/>
+    <property name="fileExtensions" value="java"/>
+  </module>
+  <module name="NewlineAtEndOfFile">
+    <property name="lineSeparator" value="lf"/>
+  </module>
+  <module name="Translation"/>
+  <module name="SuppressionCommentFilter">
+    <property name="offCommentFormat" value="Checkstyle: stop constant name check"/>
+    <property name="onCommentFormat" value="Checkstyle: resume constant name check"/>
+    <property name="checkFormat" value="ConstantNameCheck"/>
+    <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Allow non-conforming constant names"/>
+  </module>
+  <module name="SuppressionCommentFilter">
+    <property name="offCommentFormat" value="Checkstyle: stop method name check"/>
+    <property name="onCommentFormat" value="Checkstyle: resume method name check"/>
+    <property name="checkFormat" value="MethodName"/>
+    <property name="checkC" value="false"/>
+    <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable method name checks"/>
+  </module>
+  <module name="SuppressionCommentFilter">
+    <property name="offCommentFormat" value="CheckStyle: stop parameter assignment check"/>
+    <property name="onCommentFormat" value="CheckStyle: resume parameter assignment check"/>
+    <property name="checkFormat" value="ParameterAssignment"/>
+    <property name="checkC" value="false"/>
+    <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable Parameter Assignment"/>
+  </module>
+  <module name="SuppressionCommentFilter">
+    <property name="offCommentFormat" value="Checkstyle: stop final variable check"/>
+    <property name="onCommentFormat" value="Checkstyle: resume final variable check"/>
+    <property name="checkFormat" value="FinalLocalVariable"/>
+    <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable final variable checks"/>
+  </module>
+  <module name="SuppressionCommentFilter">
+    <property name="offCommentFormat" value="Checkstyle: stop"/>
+    <property name="onCommentFormat" value="Checkstyle: resume"/>
+    <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable all checks"/>
+  </module>
+  <module name="SuppressionCommentFilter">
+    <property name="offCommentFormat" value="CheckStyle: stop inner assignment check"/>
+    <property name="onCommentFormat" value="CheckStyle: resume inner assignment check"/>
+    <property name="checkFormat" value="InnerAssignment"/>
+    <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable inner assignment checks"/>
+  </module>
+  <module name="SuppressionCommentFilter">
+    <property name="offCommentFormat" value="Checkstyle: stop field name check"/>
+    <property name="onCommentFormat" value="Checkstyle: resume field name check"/>
+    <property name="checkFormat" value="MemberName"/>
+    <property name="checkC" value="false"/>
+    <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable field name checks"/>
+  </module>
+  <module name="RegexpMultiline">
+    <metadata name="net.sf.eclipsecs.core.comment" value="illegal Windows line ending"/>
+    <property name="format" value="\r\n"/>
+    <property name="message" value="illegal Windows line ending"/>
+  </module>
+  <module name="SuppressionCommentFilter">
+    <property name="offCommentFormat" value="CheckStyle: stop header check"/>
+    <property name="onCommentFormat" value="CheckStyle: resume header check"/>
+    <property name="checkFormat" value=".*Header"/>
+    <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable header checks"/>
+  </module>
+  <module name="SuppressionCommentFilter">
+    <property name="offCommentFormat" value="CheckStyle: stop line length check"/>
+    <property name="onCommentFormat" value="CheckStyle: resume line length check"/>
+    <property name="checkFormat" value="LineLength"/>
+  </module>
+  <module name="SuppressionCommentFilter">
+    <property name="offCommentFormat" value="CheckStyle: start generated"/>
+    <property name="onCommentFormat" value="CheckStyle: stop generated"/>
+    <property name="checkFormat" value=".*Name|.*LineLength|.*Header"/>
+  </module>
+</module>
--- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SystemModulesPlugin.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SystemModulesPlugin.java	Wed Nov 08 16:03:35 2017 -0500
@@ -58,8 +58,6 @@
 import java.util.stream.Collectors;
 
 import jdk.internal.module.Checks;
-import jdk.internal.module.ClassFileAttributes;
-import jdk.internal.module.ClassFileConstants;
 import jdk.internal.module.DefaultRoots;
 import jdk.internal.module.IllegalAccessMaps;
 import jdk.internal.module.ModuleHashes;
@@ -68,13 +66,13 @@
 import jdk.internal.module.ModuleReferenceImpl;
 import jdk.internal.module.ModuleResolution;
 import jdk.internal.module.ModuleTarget;
-import jdk.internal.org.objectweb.asm.Attribute;
+
 import jdk.internal.org.objectweb.asm.ClassReader;
 import jdk.internal.org.objectweb.asm.ClassVisitor;
 import jdk.internal.org.objectweb.asm.ClassWriter;
 import jdk.internal.org.objectweb.asm.MethodVisitor;
+import jdk.internal.org.objectweb.asm.ModuleVisitor;
 import jdk.internal.org.objectweb.asm.Opcodes;
-
 import static jdk.internal.org.objectweb.asm.Opcodes.*;
 
 import jdk.tools.jlink.internal.ModuleSorter;
@@ -435,24 +433,25 @@
         }
 
         boolean hasModulePackages() throws IOException {
-            Set<String> attrTypes = new HashSet<>();
-            ClassVisitor cv = new ClassVisitor(Opcodes.ASM5) {
+            Set<String> packages = new HashSet<>();
+            ClassVisitor cv = new ClassVisitor(Opcodes.ASM6) {
                 @Override
-                public void visitAttribute(Attribute attr) {
-                    attrTypes.add(attr.type);
+                public ModuleVisitor visitModule(String name,
+                                                 int flags,
+                                                 String version) {
+                    return new ModuleVisitor(Opcodes.ASM6) {
+                        public void visitPackage(String pn) {
+                            packages.add(pn);
+                        }
+                    };
                 }
             };
 
-            // prototype of attributes that should be parsed
-            Attribute[] attrs = new Attribute[] {
-                new ClassFileAttributes.ModulePackagesAttribute()
-            };
-
             try (InputStream in = getInputStream()) {
                 // parse module-info.class
                 ClassReader cr = new ClassReader(in);
-                cr.accept(cv, attrs, 0);
-                return attrTypes.contains(ClassFileConstants.MODULE_PACKAGES);
+                cr.accept(cv, 0);
+                return packages.size() > 0;
             }
         }
 
--- a/src/jdk.jshell/share/classes/jdk/internal/jshell/debug/InternalDebugControl.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.jshell/share/classes/jdk/internal/jshell/debug/InternalDebugControl.java	Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,11 +29,10 @@
 import jdk.jshell.JShell;
 
 /**
-/**
  * This class is used to externally control output messages for debugging the
  * implementation of the JShell API.
  * <p>
- * This is not part of the SPI, not API.
+ * This is not part of the SPI nor API.
  */
 public class InternalDebugControl {
 
@@ -141,7 +140,7 @@
      * @param ex the fatal Exception
      * @param where additional context
      */
-    public static void debug(JShell state, PrintStream err, Exception ex, String where) {
+    public static void debug(JShell state, PrintStream err, Throwable ex, String where) {
         if (isDebugEnabled(state, 0xFFFFFFFF)) {
             err.printf("Fatal error: %s: %s\n", where, ex.getMessage());
             ex.printStackTrace(err);
--- a/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java	Wed Nov 08 16:03:35 2017 -0500
@@ -237,7 +237,11 @@
                                              .distinct()
                                              .count() == 2;
                 boolean tooManyItems = suggestions.size() > in.getAutoprintThreshold();
-                CompletionTask ordinaryCompletion = new OrdinaryCompletionTask(suggestions, anchor[0], !command && !doc.isEmpty(), hasSmart);
+                CompletionTask ordinaryCompletion =
+                        new OrdinaryCompletionTask(suggestions,
+                                                   anchor[0],
+                                                   !command && !doc.isEmpty(),
+                                                   hasBoth);
                 CompletionTask allCompletion = new AllSuggestionsCompletionTask(suggestions, anchor[0]);
 
                 todo = new ArrayList<>();
@@ -439,16 +443,16 @@
         private final List<Suggestion> suggestions;
         private final int anchor;
         private final boolean cont;
-        private final boolean smart;
+        private final boolean showSmart;
 
         public OrdinaryCompletionTask(List<Suggestion> suggestions,
                                       int anchor,
                                       boolean cont,
-                                      boolean smart) {
+                                      boolean showSmart) {
             this.suggestions = suggestions;
             this.anchor = anchor;
             this.cont = cont;
-            this.smart = smart;
+            this.showSmart = showSmart;
         }
 
         @Override
@@ -460,7 +464,7 @@
         public Result perform(String text, int cursor) throws IOException {
             List<CharSequence> toShow;
 
-            if (smart) {
+            if (showSmart) {
                 toShow =
                     suggestions.stream()
                                .filter(Suggestion::matchesType)
@@ -487,7 +491,7 @@
             String prefixStr = prefix.orElse("").substring(cursor - anchor);
             in.putString(prefixStr);
 
-            boolean showItems = toShow.size() > 1 || smart;
+            boolean showItems = toShow.size() > 1 || showSmart;
 
             if (showItems) {
                 in.println();
@@ -495,7 +499,7 @@
             }
 
             if (!prefixStr.isEmpty())
-                return showItems ? Result.SKIP : Result.SKIP_NOREPAINT;
+                return showItems ? Result.FINISH : Result.SKIP_NOREPAINT;
 
             return cont ? Result.CONTINUE : Result.FINISH;
         }
--- a/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java	Wed Nov 08 16:03:35 2017 -0500
@@ -184,6 +184,7 @@
     private IOContext input = null;
     private boolean regenerateOnDeath = true;
     private boolean live = false;
+    private boolean interactiveModeBegun = false;
     private Options options;
 
     SourceCodeAnalysis analysis;
@@ -499,9 +500,13 @@
 
         @Override
         void msg(String key, Object... args) {
-            startmsg(key, args);
+            errormsg(key, args);
         }
 
+        /**
+         * Parse the command line options.
+         * @return the options as an Options object, or null if error
+         */
         @Override
         Options parse(OptionSet options) {
             if (options.has(argHelp)) {
@@ -541,7 +546,7 @@
             if (options.has(argStart)) {
                 List<String> sts = options.valuesOf(argStart);
                 if (options.has("no-startup")) {
-                    startmsg("jshell.err.opt.startup.conflict");
+                    msg("jshell.err.opt.startup.conflict");
                     return null;
                 }
                 initialStartup = Startup.fromFileList(sts, "--startup", new InitMessageHandler());
@@ -649,16 +654,6 @@
     }
 
     /**
-     * Base output for command output -- no pre- or post-fix
-     *
-     * @param printf format
-     * @param printf args
-     */
-    void rawout(String format, Object... args) {
-        cmdout.printf(format, args);
-    }
-
-    /**
      * Must show command output
      *
      * @param format printf format
@@ -666,17 +661,17 @@
      */
     @Override
     public void hard(String format, Object... args) {
-        rawout(prefix(format), args);
+        cmdout.printf(prefix(format), args);
     }
 
-    /**
+   /**
      * Error command output
      *
      * @param format printf format
      * @param args printf args
      */
     void error(String format, Object... args) {
-        rawout(prefixError(format), args);
+        (interactiveModeBegun? cmdout : cmderr).printf(prefixError(format), args);
     }
 
     /**
@@ -749,7 +744,8 @@
 
     /**
      * Add prefixing/postfixing to embedded newlines in a string,
-     * bracketing with prefix/postfix
+     * bracketing with prefix/postfix.  No prefixing when non-interactive.
+     * Result is expected to be the format for a printf.
      *
      * @param s the string to prefix
      * @param pre the string to prepend to each line
@@ -760,6 +756,10 @@
         if (s == null) {
             return "";
         }
+        if (!interactiveModeBegun) {
+            // messages expect to be new-line terminated (even when not prefixed)
+            return s + "%n";
+        }
         String pp = s.replaceAll("\\R", post + pre);
         if (pp.endsWith(post + pre)) {
             // prevent an extra prefix char and blank line when the string
@@ -810,21 +810,7 @@
      */
     @Override
     public void errormsg(String key, Object... args) {
-        if (isRunningInteractive()) {
-            rawout(prefixError(messageFormat(key, args)));
-        } else {
-            startmsg(key, args);
-        }
-    }
-
-    /**
-     * Print command-line error using resource bundle look-up, MessageFormat
-     *
-     * @param key the resource key
-     * @param args
-     */
-    void startmsg(String key, Object... args) {
-        cmderr.println(messageFormat(key, args));
+        error(messageFormat(key, args));
     }
 
     /**
@@ -847,7 +833,7 @@
                 LinkedHashMap::new));
         for (Entry<String, String> e : a2b.entrySet()) {
             hard("%s", e.getKey());
-            rawout(prefix(e.getValue(), feedback.getPre() + "\t", feedback.getPost()));
+            cmdout.printf(prefix(e.getValue(), feedback.getPre() + "\t", feedback.getPost()));
         }
     }
 
@@ -899,7 +885,10 @@
         replayableHistoryPrevious = ReplayableHistory.fromPrevious(prefs);
         // load snippet/command files given on command-line
         for (String loadFile : commandLineArgs.nonOptions()) {
-            runFile(loadFile, "jshell");
+            if (!runFile(loadFile, "jshell")) {
+                // Load file failed -- abort
+                return;
+            }
         }
         // if we survived that...
         if (regenerateOnDeath) {
@@ -909,6 +898,7 @@
         // check again, as feedback setting could have failed
         if (regenerateOnDeath) {
             // if we haven't died, and the feedback mode wants fluff, print welcome
+            interactiveModeBegun = true;
             if (feedback.shouldDisplayCommandFluff()) {
                 hardmsg("jshell.msg.welcome", version());
             }
@@ -994,7 +984,7 @@
 
         @Override
         public void errormsg(String messageKey, Object... args) {
-            startmsg(messageKey, args);
+            JShellTool.this.errormsg(messageKey, args);
         }
 
         @Override
@@ -1034,6 +1024,7 @@
         shutdownSubscription = state.onShutdown((JShell deadState) -> {
             if (deadState == state) {
                 hardmsg("jshell.msg.terminated");
+                fluffmsg("jshell.msg.terminated.restore");
                 live = false;
             }
         });
@@ -1056,10 +1047,6 @@
         currentNameSpace = mainNamespace;
     }
 
-    private boolean isRunningInteractive() {
-        return currentNameSpace != null && currentNameSpace == mainNamespace;
-    }
-
     //where -- one-time per run initialization of feedback modes
     private void initFeedback(String initMode) {
         // No fluff, no prefix, for init failures
@@ -1096,8 +1083,8 @@
         try (IOContext suin = new ScannerIOContext(new StringReader(start))) {
             run(suin);
         } catch (Exception ex) {
-            hardmsg("jshell.err.startup.unexpected.exception", ex);
-            ex.printStackTrace(cmdout);
+            errormsg("jshell.err.startup.unexpected.exception", ex);
+            ex.printStackTrace(cmderr);
         }
     }
 
@@ -1123,7 +1110,7 @@
             String incomplete = "";
             while (live) {
                 String prompt;
-                if (isRunningInteractive()) {
+                if (interactive()) {
                     prompt = testPrompt
                                     ? incomplete.isEmpty()
                                             ? "\u0005" //ENQ
@@ -1171,7 +1158,7 @@
     }
 
     private void addToReplayHistory(String s) {
-        if (isRunningInteractive()) {
+        if (!isCurrentlyRunningStartup) {
             replayableHistory.add(s);
         }
     }
@@ -2127,7 +2114,7 @@
                         fluff("Wrap debugging on");
                         break;
                     default:
-                        hard("Unknown debugging option: %c", ch);
+                        error("Unknown debugging option: %c", ch);
                         fluff("Use: 0 r g f c d e w");
                         return false;
                 }
@@ -2697,7 +2684,7 @@
                     }
                     currSrcs = nextSrcs;
                 } catch (IllegalStateException ex) {
-                    hardmsg("jshell.msg.resetting");
+                    errormsg("jshell.msg.resetting");
                     resetState();
                     currSrcs = new LinkedHashSet<>(); // re-process everything
                 }
@@ -2746,16 +2733,21 @@
     private boolean runFile(String filename, String context) {
         if (!filename.isEmpty()) {
             try {
-                Path path = toPathResolvingUserHome(filename);
-                Reader reader;
-                String resource;
-                if (!Files.exists(path) && (resource = getResource(filename)) != null) {
-                    // Not found as file, but found as resource
-                    reader = new StringReader(resource);
+                Scanner scanner;
+                if (!interactiveModeBegun && filename.equals("-")) {
+                    // - on command line: no interactive later, read from input
+                    regenerateOnDeath = false;
+                    scanner = new Scanner(cmdin);
                 } else {
-                    reader = new FileReader(path.toString());
+                    Path path = toPathResolvingUserHome(filename);
+                    String resource;
+                    scanner = new Scanner(
+                            (!Files.exists(path) && (resource = getResource(filename)) != null)
+                            ? new StringReader(resource) // Not found as file, but found as resource
+                            : new FileReader(path.toString())
+                    );
                 }
-                run(new ScannerIOContext(reader));
+                run(new ScannerIOContext(scanner));
                 return true;
             } catch (FileNotFoundException e) {
                 errormsg("jshell.err.file.not.found", context, filename, e.getMessage());
@@ -2841,7 +2833,7 @@
                 sb.append(a);
             }
             if (sb.length() > 0) {
-                rawout(prefix(sb.toString()));
+                hard(sb.toString());
             }
             return false;
         }
@@ -3175,11 +3167,11 @@
         if (ste.causeSnippet() == null) {
             // main event
             for (Diag d : diagnostics) {
-                hardmsg(d.isError()? "jshell.msg.error" : "jshell.msg.warning");
+                errormsg(d.isError()? "jshell.msg.error" : "jshell.msg.warning");
                 List<String> disp = new ArrayList<>();
                 displayDiagnostics(source, d, disp);
                 disp.stream()
-                        .forEach(l -> hard("%s", l));
+                        .forEach(l -> error("%s", l));
             }
 
             if (ste.status() != Status.REJECTED) {
@@ -3190,7 +3182,7 @@
                     } else if (ste.exception() instanceof UnresolvedReferenceException) {
                         printUnresolvedException((UnresolvedReferenceException) ste.exception());
                     } else {
-                        hard("Unexpected execution exception: %s", ste.exception());
+                        error("Unexpected execution exception: %s", ste.exception());
                         return true;
                     }
                 } else {
@@ -3242,7 +3234,7 @@
                             : lineNumber >= 0
                                     ? fileName + ":" + lineNumber
                                     : fileName;
-            hard("      at %s(%s)", sb, loc);
+            error("      at %s(%s)", sb, loc);
 
         }
     }
@@ -3253,9 +3245,9 @@
     //where
     void printEvalException(EvalException ex) {
         if (ex.getMessage() == null) {
-            hard("%s thrown", ex.getExceptionClassName());
+            error("%s thrown", ex.getExceptionClassName());
         } else {
-            hard("%s thrown: %s", ex.getExceptionClassName(), ex.getMessage());
+            error("%s thrown: %s", ex.getExceptionClassName(), ex.getMessage());
         }
         printStackTrace(ex.getStackTrace());
     }
@@ -3394,7 +3386,7 @@
                         resolution, unrcnt, errcnt,
                         name, type, value, unresolved, errorLines);
                 if (!resolutionErrors.trim().isEmpty()) {
-                    hard("    %s", resolutionErrors);
+                    error("    %s", resolutionErrors);
                 }
             } else if (interactive()) {
                 String display = feedback.format(fcase, action, update,
@@ -3625,7 +3617,6 @@
         scannerIn.close();
     }
 
-    @Override
     public int readUserInput() {
         return -1;
     }
@@ -3657,7 +3648,6 @@
     public void close() {
     }
 
-    @Override
     public int readUserInput() {
         return -1;
     }
--- a/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties	Wed Nov 08 16:03:35 2017 -0500
@@ -33,9 +33,8 @@
 jshell.err.opt.feedback.one = Only one feedback option (--feedback, -q, -s, or -v) may be used.
 jshell.err.opt.unknown = Unknown option: {0}
 
-jshell.msg.terminated =\
-State engine terminated.\n\
-Restore definitions with: /reload -restore
+jshell.msg.terminated = State engine terminated.
+jshell.msg.terminated.restore = Restore definitions with: /reload -restore
 
 jshell.msg.use.one.of = Use one of: {0}
 jshell.msg.see.classes.etc = See /types, /methods, /vars, or /list
@@ -189,7 +188,7 @@
    /help shortcuts
 
 help.usage = \
-Usage:   jshell <options> <load files>\n\
+Usage:   jshell <option>... <load file>...\n\
 where possible options include:\n\
 \    --class-path <path>   Specify where to find user class files\n\
 \    --module-path <path>  Specify where to find application modules\n\
@@ -213,7 +212,11 @@
 \    --version             Print version information and exit\n\
 \    --show-version        Print version information and continue\n\
 \    --help                Print this synopsis of standard options and exit\n\
-\    --help-extra, -X      Print help on non-standard options and exit\n
+\    --help-extra, -X      Print help on non-standard options and exit\n\
+A file argument may be a file name, or one of the predefined file names: DEFAULT,\n\
+PRINTING, or JAVASE.\n\
+A load file may also be "-" to indicate standard input, without interactive I/O.\n
+
 help.usage.x = \
 \    --add-exports <module>/<package>   Export specified module-private package to snippets\n\
 \    --execution <spec>                 Specify an alternate execution engine.\n\
--- a/src/jdk.jshell/share/classes/jdk/jshell/Eval.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.jshell/share/classes/jdk/jshell/Eval.java	Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -48,6 +48,7 @@
 import java.io.IOException;
 import java.io.StringWriter;
 import java.io.Writer;
+import java.util.Arrays;
 import java.util.LinkedHashSet;
 import java.util.Set;
 import jdk.jshell.ExpressionToTypeInfo.ExpressionInfo;
@@ -100,6 +101,12 @@
 
     private final JShell state;
 
+    // The set of names of methods on Object
+    private final Set<String> objectMethods = Arrays
+            .stream(Object.class.getMethods())
+            .map(m -> m.getName())
+            .collect(toSet());
+
     Eval(JShell state) {
         this.state = state;
     }
@@ -528,10 +535,26 @@
     private List<Snippet> processMethod(String userSource, Tree unitTree, String compileSource, ParseTask pt) {
         TreeDependencyScanner tds = new TreeDependencyScanner();
         tds.scan(unitTree);
-        TreeDissector dis = TreeDissector.createByFirstClass(pt);
+        final TreeDissector dis = TreeDissector.createByFirstClass(pt);
+
+        final MethodTree mt = (MethodTree) unitTree;
+        final String name = mt.getName().toString();
+        if (objectMethods.contains(name)) {
+            // The name matches a method on Object, short of an overhaul, this
+            // fails, see 8187137.  Generate a descriptive error message
 
-        MethodTree mt = (MethodTree) unitTree;
-        String name = mt.getName().toString();
+            // The error position will be the position of the name, find it
+            long possibleStart = dis.getEndPosition(mt.getReturnType());
+            Range possibleRange = new Range((int) possibleStart,
+                    dis.getStartPosition(mt.getBody()));
+            String possibleNameSection = possibleRange.part(compileSource);
+            int offset = possibleNameSection.indexOf(name);
+            long start = offset < 0
+                    ? possibleStart // something wrong, punt
+                    : possibleStart + offset;
+
+            return compileFailResult(new DiagList(objectMethodNameDiag(name, start)), userSource, Kind.METHOD);
+        }
         String parameterTypes
                 = mt.getParameters()
                 .stream()
@@ -900,6 +923,47 @@
         return PREFIX_PATTERN.matcher(ste.getClassName()).find();
     }
 
+    /**
+     * Construct a diagnostic for a method name matching an Object method name
+     * @param name the method name
+     * @param nameStart the position within the source of the method name
+     * @return the generated diagnostic
+     */
+    private Diag objectMethodNameDiag(String name, long nameStart) {
+        return new Diag() {
+            @Override
+            public boolean isError() {
+                return true;
+            }
+
+            @Override
+            public long getPosition() {
+                return nameStart;
+            }
+
+            @Override
+            public long getStartPosition() {
+                return nameStart;
+            }
+
+            @Override
+            public long getEndPosition() {
+                return nameStart + name.length();
+            }
+
+            @Override
+            public String getCode() {
+                return "jdk.eval.error.object.method";
+            }
+
+            @Override
+            public String getMessage(Locale locale) {
+                return state.messageFormat("jshell.diag.object.method.fatal",
+                        String.join(" ", objectMethods));
+            }
+        };
+    }
+
     private DiagList modifierDiagnostics(ModifiersTree modtree,
             final TreeDissector dis, boolean isAbstractProhibited) {
 
--- a/src/jdk.jshell/share/classes/jdk/jshell/JShell.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.jshell/share/classes/jdk/jshell/JShell.java	Wed Nov 08 16:03:35 2017 -0500
@@ -807,7 +807,7 @@
         InternalDebugControl.debug(this, err, flags, format, args);
     }
 
-    void debug(Exception ex, String where) {
+    void debug(Throwable ex, String where) {
         InternalDebugControl.debug(this, err, ex, where);
     }
 
--- a/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysisImpl.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysisImpl.java	Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -58,7 +58,6 @@
 import com.sun.tools.javac.util.Pair;
 import jdk.jshell.CompletenessAnalyzer.CaInfo;
 import jdk.jshell.TaskFactory.AnalyzeTask;
-import jdk.jshell.TaskFactory.ParseTask;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -255,6 +254,9 @@
         suspendIndexing();
         try {
             return completionSuggestionsImpl(code, cursor, anchor);
+        } catch (Throwable exc) {
+            proc.debug(exc, "Exception thrown in SourceCodeAnalysisImpl.completionSuggestions");
+            return Collections.emptyList();
         } finally {
             resumeIndexing();
         }
@@ -1148,6 +1150,9 @@
         suspendIndexing();
         try {
             return documentationImpl(code, cursor, computeJavadoc);
+        } catch (Throwable exc) {
+            proc.debug(exc, "Exception thrown in SourceCodeAnalysisImpl.documentation");
+            return Collections.emptyList();
         } finally {
             resumeIndexing();
         }
--- a/src/jdk.jshell/share/classes/jdk/jshell/resources/l10n.properties	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.jshell/share/classes/jdk/jshell/resources/l10n.properties	Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,7 @@
 jshell.diag.modifier.plural.ignore = Modifiers {0} not permitted in top-level declarations, ignored
 jshell.diag.modifier.single.fatal = Modifier {0} not permitted in top-level declarations
 jshell.diag.modifier.single.ignore = Modifier {0} not permitted in top-level declarations, ignored
+jshell.diag.object.method.fatal = JShell method names must not match Object methods: {0}
 
 jshell.exc.null = Snippet must not be null
 jshell.exc.alien = Snippet not from this JShell: {0}
--- a/src/jdk.rmic/share/classes/sun/rmi/rmic/Main.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.rmic/share/classes/sun/rmi/rmic/Main.java	Wed Nov 08 16:03:35 2017 -0500
@@ -139,21 +139,6 @@
      */
     public synchronized boolean compile(String argv[]) {
 
-        /*
-         * Handle internal option to use the new (and incomplete) rmic
-         * implementation.  This option is handled here, rather than
-         * in parseArgs, so that none of the arguments will be nulled
-         * before delegating to the new implementation.
-         */
-        // disable the -Xnew option as per JDK-8146299 and JDK-8145980
-        // to allow further discussion how to progress with this feature
-        //for (int i = 0; i < argv.length; i++) {
-        //    if (argv[i].equals("-Xnew")) {
-        //        return (new sun.rmi.rmic.newrmic.Main(out,
-        //                                              program)).compile(argv);
-        //    }
-        //}
-
         if (!parseArgs(argv)) {
             return false;
         }
--- a/src/jdk.rmic/share/classes/sun/rmi/rmic/newrmic/BatchEnvironment.java	Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,145 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.rmi.rmic.newrmic;
-
-import com.sun.javadoc.ClassDoc;
-import com.sun.javadoc.RootDoc;
-import java.io.File;
-import java.text.MessageFormat;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import static sun.rmi.rmic.newrmic.Constants.*;
-
-/**
- * The environment for an rmic compilation batch.
- *
- * A BatchEnvironment contains a RootDoc, which is the entry point
- * into the doclet environment for the associated rmic compilation
- * batch.  A BatchEnvironment collects the source files generated
- * during the batch's execution, for eventual source code compilation
- * and, possibly, deletion.  Errors that occur during generation
- * activity should be reported through the BatchEnvironment's "error"
- * method.
- *
- * A protocol-specific generator class may require the use of a
- * particular BatchEnvironment subclass for enhanced environment
- * functionality.  A BatchEnvironment subclass must declare a
- * public constructor with one parameter of type RootDoc.
- *
- * WARNING: The contents of this source file are not part of any
- * supported API.  Code that depends on them does so at its own risk:
- * they are subject to change or removal without notice.
- *
- * @author Peter Jones
- **/
-public class BatchEnvironment {
-
-    private final RootDoc rootDoc;
-
-    /** cached ClassDoc for certain types used by rmic */
-    private final ClassDoc docRemote;
-    private final ClassDoc docException;
-    private final ClassDoc docRemoteException;
-    private final ClassDoc docRuntimeException;
-
-    private boolean verbose = false;
-    private final List<File> generatedFiles = new ArrayList<File>();
-
-    /**
-     * Creates a new BatchEnvironment with the specified RootDoc.
-     **/
-    public BatchEnvironment(RootDoc rootDoc) {
-        this.rootDoc = rootDoc;
-
-        /*
-         * Initialize cached ClassDoc for types used by rmic.  Note
-         * that any of these could be null if the boot class path is
-         * incorrect, which could cause a NullPointerException later.
-         */
-        docRemote = rootDoc().classNamed(REMOTE);
-        docException = rootDoc().classNamed(EXCEPTION);
-        docRemoteException = rootDoc().classNamed(REMOTE_EXCEPTION);
-        docRuntimeException = rootDoc().classNamed(RUNTIME_EXCEPTION);
-    }
-
-    /**
-     * Returns the RootDoc for this environment.
-     **/
-    public RootDoc rootDoc() {
-        return rootDoc;
-    }
-
-    public ClassDoc docRemote() { return docRemote; }
-    public ClassDoc docException() { return docException; }
-    public ClassDoc docRemoteException() { return docRemoteException; }
-    public ClassDoc docRuntimeException() { return docRuntimeException; }
-
-    /**
-     * Sets this environment's verbosity status.
-     **/
-    public void setVerbose(boolean verbose) {
-        this.verbose = verbose;
-    }
-
-    /**
-     * Returns this environment's verbosity status.
-     **/
-    public boolean verbose() {
-        return verbose;
-    }
-
-    /**
-     * Adds the specified file to the list of source files generated
-     * during this batch.
-     **/
-    public void addGeneratedFile(File file) {
-        generatedFiles.add(file);
-    }
-
-    /**
-     * Returns the list of files generated during this batch.
-     **/
-    public List<File> generatedFiles() {
-        return Collections.unmodifiableList(generatedFiles);
-    }
-
-    /**
-     * Outputs the specified (non-error) message.
-     **/
-    public void output(String msg) {
-        rootDoc.printNotice(msg);
-    }
-
-    /**
-     * Reports an error using the specified resource key and text
-     * formatting arguments.
-     **/
-    public void error(String key, String... args) {
-        rootDoc.printError(Resources.getText(key, args));
-    }
-}
--- a/src/jdk.rmic/share/classes/sun/rmi/rmic/newrmic/Constants.java	Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.rmi.rmic.newrmic;
-
-/**
- * Constants potentially useful to all rmic generators.
- *
- * WARNING: The contents of this source file are not part of any
- * supported API.  Code that depends on them does so at its own risk:
- * they are subject to change or removal without notice.
- *
- * @author Peter Jones
- **/
-public final class Constants {
-
-    private Constants() { throw new AssertionError(); }
-
-    /*
-     * fully-qualified names of types used by rmic
-     */
-    public static final String REMOTE = "java.rmi.Remote";
-    public static final String EXCEPTION = "java.lang.Exception";
-    public static final String REMOTE_EXCEPTION = "java.rmi.RemoteException";
-    public static final String RUNTIME_EXCEPTION = "java.lang.RuntimeException";
-}
--- a/src/jdk.rmic/share/classes/sun/rmi/rmic/newrmic/Generator.java	Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,87 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.rmi.rmic.newrmic;
-
-import com.sun.javadoc.ClassDoc;
-import java.io.File;
-import java.util.Set;
-
-/**
- * The interface to rmic back end implementations.  Classes that
- * implement this interface correspond to the various generation modes
- * of rmic (JRMP, IIOP, IDL, etc.).
- *
- * A Generator instance corresponds to a particular rmic compilation
- * batch, and its instance state represents the generator-specific
- * command line options for that batch.  Main will instantiate a
- * generator class when the command line arguments indicate selection
- * of the corresponding generation mode.  Main will then invoke the
- * "parseArgs" method to allow the generator to process any
- * generator-specific command line options and set its instance state
- * accordingly.
- *
- * WARNING: The contents of this source file are not part of any
- * supported API.  Code that depends on them does so at its own risk:
- * they are subject to change or removal without notice.
- *
- * @author Peter Jones
- **/
-public interface Generator {
-
-    /**
-     * Processes the command line options specific to this generator.
-     * Processed options are set to null in the specified array.
-     * Returns true if successful or false if an error occurs.  Errors
-     * are output to the specific Main instance.
-     **/
-    public boolean parseArgs(String[] args, Main main);
-
-    /**
-     * Returns the most specific environment class required by this
-     * generator.
-     **/
-    public Class<? extends BatchEnvironment> envClass();
-
-    /**
-     * Returns the names of the classes that must be available through
-     * the doclet API in order for this generator to function.
-     **/
-    public Set<String> bootstrapClassNames();
-
-    /**
-     * Generates the protocol-specific rmic output files for the
-     * specified remote class.  This method is invoked once for each
-     * class or interface specified on the command line for the rmic
-     * compilation batch associated with this instance.
-     *
-     * Any generated source files (to be compiled with javac) are
-     * passed to the addGeneratedFile method of the specified
-     * BatchEnvironment.
-     **/
-    public void generate(BatchEnvironment env,
-                         ClassDoc inputClass,
-                         File destDir);
-}
--- a/src/jdk.rmic/share/classes/sun/rmi/rmic/newrmic/IndentingWriter.java	Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,291 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.rmi.rmic.newrmic;
-
-import java.io.Writer;
-import java.io.BufferedWriter;
-import java.io.IOException;
-
-/**
- * A BufferedWriter that supports automatic indentation of lines of
- * text written to the underlying Writer.
- *
- * Methods are provided for compact/convenient indenting in and out,
- * writing text, and writing lines of text in various combinations.
- *
- * WARNING: The contents of this source file are not part of any
- * supported API.  Code that depends on them does so at its own risk:
- * they are subject to change or removal without notice.
- *
- * @author Peter Jones
- **/
-public class IndentingWriter extends BufferedWriter {
-
-    /** number of spaces to change indent when indenting in or out */
-    private final int indentStep;
-
-    /** number of spaces to convert into tabs (use MAX_VALUE to disable) */
-    private final int tabSize;
-
-    /** true if the next character written is the first on a line */
-    private boolean beginningOfLine = true;
-
-    /** current number of spaces to prepend to lines */
-    private int currentIndent = 0;
-
-    /**
-     * Creates a new IndentingWriter that writes indented text to the
-     * given Writer.  Use the default indent step of four spaces.
-     **/
-    public IndentingWriter(Writer out) {
-        this(out, 4);
-    }
-
-    /**
-     * Creates a new IndentingWriter that writes indented text to the
-     * given Writer and uses the supplied indent step.
-     **/
-    public IndentingWriter(Writer out, int indentStep) {
-        this(out, indentStep, 8);
-    }
-
-    /**
-     * Creates a new IndentingWriter that writes indented text to the
-     * given Writer and uses the supplied indent step and tab size.
-     **/
-    public IndentingWriter(Writer out, int indentStep, int tabSize) {
-        super(out);
-        if (indentStep < 0) {
-            throw new IllegalArgumentException("negative indent step");
-        }
-        if (tabSize < 0) {
-            throw new IllegalArgumentException("negative tab size");
-        }
-        this.indentStep = indentStep;
-        this.tabSize = tabSize;
-    }
-
-    /**
-     * Writes a single character.
-     **/
-    public void write(int c) throws IOException {
-        checkWrite();
-        super.write(c);
-    }
-
-    /**
-     * Writes a portion of an array of characters.
-     **/
-    public void write(char[] cbuf, int off, int len) throws IOException {
-        if (len > 0) {
-            checkWrite();
-        }
-        super.write(cbuf, off, len);
-    }
-
-    /**
-     * Writes a portion of a String.
-     **/
-    public void write(String s, int off, int len) throws IOException {
-        if (len > 0) {
-            checkWrite();
-        }
-        super.write(s, off, len);
-    }
-
-    /**
-     * Writes a line separator.  The next character written will be
-     * preceded by an indent.
-     **/
-    public void newLine() throws IOException {
-        super.newLine();
-        beginningOfLine = true;
-    }
-
-    /**
-     * Checks if an indent needs to be written before writing the next
-     * character.
-     *
-     * The indent generation is optimized (and made consistent with
-     * certain coding conventions) by condensing groups of eight
-     * spaces into tab characters.
-     **/
-    protected void checkWrite() throws IOException {
-        if (beginningOfLine) {
-            beginningOfLine = false;
-            int i = currentIndent;
-            while (i >= tabSize) {
-                super.write('\t');
-                i -= tabSize;
-            }
-            while (i > 0) {
-                super.write(' ');
-                i--;
-            }
-        }
-    }
-
-    /**
-     * Increases the current indent by the indent step.
-     **/
-    protected void indentIn() {
-        currentIndent += indentStep;
-    }
-
-    /**
-     * Decreases the current indent by the indent step.
-     **/
-    protected void indentOut() {
-        currentIndent -= indentStep;
-        if (currentIndent < 0)
-            currentIndent = 0;
-    }
-
-    /**
-     * Indents in.
-     **/
-    public void pI() {
-        indentIn();
-    }
-
-    /**
-     * Indents out.
-     **/
-    public void pO() {
-        indentOut();
-    }
-
-    /**
-     * Writes string.
-     **/
-    public void p(String s) throws IOException {
-        write(s);
-    }
-
-    /**
-     * Ends current line.
-     **/
-    public void pln() throws IOException {
-        newLine();
-    }
-
-    /**
-     * Writes string; ends current line.
-     **/
-    public void pln(String s) throws IOException {
-        p(s);
-        pln();
-    }
-
-    /**
-     * Writes string; ends current line; indents in.
-     **/
-    public void plnI(String s) throws IOException {
-        p(s);
-        pln();
-        pI();
-    }
-
-    /**
-     * Indents out; writes string.
-     **/
-    public void pO(String s) throws IOException {
-        pO();
-        p(s);
-    }
-
-    /**
-     * Indents out; writes string; ends current line.
-     **/
-    public void pOln(String s) throws IOException {
-        pO(s);
-        pln();
-    }
-
-    /**
-     * Indents out; writes string; ends current line; indents in.
-     *
-     * This method is useful for generating lines of code that both
-     * end and begin nested blocks, like "} else {".
-     **/
-    public void pOlnI(String s) throws IOException {
-        pO(s);
-        pln();
-        pI();
-    }
-
-    /**
-     * Writes object.
-     **/
-    public void p(Object o) throws IOException {
-        write(o.toString());
-    }
-
-    /**
-     * Writes object; ends current line.
-     **/
-    public void pln(Object o) throws IOException {
-        p(o.toString());
-        pln();
-    }
-
-    /**
-     * Writes object; ends current line; indents in.
-     **/
-    public void plnI(Object o) throws IOException {
-        p(o.toString());
-        pln();
-        pI();
-    }
-
-    /**
-     * Indents out; writes object.
-     **/
-    public void pO(Object o) throws IOException {
-        pO();
-        p(o.toString());
-    }
-
-    /**
-     * Indents out; writes object; ends current line.
-     **/
-    public void pOln(Object o) throws IOException {
-        pO(o.toString());
-        pln();
-    }
-
-    /**
-     * Indents out; writes object; ends current line; indents in.
-     *
-     * This method is useful for generating lines of code that both
-     * end and begin nested blocks, like "} else {".
-     **/
-    public void pOlnI(Object o) throws IOException {
-        pO(o.toString());
-        pln();
-        pI();
-    }
-}
--- a/src/jdk.rmic/share/classes/sun/rmi/rmic/newrmic/Main.java	Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,689 +0,0 @@
-/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.rmi.rmic.newrmic;
-
-import com.sun.javadoc.ClassDoc;
-import com.sun.javadoc.RootDoc;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.PrintStream;
-import java.io.PrintWriter;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import sun.rmi.rmic.newrmic.jrmp.JrmpGenerator;
-import sun.tools.util.CommandLine;
-
-/**
- * The rmic front end.  This class contains the "main" method for rmic
- * command line invocation.
- *
- * A Main instance contains the stream to output error messages and
- * other diagnostics to.
- *
- * An rmic compilation batch (for example, one rmic command line
- * invocation) is executed by invoking the "compile" method of a Main
- * instance.
- *
- * WARNING: The contents of this source file are not part of any
- * supported API.  Code that depends on them does so at its own risk:
- * they are subject to change or removal without notice.
- *
- * NOTE: If and when there is a J2SE API for invoking SDK tools, this
- * class should be updated to support that API.
- *
- * NOTE: This class is the front end for a "new" rmic implementation,
- * which uses javadoc and the doclet API for reading class files and
- * javac for compiling generated source files.  This implementation is
- * incomplete: it lacks any CORBA-based back end implementations, and
- * thus the command line options "-idl", "-iiop", and their related
- * options are not yet supported.  The front end for the "old",
- * oldjavac-based rmic implementation is sun.rmi.rmic.Main.
- *
- * @author Peter Jones
- **/
-public class Main {
-
-    /*
-     * Implementation note:
-     *
-     * In order to use the doclet API to read class files, much of
-     * this implementation of rmic executes as a doclet within an
-     * invocation of javadoc.  This class is used as the doclet class
-     * for such javadoc invocations, via its static "start" and
-     * "optionLength" methods.  There is one javadoc invocation per
-     * rmic compilation batch.
-     *
-     * The only guaranteed way to pass data to a doclet through a
-     * javadoc invocation is through doclet-specific options on the
-     * javadoc "command line".  Rather than passing numerous pieces of
-     * individual data in string form as javadoc options, we use a
-     * single doclet-specific option ("-batchID") to pass a numeric
-     * identifier that uniquely identifies the rmic compilation batch
-     * that the javadoc invocation is for, and that identifier can
-     * then be used as a key in a global table to retrieve an object
-     * containing all of batch-specific data (rmic command line
-     * arguments, etc.).
-     */
-
-    /** guards "batchCount" */
-    private static final Object batchCountLock = new Object();
-
-    /** number of batches run; used to generated batch IDs */
-    private static long batchCount = 0;
-
-    /** maps batch ID to batch data */
-    private static final Map<Long,Batch> batchTable =
-        Collections.synchronizedMap(new HashMap<Long,Batch>());
-
-    /** stream to output error messages and other diagnostics to */
-    private final PrintStream out;
-
-    /** name of this program, to use in error messages */
-    private final String program;
-
-    /**
-     * Command line entry point.
-     **/
-    public static void main(String[] args) {
-        Main rmic = new Main(System.err, "rmic");
-        System.exit(rmic.compile(args) ? 0 : 1);
-    }
-
-    /**
-     * Creates a Main instance that writes output to the specified
-     * stream.  The specified program name is used in error messages.
-     **/
-    public Main(OutputStream out, String program) {
-        this.out = out instanceof PrintStream ?
-            (PrintStream) out : new PrintStream(out);
-        this.program = program;
-    }
-
-    /**
-     * Compiles a batch of input classes, as given by the specified
-     * command line arguments.  Protocol-specific generators are
-     * determined by the choice options on the command line.  Returns
-     * true if successful, or false if an error occurred.
-     *
-     * NOTE: This method is retained for transitional consistency with
-     * previous implementations.
-     **/
-    public boolean compile(String[] args) {
-        long startTime = System.currentTimeMillis();
-
-        long batchID;
-        synchronized (batchCountLock) {
-            batchID = batchCount++;     // assign batch ID
-        }
-
-        // process command line
-        Batch batch = parseArgs(args);
-        if (batch == null) {
-            return false;               // terminate if error occurred
-        }
-
-        /*
-         * With the batch data retrievable in the global table, run
-         * javadoc to continue the rest of the batch's compliation as
-         * a doclet.
-         */
-        boolean status;
-        try {
-            batchTable.put(batchID, batch);
-            status = invokeJavadoc(batch, batchID);
-        } finally {
-            batchTable.remove(batchID);
-        }
-
-        if (batch.verbose) {
-            long deltaTime = System.currentTimeMillis() - startTime;
-            output(Resources.getText("rmic.done_in",
-                                     Long.toString(deltaTime)));
-        }
-
-        return status;
-    }
-
-    /**
-     * Prints the specified string to the output stream of this Main
-     * instance.
-     **/
-    public void output(String msg) {
-        out.println(msg);
-    }
-
-    /**
-     * Prints an error message to the output stream of this Main
-     * instance.  The first argument is used as a key in rmic's
-     * resource bundle, and the rest of the arguments are used as
-     * arguments in the formatting of the resource string.
-     **/
-    public void error(String msg, String... args) {
-        output(Resources.getText(msg, args));
-    }
-
-    /**
-     * Prints rmic's usage message to the output stream of this Main
-     * instance.
-     *
-     * This method is public so that it can be used by the "parseArgs"
-     * methods of Generator implementations.
-     **/
-    public void usage() {
-        error("rmic.usage", program);
-    }
-
-    /**
-     * Processes rmic command line arguments.  Returns a Batch object
-     * representing the command line arguments if successful, or null
-     * if an error occurred.  Processed elements of the args array are
-     * set to null.
-     **/
-    private Batch parseArgs(String[] args) {
-        Batch batch = new Batch();
-
-        /*
-         * Pre-process command line for @file arguments.
-         */
-        try {
-            args = CommandLine.parse(args);
-        } catch (FileNotFoundException e) {
-            error("rmic.cant.read", e.getMessage());
-            return null;
-        } catch (IOException e) {
-            e.printStackTrace(out);
-            return null;
-        }
-
-        for (int i = 0; i < args.length; i++) {
-
-            if (args[i] == null) {
-                // already processed by a generator
-                continue;
-
-            } else if (args[i].equals("-Xnew")) {
-                // we're already using the "new" implementation
-                args[i] = null;
-
-            } else if (args[i].equals("-show")) {
-                // obselete: fail
-                error("rmic.option.unsupported", args[i]);
-                usage();
-                return null;
-
-            } else if (args[i].equals("-O")) {
-                // obselete: warn but tolerate
-                error("rmic.option.unsupported", args[i]);
-                args[i] = null;
-
-            } else if (args[i].equals("-debug")) {
-                // obselete: warn but tolerate
-                error("rmic.option.unsupported", args[i]);
-                args[i] = null;
-
-            } else if (args[i].equals("-depend")) {
-                // obselete: warn but tolerate
-                // REMIND: should this fail instead?
-                error("rmic.option.unsupported", args[i]);
-                args[i] = null;
-
-            } else if (args[i].equals("-keep") ||
-                       args[i].equals("-keepgenerated"))
-            {
-                batch.keepGenerated = true;
-                args[i] = null;
-
-            } else if (args[i].equals("-g")) {
-                batch.debug = true;
-                args[i] = null;
-
-            } else if (args[i].equals("-nowarn")) {
-                batch.noWarn = true;
-                args[i] = null;
-
-            } else if (args[i].equals("-nowrite")) {
-                batch.noWrite = true;
-                args[i] = null;
-
-            } else if (args[i].equals("-verbose")) {
-                batch.verbose = true;
-                args[i] = null;
-
-            } else if (args[i].equals("-Xnocompile")) {
-                batch.noCompile = true;
-                batch.keepGenerated = true;
-                args[i] = null;
-
-            } else if (args[i].equals("-bootclasspath")) {
-                if ((i + 1) >= args.length) {
-                    error("rmic.option.requires.argument", args[i]);
-                    usage();
-                    return null;
-                }
-                if (batch.bootClassPath != null) {
-                    error("rmic.option.already.seen", args[i]);
-                    usage();
-                    return null;
-                }
-                args[i] = null;
-                batch.bootClassPath = args[++i];
-                assert batch.bootClassPath != null;
-                args[i] = null;
-
-            } else if (args[i].equals("-extdirs")) {
-                if ((i + 1) >= args.length) {
-                    error("rmic.option.requires.argument", args[i]);
-                    usage();
-                    return null;
-                }
-                if (batch.extDirs != null) {
-                    error("rmic.option.already.seen", args[i]);
-                    usage();
-                    return null;
-                }
-                args[i] = null;
-                batch.extDirs = args[++i];
-                assert batch.extDirs != null;
-                args[i] = null;
-
-            } else if (args[i].equals("-classpath")) {
-                if ((i + 1) >= args.length) {
-                    error("rmic.option.requires.argument", args[i]);
-                    usage();
-                    return null;
-                }
-                if (batch.classPath != null) {
-                    error("rmic.option.already.seen", args[i]);
-                    usage();
-                    return null;
-                }
-                args[i] = null;
-                batch.classPath = args[++i];
-                assert batch.classPath != null;
-                args[i] = null;
-
-            } else if (args[i].equals("-d")) {
-                if ((i + 1) >= args.length) {
-                    error("rmic.option.requires.argument", args[i]);
-                    usage();
-                    return null;
-                }
-                if (batch.destDir != null) {
-                    error("rmic.option.already.seen", args[i]);
-                    usage();
-                    return null;
-                }
-                args[i] = null;
-                batch.destDir = new File(args[++i]);
-                assert batch.destDir != null;
-                args[i] = null;
-                if (!batch.destDir.exists()) {
-                    error("rmic.no.such.directory", batch.destDir.getPath());
-                    usage();
-                    return null;
-                }
-
-            } else if (args[i].equals("-v1.1") ||
-                       args[i].equals("-vcompat") ||
-                       args[i].equals("-v1.2"))
-            {
-                Generator gen = new JrmpGenerator();
-                batch.generators.add(gen);
-                // JrmpGenerator only requires base BatchEnvironment class
-                if (!gen.parseArgs(args, this)) {
-                    return null;
-                }
-
-            } else if (args[i].equalsIgnoreCase("-iiop")) {
-                error("rmic.option.unimplemented", args[i]);
-                return null;
-
-                // Generator gen = new IiopGenerator();
-                // batch.generators.add(gen);
-                // if (!batch.envClass.isAssignableFrom(gen.envClass())) {
-                //   error("rmic.cannot.use.both",
-                //         batch.envClass.getName(), gen.envClass().getName());
-                //   return null;
-                // }
-                // batch.envClass = gen.envClass();
-                // if (!gen.parseArgs(args, this)) {
-                //   return null;
-                // }
-
-            } else if (args[i].equalsIgnoreCase("-idl")) {
-                error("rmic.option.unimplemented", args[i]);
-                return null;
-
-                // see implementation sketch above
-
-            } else if (args[i].equalsIgnoreCase("-xprint")) {
-                error("rmic.option.unimplemented", args[i]);
-                return null;
-
-                // see implementation sketch above
-            }
-        }
-
-        /*
-         * At this point, all that remains non-null in the args
-         * array are input class names or illegal options.
-         */
-        for (int i = 0; i < args.length; i++) {
-            if (args[i] != null) {
-                if (args[i].startsWith("-")) {
-                    error("rmic.no.such.option", args[i]);
-                    usage();
-                    return null;
-                } else {
-                    batch.classes.add(args[i]);
-                }
-            }
-        }
-        if (batch.classes.isEmpty()) {
-            usage();
-            return null;
-        }
-
-        /*
-         * If options did not specify at least one protocol-specific
-         * generator, then JRMP is the default.
-         */
-        if (batch.generators.isEmpty()) {
-            batch.generators.add(new JrmpGenerator());
-        }
-        return batch;
-    }
-
-    /**
-     * Doclet class entry point.
-     **/
-    public static boolean start(RootDoc rootDoc) {
-
-        /*
-         * Find batch ID among javadoc options, and retrieve
-         * corresponding batch data from global table.
-         */
-        long batchID = -1;
-        for (String[] option : rootDoc.options()) {
-            if (option[0].equals("-batchID")) {
-                try {
-                    batchID = Long.parseLong(option[1]);
-                } catch (NumberFormatException e) {
-                    throw new AssertionError(e);
-                }
-            }
-        }
-        Batch batch = batchTable.get(batchID);
-        assert batch != null;
-
-        /*
-         * Construct batch environment using class agreed upon by
-         * generator implementations.
-         */
-        BatchEnvironment env;
-        try {
-            Constructor<? extends BatchEnvironment> cons =
-                batch.envClass.getConstructor(new Class<?>[] { RootDoc.class });
-            env = cons.newInstance(rootDoc);
-        } catch (NoSuchMethodException e) {
-            throw new AssertionError(e);
-        } catch (IllegalAccessException e) {
-            throw new AssertionError(e);
-        } catch (InstantiationException e) {
-            throw new AssertionError(e);
-        } catch (InvocationTargetException e) {
-            throw new AssertionError(e);
-        }
-
-        env.setVerbose(batch.verbose);
-
-        /*
-         * Determine the destination directory (the top of the package
-         * hierarchy) for the output of this batch; if no destination
-         * directory was specified on the command line, then the
-         * default is the current working directory.
-         */
-        File destDir = batch.destDir;
-        if (destDir == null) {
-            destDir = new File(System.getProperty("user.dir"));
-        }
-
-        /*
-         * Run each input class through each generator.
-         */
-        for (String inputClassName : batch.classes) {
-            ClassDoc inputClass = rootDoc.classNamed(inputClassName);
-            try {
-                for (Generator gen : batch.generators) {
-                    gen.generate(env, inputClass, destDir);
-                }
-            } catch (NullPointerException e) {
-                /*
-                 * We assume that this means that some class that was
-                 * needed (perhaps even a bootstrap class) was not
-                 * found, and that javadoc has already reported this
-                 * as an error.  There is nothing for us to do here
-                 * but try to continue with the next input class.
-                 *
-                 * REMIND: More explicit error checking throughout
-                 * would be preferable, however.
-                 */
-            }
-        }
-
-        /*
-         * Compile any generated source files, if configured to do so.
-         */
-        boolean status = true;
-        List<File> generatedFiles = env.generatedFiles();
-        if (!batch.noCompile && !batch.noWrite && !generatedFiles.isEmpty()) {
-            status = batch.enclosingMain().invokeJavac(batch, generatedFiles);
-        }
-
-        /*
-         * Delete any generated source files, if configured to do so.
-         */
-        if (!batch.keepGenerated) {
-            for (File file : generatedFiles) {
-                file.delete();
-            }
-        }
-
-        return status;
-    }
-
-    /**
-     * Doclet class method that indicates that this doclet class
-     * recognizes (only) the "-batchID" option on the javadoc command
-     * line, and that the "-batchID" option comprises two arguments on
-     * the javadoc command line.
-     **/
-    public static int optionLength(String option) {
-        if (option.equals("-batchID")) {
-            return 2;
-        } else {
-            return 0;
-        }
-    }
-
-    /**
-     * Runs the javadoc tool to invoke this class as a doclet, passing
-     * command line options derived from the specified batch data and
-     * indicating the specified batch ID.
-     *
-     * NOTE: This method currently uses a J2SE-internal API to run
-     * javadoc.  If and when there is a J2SE API for invoking SDK
-     * tools, this method should be updated to use that API instead.
-     **/
-    private boolean invokeJavadoc(Batch batch, long batchID) {
-        List<String> javadocArgs = new ArrayList<String>();
-
-        // include all types, regardless of language-level access
-        javadocArgs.add("-private");
-
-        // inputs are class names, not source files
-        javadocArgs.add("-Xclasses");
-
-        // reproduce relevant options from rmic invocation
-        if (batch.verbose) {
-            javadocArgs.add("-verbose");
-        }
-        if (batch.bootClassPath != null) {
-            javadocArgs.add("-bootclasspath");
-            javadocArgs.add(batch.bootClassPath);
-        }
-        if (batch.extDirs != null) {
-            javadocArgs.add("-extdirs");
-            javadocArgs.add(batch.extDirs);
-        }
-        if (batch.classPath != null) {
-            javadocArgs.add("-classpath");
-            javadocArgs.add(batch.classPath);
-        }
-
-        // specify batch ID
-        javadocArgs.add("-batchID");
-        javadocArgs.add(Long.toString(batchID));
-
-        /*
-         * Run javadoc on union of rmic input classes and all
-         * generators' bootstrap classes, so that they will all be
-         * available to the doclet code.
-         */
-        Set<String> classNames = new HashSet<String>();
-        for (Generator gen : batch.generators) {
-            classNames.addAll(gen.bootstrapClassNames());
-        }
-        classNames.addAll(batch.classes);
-        for (String s : classNames) {
-            javadocArgs.add(s);
-        }
-
-        // run javadoc with our program name and output stream
-        int status = com.sun.tools.javadoc.Main.execute(
-            program,
-            new PrintWriter(out, true),
-            new PrintWriter(out, true),
-            new PrintWriter(out, true),
-            this.getClass().getName(),          // doclet class is this class
-            javadocArgs.toArray(new String[javadocArgs.size()]));
-        return status == 0;
-    }
-
-    /**
-     * Runs the javac tool to compile the specified source files,
-     * passing command line options derived from the specified batch
-     * data.
-     *
-     * NOTE: This method currently uses a J2SE-internal API to run
-     * javac.  If and when there is a J2SE API for invoking SDK tools,
-     * this method should be updated to use that API instead.
-     **/
-    private boolean invokeJavac(Batch batch, List<File> files) {
-        List<String> javacArgs = new ArrayList<String>();
-
-        // rmic never wants to display javac warnings
-        javacArgs.add("-nowarn");
-
-        // reproduce relevant options from rmic invocation
-        if (batch.debug) {
-            javacArgs.add("-g");
-        }
-        if (batch.verbose) {
-            javacArgs.add("-verbose");
-        }
-        if (batch.bootClassPath != null) {
-            javacArgs.add("-bootclasspath");
-            javacArgs.add(batch.bootClassPath);
-        }
-        if (batch.extDirs != null) {
-            javacArgs.add("-extdirs");
-            javacArgs.add(batch.extDirs);
-        }
-        if (batch.classPath != null) {
-            javacArgs.add("-classpath");
-            javacArgs.add(batch.classPath);
-        }
-
-        /*
-         * For now, rmic still always produces class files that have a
-         * class file format version compatible with JDK 1.1.
-         */
-        javacArgs.add("-source");
-        javacArgs.add("1.3");
-        javacArgs.add("-target");
-        javacArgs.add("1.1");
-
-        // add source files to compile
-        for (File file : files) {
-            javacArgs.add(file.getPath());
-        }
-
-        // run javac with our output stream
-        int status = com.sun.tools.javac.Main.compile(
-            javacArgs.toArray(new String[javacArgs.size()]),
-            new PrintWriter(out, true));
-        return status == 0;
-    }
-
-    /**
-     * The data for an rmic compliation batch: the processed command
-     * line arguments.
-     **/
-    private class Batch {
-        boolean keepGenerated = false;  // -keep or -keepgenerated
-        boolean debug = false;          // -g
-        boolean noWarn = false;         // -nowarn
-        boolean noWrite = false;        // -nowrite
-        boolean verbose = false;        // -verbose
-        boolean noCompile = false;      // -Xnocompile
-        String bootClassPath = null;    // -bootclasspath
-        String extDirs = null;          // -extdirs
-        String classPath = null;        // -classpath
-        File destDir = null;            // -d
-        List<Generator> generators = new ArrayList<Generator>();
-        Class<? extends BatchEnvironment> envClass = BatchEnvironment.class;
-        List<String> classes = new ArrayList<String>();
-
-        Batch() { }
-
-        /**
-         * Returns the Main instance for this batch.
-         **/
-        Main enclosingMain() {
-            return Main.this;
-        }
-    }
-}
--- a/src/jdk.rmic/share/classes/sun/rmi/rmic/newrmic/Resources.java	Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,95 +0,0 @@
-/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.rmi.rmic.newrmic;
-
-import java.text.MessageFormat;
-import java.util.MissingResourceException;
-import java.util.ResourceBundle;
-
-/**
- * Provides resource support for rmic.
- *
- * WARNING: The contents of this source file are not part of any
- * supported API.  Code that depends on them does so at its own risk:
- * they are subject to change or removal without notice.
- *
- * @author Peter Jones
- **/
-public final class Resources {
-
-    private static ResourceBundle resources = null;
-    private static ResourceBundle resourcesExt = null;
-    static {
-        try {
-            resources =
-                ResourceBundle.getBundle("sun.rmi.rmic.resources.rmic");
-        } catch (MissingResourceException e) {
-            // gracefully handle this later
-        }
-        try {
-            resourcesExt =
-                ResourceBundle.getBundle("sun.rmi.rmic.resources.rmicext");
-        } catch (MissingResourceException e) {
-            // OK if this isn't found
-        }
-    }
-
-    private Resources() { throw new AssertionError(); }
-
-    /**
-     * Returns the text of the rmic resource for the specified key
-     * formatted with the specified arguments.
-     **/
-    public static String getText(String key, String... args) {
-        String format = getString(key);
-        if (format == null) {
-            format = "missing resource key: key = \"" + key + "\", " +
-                "arguments = \"{0}\", \"{1}\", \"{2}\"";
-        }
-        return MessageFormat.format(format, (Object[]) args);
-    }
-
-    /**
-     * Returns the rmic resource string for the specified key.
-     **/
-    private static String getString(String key) {
-        if (resourcesExt != null) {
-            try {
-                return resourcesExt.getString(key);
-            } catch (MissingResourceException e) {
-            }
-        }
-        if (resources != null) {
-            try {
-                return resources.getString(key);
-            } catch (MissingResourceException e) {
-                return null;
-            }
-        }
-        return "missing resource bundle: key = \"" + key + "\", " +
-            "arguments = \"{0}\", \"{1}\", \"{2}\"";
-    }
-}
--- a/src/jdk.rmic/share/classes/sun/rmi/rmic/newrmic/jrmp/Constants.java	Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.rmi.rmic.newrmic.jrmp;
-
-/**
- * Constants specific to the JRMP rmic generator.
- *
- * WARNING: The contents of this source file are not part of any
- * supported API.  Code that depends on them does so at its own risk:
- * they are subject to change or removal without notice.
- *
- * @author Peter Jones
- **/
-final class Constants {
-
-    private Constants() { throw new AssertionError(); }
-
-    /*
-     * fully-qualified names of types used by rmic
-     */
-    static final String REMOTE_OBJECT = "java.rmi.server.RemoteObject";
-    static final String REMOTE_STUB = "java.rmi.server.RemoteStub";
-    static final String REMOTE_REF = "java.rmi.server.RemoteRef";
-    static final String OPERATION = "java.rmi.server.Operation";
-    static final String SKELETON = "java.rmi.server.Skeleton";
-    static final String SKELETON_MISMATCH_EXCEPTION =
-        "java.rmi.server.SkeletonMismatchException";
-    static final String REMOTE_CALL = "java.rmi.server.RemoteCall";
-    static final String MARSHAL_EXCEPTION = "java.rmi.MarshalException";
-    static final String UNMARSHAL_EXCEPTION = "java.rmi.UnmarshalException";
-    static final String UNEXPECTED_EXCEPTION = "java.rmi.UnexpectedException";
-
-    /*
-     * stub protocol versions
-     */
-    enum StubVersion { V1_1, VCOMPAT, V1_2 };
-
-    /*
-     * serialVersionUID for all stubs that can use 1.2 protocol
-     */
-    static final long STUB_SERIAL_VERSION_UID = 2;
-
-    /*
-     * version number used to seed interface hash computation
-     */
-    static final int INTERFACE_HASH_STUB_VERSION = 1;
-}
--- a/src/jdk.rmic/share/classes/sun/rmi/rmic/newrmic/jrmp/JrmpGenerator.java	Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,226 +0,0 @@
-/*
- * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.rmi.rmic.newrmic.jrmp;
-
-import com.sun.javadoc.ClassDoc;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStreamWriter;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import sun.rmi.rmic.newrmic.BatchEnvironment;
-import sun.rmi.rmic.newrmic.Generator;
-import sun.rmi.rmic.newrmic.IndentingWriter;
-import sun.rmi.rmic.newrmic.Main;
-import sun.rmi.rmic.newrmic.Resources;
-
-import static sun.rmi.rmic.newrmic.jrmp.Constants.*;
-
-/**
- * JRMP rmic back end; generates source code for JRMP stub and
- * skeleton classes.
- *
- * WARNING: The contents of this source file are not part of any
- * supported API.  Code that depends on them does so at its own risk:
- * they are subject to change or removal without notice.
- *
- * @author Peter Jones
- **/
-public class JrmpGenerator implements Generator {
-
-    private static final Map<String,StubVersion> versionOptions =
-        new HashMap<String,StubVersion>();
-    static {
-        versionOptions.put("-v1.1", StubVersion.V1_1);
-        versionOptions.put("-vcompat", StubVersion.VCOMPAT);
-        versionOptions.put("-v1.2", StubVersion.V1_2);
-    }
-
-    private static final Set<String> bootstrapClassNames =
-        new HashSet<String>();
-    static {
-        bootstrapClassNames.add("java.lang.Exception");
-        bootstrapClassNames.add("java.rmi.Remote");
-        bootstrapClassNames.add("java.rmi.RemoteException");
-        bootstrapClassNames.add("java.lang.RuntimeException");
-    };
-
-    /** version of the JRMP stub protocol to generate code for */
-    private StubVersion version = StubVersion.V1_2;     // default is -v1.2
-
-    /**
-     * Creates a new JrmpGenerator.
-     **/
-    public JrmpGenerator() { }
-
-    /**
-     * The JRMP generator recognizes command line options for
-     * selecting the JRMP stub protocol version to generate classes
-     * for.  Only one such option is allowed.
-     **/
-    public boolean parseArgs(String[] args, Main main) {
-        String explicitVersion = null;
-        for (int i = 0; i < args.length; i++) {
-            String arg = args[i];
-            if (versionOptions.containsKey(arg)) {
-                if (explicitVersion != null && !explicitVersion.equals(arg)) {
-                    main.error("rmic.cannot.use.both", explicitVersion, arg);
-                    return false;
-                }
-                explicitVersion = arg;
-                version = versionOptions.get(arg);
-                args[i] = null;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * The JRMP generator does not require an environment class more
-     * specific than BatchEnvironment.
-     **/
-    public Class<? extends BatchEnvironment> envClass() {
-        return BatchEnvironment.class;
-    }
-
-    public Set<String> bootstrapClassNames() {
-        return Collections.unmodifiableSet(bootstrapClassNames);
-    }
-
-    /**
-     * Generates the source file(s) for the JRMP stub class and
-     * (optionally) skeleton class for the specified remote
-     * implementation class.
-     **/
-    public void generate(BatchEnvironment env,
-                         ClassDoc inputClass,
-                         File destDir)
-    {
-        RemoteClass remoteClass = RemoteClass.forClass(env, inputClass);
-        if (remoteClass == null) {
-            return;     // an error must have occurred
-        }
-
-        StubSkeletonWriter writer =
-            new StubSkeletonWriter(env, remoteClass, version);
-
-        File stubFile = sourceFileForClass(writer.stubClassName(), destDir);
-        try {
-            IndentingWriter out = new IndentingWriter(
-                new OutputStreamWriter(new FileOutputStream(stubFile)));
-            writer.writeStub(out);
-            out.close();
-            if (env.verbose()) {
-                env.output(Resources.getText("rmic.wrote",
-                                             stubFile.getPath()));
-            }
-            env.addGeneratedFile(stubFile);
-        } catch (IOException e) {
-            env.error("rmic.cant.write", stubFile.toString());
-            return;
-        }
-
-        File skeletonFile =
-            sourceFileForClass(writer.skeletonClassName(), destDir);
-        if (version == StubVersion.V1_1 ||
-            version == StubVersion.VCOMPAT)
-        {
-            try {
-                IndentingWriter out = new IndentingWriter(
-                    new OutputStreamWriter(
-                        new FileOutputStream(skeletonFile)));
-                writer.writeSkeleton(out);
-                out.close();
-                if (env.verbose()) {
-                    env.output(Resources.getText("rmic.wrote",
-                                                 skeletonFile.getPath()));
-                }
-                env.addGeneratedFile(skeletonFile);
-            } catch (IOException e) {
-                env.error("rmic.cant.write", skeletonFile.toString());
-                return;
-            }
-        } else {
-            /*
-             * If skeleton files are not being generated for this run,
-             * delete old skeleton source or class files for this
-             * remote implementation class that were (presumably) left
-             * over from previous runs, to avoid user confusion from
-             * extraneous or inconsistent generated files.
-             */
-            File skeletonClassFile =
-                classFileForClass(writer.skeletonClassName(), destDir);
-
-            skeletonFile.delete();      // ignore failures (no big deal)
-            skeletonClassFile.delete();
-        }
-    }
-
-
-    /**
-     * Returns the File object to be used as the source file for a
-     * class with the specified binary name, with the specified
-     * destination directory as the top of the package hierarchy.
-     **/
-    private File sourceFileForClass(String binaryName, File destDir) {
-        return fileForClass(binaryName, destDir, ".java");
-    }
-
-    /**
-     * Returns the File object to be used as the class file for a
-     * class with the specified binary name, with the supplied
-     * destination directory as the top of the package hierarchy.
-     **/
-    private File classFileForClass(String binaryName, File destDir) {
-        return fileForClass(binaryName, destDir, ".class");
-    }
-
-    private File fileForClass(String binaryName, File destDir, String ext) {
-        int i = binaryName.lastIndexOf('.');
-        String classFileName = binaryName.substring(i + 1) + ext;
-        if (i != -1) {
-            String packageName = binaryName.substring(0, i);
-            String packagePath = packageName.replace('.', File.separatorChar);
-            File packageDir = new File(destDir, packagePath);
-            /*
-             * Make sure that the directory for this package exists.
-             * We assume that the caller has verified that the top-
-             * level destination directory exists, so we need not
-             * worry about creating it unintentionally.
-             */
-            if (!packageDir.exists()) {
-                packageDir.mkdirs();
-            }
-            return new File(packageDir, classFileName);
-        } else {
-            return new File(destDir, classFileName);
-        }
-    }
-}
--- a/src/jdk.rmic/share/classes/sun/rmi/rmic/newrmic/jrmp/RemoteClass.java	Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,710 +0,0 @@
-/*
- * Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.rmi.rmic.newrmic.jrmp;
-
-import com.sun.javadoc.ClassDoc;
-import com.sun.javadoc.MethodDoc;
-import com.sun.javadoc.Parameter;
-import com.sun.javadoc.Type;
-import java.io.IOException;
-import java.io.ByteArrayOutputStream;
-import java.io.DataOutputStream;
-import java.security.MessageDigest;
-import java.security.DigestOutputStream;
-import java.security.NoSuchAlgorithmException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.List;
-import java.util.HashMap;
-import java.util.Map;
-import sun.rmi.rmic.newrmic.BatchEnvironment;
-
-import static sun.rmi.rmic.newrmic.Constants.*;
-import static sun.rmi.rmic.newrmic.jrmp.Constants.*;
-
-/**
- * Encapsulates RMI-specific information about a remote implementation
- * class (a class that implements one or more remote interfaces).
- *
- * WARNING: The contents of this source file are not part of any
- * supported API.  Code that depends on them does so at its own risk:
- * they are subject to change or removal without notice.
- *
- * @author Peter Jones
- **/
-final class RemoteClass {
-
-    /** rmic environment for this object */
-    private final BatchEnvironment env;
-
-    /** the remote implementation class this object represents */
-    private final ClassDoc implClass;
-
-    /** remote interfaces implemented by this class */
-    private ClassDoc[] remoteInterfaces;
-
-    /** the remote methods of this class */
-    private Method[] remoteMethods;
-
-    /** stub/skeleton "interface hash" for this class */
-    private long interfaceHash;
-
-    /**
-     * Creates a RemoteClass instance that represents the RMI-specific
-     * information about the specified remote implementation class.
-     *
-     * If the class is not a valid remote implementation class or if
-     * some other error occurs, the return value will be null, and
-     * errors will have been reported to the supplied
-     * BatchEnvironment.
-     **/
-    static RemoteClass forClass(BatchEnvironment env, ClassDoc implClass) {
-        RemoteClass remoteClass = new RemoteClass(env, implClass);
-        if (remoteClass.init()) {
-            return remoteClass;
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * Creates a RemoteClass instance for the specified class.  The
-     * resulting object is not yet initialized.
-     **/
-    private RemoteClass(BatchEnvironment env, ClassDoc implClass) {
-        this.env = env;
-        this.implClass = implClass;
-    }
-
-    /**
-     * Returns the ClassDoc for this remote implementation class.
-     **/
-    ClassDoc classDoc() {
-        return implClass;
-    }
-
-    /**
-     * Returns the remote interfaces implemented by this remote
-     * implementation class.
-     *
-     * A remote interface is an interface that is a subinterface of
-     * java.rmi.Remote.  The remote interfaces of a class are the
-     * direct superinterfaces of the class and all of its superclasses
-     * that are remote interfaces.
-     *
-     * The order of the array returned is arbitrary, and some elements
-     * may be superfluous (i.e., superinterfaces of other interfaces
-     * in the array).
-     **/
-    ClassDoc[] remoteInterfaces() {
-        return remoteInterfaces.clone();
-    }
-
-    /**
-     * Returns an array of RemoteClass.Method objects representing all
-     * of the remote methods of this remote implementation class (all
-     * of the member methods of the class's remote interfaces).
-     *
-     * The methods in the array are ordered according to a comparison
-     * of strings consisting of their name followed by their
-     * descriptor, so each method's index in the array corresponds to
-     * its "operation number" in the JDK 1.1 version of the JRMP
-     * stub/skeleton protocol.
-     **/
-    Method[] remoteMethods() {
-        return remoteMethods.clone();
-    }
-
-    /**
-     * Returns the "interface hash" used to match a stub/skeleton pair
-     * for this remote implementation class in the JDK 1.1 version of
-     * the JRMP stub/skeleton protocol.
-     **/
-    long interfaceHash() {
-        return interfaceHash;
-    }
-
-    /**
-     * Validates this remote implementation class and computes the
-     * RMI-specific information.  Returns true if successful, or false
-     * if an error occurred.
-     **/
-    private boolean init() {
-        /*
-         * Verify that it is really a class, not an interface.
-         */
-        if (implClass.isInterface()) {
-            env.error("rmic.cant.make.stubs.for.interface",
-                      implClass.qualifiedName());
-            return false;
-        }
-
-        /*
-         * Find all of the remote interfaces of our remote
-         * implementation class-- for each class up the superclass
-         * chain, add each directly-implemented interface that somehow
-         * extends Remote to a list.
-         */
-        List<ClassDoc> remotesImplemented = new ArrayList<ClassDoc>();
-        for (ClassDoc cl = implClass; cl != null; cl = cl.superclass()) {
-            for (ClassDoc intf : cl.interfaces()) {
-                /*
-                 * Add interface to the list if it extends Remote and
-                 * it is not already there.
-                 */
-                if (!remotesImplemented.contains(intf) &&
-                    intf.subclassOf(env.docRemote()))
-                {
-                    remotesImplemented.add(intf);
-                    if (env.verbose()) {
-                        env.output("[found remote interface: " +
-                                   intf.qualifiedName() + "]");
-                    }
-                }
-            }
-
-            /*
-             * Verify that the candidate remote implementation class
-             * implements at least one remote interface directly.
-             */
-            if (cl == implClass && remotesImplemented.isEmpty()) {
-                if (implClass.subclassOf(env.docRemote())) {
-                    /*
-                     * This error message is used if the class does
-                     * implement a remote interface through one of its
-                     * superclasses, but not directly.
-                     */
-                    env.error("rmic.must.implement.remote.directly",
-                              implClass.qualifiedName());
-                } else {
-                    /*
-                     * This error message is used if the class does
-                     * not implement a remote interface at all.
-                     */
-                    env.error("rmic.must.implement.remote",
-                              implClass.qualifiedName());
-                }
-                return false;
-            }
-        }
-
-        /*
-         * Convert list of remote interfaces to an array
-         * (order is not important for this array).
-         */
-        remoteInterfaces =
-            remotesImplemented.toArray(
-                new ClassDoc[remotesImplemented.size()]);
-
-        /*
-         * Collect the methods from all of the remote interfaces into
-         * a table, which maps from method name-and-descriptor string
-         * to Method object.
-         */
-        Map<String,Method> methods = new HashMap<String,Method>();
-        boolean errors = false;
-        for (ClassDoc intf : remotesImplemented) {
-            if (!collectRemoteMethods(intf, methods)) {
-                /*
-                 * Continue iterating despite errors in order to
-                 * generate more complete error report.
-                 */
-                errors = true;
-            }
-        }
-        if (errors) {
-            return false;
-        }
-
-        /*
-         * Sort table of remote methods into an array.  The elements
-         * are sorted in ascending order of the string of the method's
-         * name and descriptor, so that each elements index is equal
-         * to its operation number in the JDK 1.1 version of the JRMP
-         * stub/skeleton protocol.
-         */
-        String[] orderedKeys =
-            methods.keySet().toArray(new String[methods.size()]);
-        Arrays.sort(orderedKeys);
-        remoteMethods = new Method[methods.size()];
-        for (int i = 0; i < remoteMethods.length; i++) {
-            remoteMethods[i] = methods.get(orderedKeys[i]);
-            if (env.verbose()) {
-                String msg = "[found remote method <" + i + ">: " +
-                    remoteMethods[i].operationString();
-                ClassDoc[] exceptions = remoteMethods[i].exceptionTypes();
-                if (exceptions.length > 0) {
-                    msg += " throws ";
-                    for (int j = 0; j < exceptions.length; j++) {
-                        if (j > 0) {
-                            msg += ", ";
-                        }
-                        msg +=  exceptions[j].qualifiedName();
-                    }
-                }
-                msg += "\n\tname and descriptor = \"" +
-                    remoteMethods[i].nameAndDescriptor();
-                msg += "\n\tmethod hash = " +
-                    remoteMethods[i].methodHash() + "]";
-                env.output(msg);
-            }
-        }
-
-        /*
-         * Finally, pre-compute the interface hash to be used by
-         * stubs/skeletons for this remote class in the JDK 1.1
-         * version of the JRMP stub/skeleton protocol.
-         */
-        interfaceHash = computeInterfaceHash();
-
-        return true;
-    }
-
-    /**
-     * Collects and validates all methods from the specified interface
-     * and all of its superinterfaces as remote methods.  Remote
-     * methods are added to the supplied table.  Returns true if
-     * successful, or false if an error occurred.
-     **/
-    private boolean collectRemoteMethods(ClassDoc intf,
-                                         Map<String,Method> table)
-    {
-        if (!intf.isInterface()) {
-            throw new AssertionError(
-                intf.qualifiedName() + " not an interface");
-        }
-
-        boolean errors = false;
-
-        /*
-         * Search interface's declared methods.
-         */
-    nextMethod:
-        for (MethodDoc method : intf.methods()) {
-
-            /*
-             * Verify that each method throws RemoteException (or a
-             * superclass of RemoteException).
-             */
-            boolean hasRemoteException = false;
-            for (ClassDoc ex : method.thrownExceptions()) {
-                if (env.docRemoteException().subclassOf(ex)) {
-                    hasRemoteException = true;
-                    break;
-                }
-            }
-
-            /*
-             * If this method did not throw RemoteException as required,
-             * generate the error but continue, so that multiple such
-             * errors can be reported.
-             */
-            if (!hasRemoteException) {
-                env.error("rmic.must.throw.remoteexception",
-                          intf.qualifiedName(),
-                          method.name() + method.signature());
-                errors = true;
-                continue nextMethod;
-            }
-
-            /*
-             * Verify that the implementation of this method throws only
-             * java.lang.Exception or its subclasses (fix bugid 4092486).
-             * JRMP does not support remote methods throwing
-             * java.lang.Throwable or other subclasses.
-             */
-            MethodDoc implMethod = findImplMethod(method);
-            if (implMethod != null) {           // should not be null
-                for (ClassDoc ex : implMethod.thrownExceptions()) {
-                    if (!ex.subclassOf(env.docException())) {
-                        env.error("rmic.must.only.throw.exception",
-                                  implMethod.name() + implMethod.signature(),
-                                  ex.qualifiedName());
-                        errors = true;
-                        continue nextMethod;
-                    }
-                }
-            }
-
-            /*
-             * Create RemoteClass.Method object to represent this method
-             * found in a remote interface.
-             */
-            Method newMethod = new Method(method);
-
-            /*
-             * Store remote method's representation in the table of
-             * remote methods found, keyed by its name and descriptor.
-             *
-             * If the table already contains an entry with the same
-             * method name and descriptor, then we must replace the
-             * old entry with a Method object that represents a legal
-             * combination of the old and the new methods;
-             * specifically, the combined method must have a throws
-             * clause that contains (only) all of the checked
-             * exceptions that can be thrown by both the old and the
-             * new method (see bugid 4070653).
-             */
-            String key = newMethod.nameAndDescriptor();
-            Method oldMethod = table.get(key);
-            if (oldMethod != null) {
-                newMethod = newMethod.mergeWith(oldMethod);
-            }
-            table.put(key, newMethod);
-        }
-
-        /*
-         * Recursively collect methods for all superinterfaces.
-         */
-        for (ClassDoc superintf : intf.interfaces()) {
-            if (!collectRemoteMethods(superintf, table)) {
-                errors = true;
-            }
-        }
-
-        return !errors;
-    }
-
-    /**
-     * Returns the MethodDoc for the method of this remote
-     * implementation class that implements the specified remote
-     * method of a remote interface.  Returns null if no matching
-     * method was found in this remote implementation class.
-     **/
-    private MethodDoc findImplMethod(MethodDoc interfaceMethod) {
-        String name = interfaceMethod.name();
-        String desc = Util.methodDescriptorOf(interfaceMethod);
-        for (MethodDoc implMethod : implClass.methods()) {
-            if (name.equals(implMethod.name()) &&
-                desc.equals(Util.methodDescriptorOf(implMethod)))
-            {
-                return implMethod;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Computes the "interface hash" of the stub/skeleton pair for
-     * this remote implementation class.  This is the 64-bit value
-     * used to enforce compatibility between a stub class and a
-     * skeleton class in the JDK 1.1 version of the JRMP stub/skeleton
-     * protocol.
-     *
-     * It is calculated using the first 64 bits of an SHA digest.  The
-     * digest is of a stream consisting of the following data:
-     *     (int) stub version number, always 1
-     *     for each remote method, in order of operation number:
-     *         (UTF-8) method name
-     *         (UTF-8) method descriptor
-     *         for each declared exception, in alphabetical name order:
-     *             (UTF-8) name of exception class
-     * (where "UTF-8" includes a 16-bit length prefix as written by
-     * java.io.DataOutput.writeUTF).
-     **/
-    private long computeInterfaceHash() {
-        long hash = 0;
-        ByteArrayOutputStream sink = new ByteArrayOutputStream(512);
-        try {
-            MessageDigest md = MessageDigest.getInstance("SHA");
-            DataOutputStream out = new DataOutputStream(
-                new DigestOutputStream(sink, md));
-
-            out.writeInt(INTERFACE_HASH_STUB_VERSION);
-
-            for (Method method : remoteMethods) {
-                MethodDoc methodDoc = method.methodDoc();
-
-                out.writeUTF(methodDoc.name());
-                out.writeUTF(Util.methodDescriptorOf(methodDoc));
-                                // descriptors already use binary names
-
-                ClassDoc exceptions[] = methodDoc.thrownExceptions();
-                Arrays.sort(exceptions, new ClassDocComparator());
-                for (ClassDoc ex : exceptions) {
-                    out.writeUTF(Util.binaryNameOf(ex));
-                }
-            }
-            out.flush();
-
-            // use only the first 64 bits of the digest for the hash
-            byte hashArray[] = md.digest();
-            for (int i = 0; i < Math.min(8, hashArray.length); i++) {
-                hash += ((long) (hashArray[i] & 0xFF)) << (i * 8);
-            }
-        } catch (IOException e) {
-            throw new AssertionError(e);
-        } catch (NoSuchAlgorithmException e) {
-            throw new AssertionError(e);
-        }
-
-        return hash;
-    }
-
-    /**
-     * Compares ClassDoc instances according to the lexicographic
-     * order of their binary names.
-     **/
-    private static class ClassDocComparator implements Comparator<ClassDoc> {
-        public int compare(ClassDoc o1, ClassDoc o2) {
-            return Util.binaryNameOf(o1).compareTo(Util.binaryNameOf(o2));
-        }
-    }
-
-    /**
-     * Encapsulates RMI-specific information about a particular remote
-     * method in the remote implementation class represented by the
-     * enclosing RemoteClass.
-     **/
-    final class Method implements Cloneable {
-
-        /**
-         * MethodDoc for this remove method, from one of the remote
-         * interfaces that this method was found in.
-         *
-         * Note that this MethodDoc may be only one of multiple that
-         * correspond to this remote method object, if multiple of
-         * this class's remote interfaces contain methods with the
-         * same name and descriptor.  Therefore, this MethodDoc may
-         * declare more exceptions thrown that this remote method
-         * does.
-         **/
-        private final MethodDoc methodDoc;
-
-        /** java.rmi.server.Operation string for this remote method */
-        private final String operationString;
-
-        /** name and descriptor of this remote method */
-        private final String nameAndDescriptor;
-
-        /** JRMP "method hash" for this remote method */
-        private final long methodHash;
-
-        /**
-         * Exceptions declared to be thrown by this remote method.
-         *
-         * This list may include superfluous entries, such as
-         * unchecked exceptions and subclasses of other entries.
-         **/
-        private ClassDoc[] exceptionTypes;
-
-        /**
-         * Creates a new Method instance for the specified method.
-         **/
-        Method(MethodDoc methodDoc) {
-            this.methodDoc = methodDoc;
-            exceptionTypes = methodDoc.thrownExceptions();
-            /*
-             * Sort exception types to improve consistency with
-             * previous implementations.
-             */
-            Arrays.sort(exceptionTypes, new ClassDocComparator());
-            operationString = computeOperationString();
-            nameAndDescriptor =
-                methodDoc.name() + Util.methodDescriptorOf(methodDoc);
-            methodHash = computeMethodHash();
-        }
-
-        /**
-         * Returns the MethodDoc object corresponding to this method
-         * of a remote interface.
-         **/
-        MethodDoc methodDoc() {
-            return methodDoc;
-        }
-
-        /**
-         * Returns the parameter types declared by this method.
-         **/
-        Type[] parameterTypes() {
-            Parameter[] parameters = methodDoc.parameters();
-            Type[] paramTypes = new Type[parameters.length];
-            for (int i = 0; i < paramTypes.length; i++) {
-                paramTypes[i] = parameters[i].type();
-            }
-            return paramTypes;
-        }
-
-        /**
-         * Returns the exception types declared to be thrown by this
-         * remote method.
-         *
-         * For methods with the same name and descriptor inherited
-         * from multiple remote interfaces, the array will contain the
-         * set of exceptions declared in all of the interfaces'
-         * methods that can be legally thrown by all of them.
-         **/
-        ClassDoc[] exceptionTypes() {
-            return exceptionTypes.clone();
-        }
-
-        /**
-         * Returns the JRMP "method hash" used to identify this remote
-         * method in the JDK 1.2 version of the stub protocol.
-         **/
-        long methodHash() {
-            return methodHash;
-        }
-
-        /**
-         * Returns the string representation of this method
-         * appropriate for the construction of a
-         * java.rmi.server.Operation object.
-         **/
-        String operationString() {
-            return operationString;
-        }
-
-        /**
-         * Returns a string consisting of this method's name followed
-         * by its descriptor.
-         **/
-        String nameAndDescriptor() {
-            return nameAndDescriptor;
-        }
-
-        /**
-         * Returns a new Method object that is a legal combination of
-         * this Method object and another one.
-         *
-         * Doing this requires determining the exceptions declared by
-         * the combined method, which must be (only) all of the
-         * exceptions declared in both old Methods that may thrown in
-         * either of them.
-         **/
-        Method mergeWith(Method other) {
-            if (!nameAndDescriptor().equals(other.nameAndDescriptor())) {
-                throw new AssertionError(
-                    "attempt to merge method \"" +
-                    other.nameAndDescriptor() + "\" with \"" +
-                    nameAndDescriptor());
-            }
-
-            List<ClassDoc> legalExceptions = new ArrayList<ClassDoc>();
-            collectCompatibleExceptions(
-                other.exceptionTypes, exceptionTypes, legalExceptions);
-            collectCompatibleExceptions(
-                exceptionTypes, other.exceptionTypes, legalExceptions);
-
-            Method merged = clone();
-            merged.exceptionTypes =
-                legalExceptions.toArray(new ClassDoc[legalExceptions.size()]);
-
-            return merged;
-        }
-
-        /**
-         * Cloning is supported by returning a shallow copy of this
-         * object.
-         **/
-        protected Method clone() {
-            try {
-                return (Method) super.clone();
-            } catch (CloneNotSupportedException e) {
-                throw new AssertionError(e);
-            }
-        }
-
-        /**
-         * Adds to the supplied list all exceptions in the "froms"
-         * array that are subclasses of an exception in the "withs"
-         * array.
-         **/
-        private void collectCompatibleExceptions(ClassDoc[] froms,
-                                                 ClassDoc[] withs,
-                                                 List<ClassDoc> list)
-        {
-            for (ClassDoc from : froms) {
-                if (!list.contains(from)) {
-                    for (ClassDoc with : withs) {
-                        if (from.subclassOf(with)) {
-                            list.add(from);
-                            break;
-                        }
-                    }
-                }
-            }
-        }
-
-        /**
-         * Computes the JRMP "method hash" of this remote method.  The
-         * method hash is a long containing the first 64 bits of the
-         * SHA digest from the UTF-8 encoded string of the method name
-         * and descriptor.
-         **/
-        private long computeMethodHash() {
-            long hash = 0;
-            ByteArrayOutputStream sink = new ByteArrayOutputStream(512);
-            try {
-                MessageDigest md = MessageDigest.getInstance("SHA");
-                DataOutputStream out = new DataOutputStream(
-                    new DigestOutputStream(sink, md));
-
-                String methodString = nameAndDescriptor();
-                out.writeUTF(methodString);
-
-                // use only the first 64 bits of the digest for the hash
-                out.flush();
-                byte hashArray[] = md.digest();
-                for (int i = 0; i < Math.min(8, hashArray.length); i++) {
-                    hash += ((long) (hashArray[i] & 0xFF)) << (i * 8);
-                }
-            } catch (IOException e) {
-                throw new AssertionError(e);
-            } catch (NoSuchAlgorithmException e) {
-                throw new AssertionError(e);
-            }
-
-            return hash;
-        }
-
-        /**
-         * Computes the string representation of this method
-         * appropriate for the construction of a
-         * java.rmi.server.Operation object.
-         **/
-        private String computeOperationString() {
-            /*
-             * To be consistent with previous implementations, we use
-             * the deprecated style of placing the "[]" for the return
-             * type (if any) after the parameter list.
-             */
-            Type returnType = methodDoc.returnType();
-            String op = returnType.qualifiedTypeName() + " " +
-                methodDoc.name() + "(";
-            Parameter[] parameters = methodDoc.parameters();
-            for (int i = 0; i < parameters.length; i++) {
-                if (i > 0) {
-                    op += ", ";
-                }
-                op += parameters[i].type().toString();
-            }
-            op += ")" + returnType.dimension();
-            return op;
-        }
-    }
-}
--- a/src/jdk.rmic/share/classes/sun/rmi/rmic/newrmic/jrmp/StubSkeletonWriter.java	Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1079 +0,0 @@
-/*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.rmi.rmic.newrmic.jrmp;
-
-import com.sun.javadoc.ClassDoc;
-import com.sun.javadoc.MethodDoc;
-import com.sun.javadoc.Type;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import sun.rmi.rmic.newrmic.BatchEnvironment;
-import sun.rmi.rmic.newrmic.IndentingWriter;
-
-import static sun.rmi.rmic.newrmic.Constants.*;
-import static sun.rmi.rmic.newrmic.jrmp.Constants.*;
-
-/**
- * Writes the source code for the stub class and (optionally) skeleton
- * class for a particular remote implementation class.
- *
- * WARNING: The contents of this source file are not part of any
- * supported API.  Code that depends on them does so at its own risk:
- * they are subject to change or removal without notice.
- *
- * @author Peter Jones
- **/
-class StubSkeletonWriter {
-
-    /** rmic environment for this object */
-    private final BatchEnvironment env;
-
-    /** the remote implementation class to generate code for */
-    private final RemoteClass remoteClass;
-
-    /** version of the JRMP stub protocol to generate code for */
-    private final StubVersion version;
-
-    /*
-     * binary names of the stub and skeleton classes to generate for
-     * the remote class
-     */
-    private final String stubClassName;
-    private final String skeletonClassName;
-
-    /* package name and simple names of the stub and skeleton classes */
-    private final String packageName;
-    private final String stubClassSimpleName;
-    private final String skeletonClassSimpleName;
-
-    /** remote methods of class, indexed by operation number */
-    private final RemoteClass.Method[] remoteMethods;
-
-    /**
-     * Names to use for the java.lang.reflect.Method static fields in
-     * the generated stub class corresponding to each remote method.
-     **/
-    private final String[] methodFieldNames;
-
-    /**
-     * Creates a StubSkeletonWriter instance for the specified remote
-     * implementation class.  The generated code will implement the
-     * specified JRMP stub protocol version.
-     **/
-    StubSkeletonWriter(BatchEnvironment env,
-                       RemoteClass remoteClass,
-                       StubVersion version)
-    {
-        this.env = env;
-        this.remoteClass = remoteClass;
-        this.version = version;
-
-        stubClassName = Util.binaryNameOf(remoteClass.classDoc()) + "_Stub";
-        skeletonClassName =
-            Util.binaryNameOf(remoteClass.classDoc()) + "_Skel";
-
-        int i = stubClassName.lastIndexOf('.');
-        packageName = (i != -1 ? stubClassName.substring(0, i) : "");
-        stubClassSimpleName = stubClassName.substring(i + 1);
-        skeletonClassSimpleName = skeletonClassName.substring(i + 1);
-
-        remoteMethods = remoteClass.remoteMethods();
-        methodFieldNames = nameMethodFields(remoteMethods);
-    }
-
-    /**
-     * Returns the binary name of the stub class to generate for the
-     * remote implementation class.
-     **/
-    String stubClassName() {
-        return stubClassName;
-    }
-
-    /**
-     * Returns the binary name of the skeleton class to generate for
-     * the remote implementation class.
-     **/
-    String skeletonClassName() {
-        return skeletonClassName;
-    }
-
-    /**
-     * Writes the stub class for the remote class to a stream.
-     **/
-    void writeStub(IndentingWriter p) throws IOException {
-
-        /*
-         * Write boiler plate comment.
-         */
-        p.pln("// Stub class generated by rmic, do not edit.");
-        p.pln("// Contents subject to change without notice.");
-        p.pln();
-
-        /*
-         * If remote implementation class was in a particular package,
-         * declare the stub class to be in the same package.
-         */
-        if (!packageName.equals("")) {
-            p.pln("package " + packageName + ";");
-            p.pln();
-        }
-
-        /*
-         * Declare the stub class; implement all remote interfaces.
-         */
-        p.plnI("public final class " + stubClassSimpleName);
-        p.pln("extends " + REMOTE_STUB);
-        ClassDoc[] remoteInterfaces = remoteClass.remoteInterfaces();
-        if (remoteInterfaces.length > 0) {
-            p.p("implements ");
-            for (int i = 0; i < remoteInterfaces.length; i++) {
-                if (i > 0) {
-                    p.p(", ");
-                }
-                p.p(remoteInterfaces[i].qualifiedName());
-            }
-            p.pln();
-        }
-        p.pOlnI("{");
-
-        if (version == StubVersion.V1_1 ||
-            version == StubVersion.VCOMPAT)
-        {
-            writeOperationsArray(p);
-            p.pln();
-            writeInterfaceHash(p);
-            p.pln();
-        }
-
-        if (version == StubVersion.VCOMPAT ||
-            version == StubVersion.V1_2)
-        {
-            p.pln("private static final long serialVersionUID = " +
-                STUB_SERIAL_VERSION_UID + ";");
-            p.pln();
-
-            /*
-             * We only need to declare and initialize the static fields of
-             * Method objects for each remote method if there are any remote
-             * methods; otherwise, skip this code entirely, to avoid generating
-             * a try/catch block for a checked exception that cannot occur
-             * (see bugid 4125181).
-             */
-            if (methodFieldNames.length > 0) {
-                if (version == StubVersion.VCOMPAT) {
-                    p.pln("private static boolean useNewInvoke;");
-                }
-                writeMethodFieldDeclarations(p);
-                p.pln();
-
-                /*
-                 * Initialize java.lang.reflect.Method fields for each remote
-                 * method in a static initializer.
-                 */
-                p.plnI("static {");
-                p.plnI("try {");
-                if (version == StubVersion.VCOMPAT) {
-                    /*
-                     * Fat stubs must determine whether the API required for
-                     * the JDK 1.2 stub protocol is supported in the current
-                     * runtime, so that it can use it if supported.  This is
-                     * determined by using the Reflection API to test if the
-                     * new invoke method on RemoteRef exists, and setting the
-                     * static boolean "useNewInvoke" to true if it does, or
-                     * to false if a NoSuchMethodException is thrown.
-                     */
-                    p.plnI(REMOTE_REF + ".class.getMethod(\"invoke\",");
-                    p.plnI("new java.lang.Class[] {");
-                    p.pln(REMOTE + ".class,");
-                    p.pln("java.lang.reflect.Method.class,");
-                    p.pln("java.lang.Object[].class,");
-                    p.pln("long.class");
-                    p.pOln("});");
-                    p.pO();
-                    p.pln("useNewInvoke = true;");
-                }
-                writeMethodFieldInitializers(p);
-                p.pOlnI("} catch (java.lang.NoSuchMethodException e) {");
-                if (version == StubVersion.VCOMPAT) {
-                    p.pln("useNewInvoke = false;");
-                } else {
-                    p.plnI("throw new java.lang.NoSuchMethodError(");
-                    p.pln("\"stub class initialization failed\");");
-                    p.pO();
-                }
-                p.pOln("}");            // end try/catch block
-                p.pOln("}");            // end static initializer
-                p.pln();
-            }
-        }
-
-        writeStubConstructors(p);
-        p.pln();
-
-        /*
-         * Write each stub method.
-         */
-        if (remoteMethods.length > 0) {
-            p.pln("// methods from remote interfaces");
-            for (int i = 0; i < remoteMethods.length; ++i) {
-                p.pln();
-                writeStubMethod(p, i);
-            }
-        }
-
-        p.pOln("}");                    // end stub class
-    }
-
-    /**
-     * Writes the constructors for the stub class.
-     **/
-    private void writeStubConstructors(IndentingWriter p)
-        throws IOException
-    {
-        p.pln("// constructors");
-
-        /*
-         * Only stubs compatible with the JDK 1.1 stub protocol need
-         * a no-arg constructor; later versions use reflection to find
-         * the constructor that directly takes a RemoteRef argument.
-         */
-        if (version == StubVersion.V1_1 ||
-            version == StubVersion.VCOMPAT)
-        {
-            p.plnI("public " + stubClassSimpleName + "() {");
-            p.pln("super();");
-            p.pOln("}");
-        }
-
-        p.plnI("public " + stubClassSimpleName + "(" + REMOTE_REF + " ref) {");
-        p.pln("super(ref);");
-        p.pOln("}");
-    }
-
-    /**
-     * Writes the stub method for the remote method with the given
-     * operation number.
-     **/
-    private void writeStubMethod(IndentingWriter p, int opnum)
-        throws IOException
-    {
-        RemoteClass.Method method = remoteMethods[opnum];
-        MethodDoc methodDoc = method.methodDoc();
-        String methodName = methodDoc.name();
-        Type[] paramTypes = method.parameterTypes();
-        String paramNames[] = nameParameters(paramTypes);
-        Type returnType = methodDoc.returnType();
-        ClassDoc[] exceptions = method.exceptionTypes();
-
-        /*
-         * Declare stub method; throw exceptions declared in remote
-         * interface(s).
-         */
-        p.pln("// implementation of " +
-              Util.getFriendlyUnqualifiedSignature(methodDoc));
-        p.p("public " + returnType.toString() + " " + methodName + "(");
-        for (int i = 0; i < paramTypes.length; i++) {
-            if (i > 0) {
-                p.p(", ");
-            }
-            p.p(paramTypes[i].toString() + " " + paramNames[i]);
-        }
-        p.plnI(")");
-        if (exceptions.length > 0) {
-            p.p("throws ");
-            for (int i = 0; i < exceptions.length; i++) {
-                if (i > 0) {
-                    p.p(", ");
-                }
-                p.p(exceptions[i].qualifiedName());
-            }
-            p.pln();
-        }
-        p.pOlnI("{");
-
-        /*
-         * The RemoteRef.invoke methods throw Exception, but unless
-         * this stub method throws Exception as well, we must catch
-         * Exceptions thrown from the invocation.  So we must catch
-         * Exception and rethrow something we can throw:
-         * UnexpectedException, which is a subclass of
-         * RemoteException.  But for any subclasses of Exception that
-         * we can throw, like RemoteException, RuntimeException, and
-         * any of the exceptions declared by this stub method, we want
-         * them to pass through unmodified, so first we must catch any
-         * such exceptions and rethrow them directly.
-         *
-         * We have to be careful generating the rethrowing catch
-         * blocks here, because javac will flag an error if there are
-         * any unreachable catch blocks, i.e. if the catch of an
-         * exception class follows a previous catch of it or of one of
-         * its superclasses.  The following method invocation takes
-         * care of these details.
-         */
-        List<ClassDoc> catchList = computeUniqueCatchList(exceptions);
-
-        /*
-         * If we need to catch any particular exceptions (i.e. this method
-         * does not declare java.lang.Exception), put the entire stub
-         * method in a try block.
-         */
-        if (catchList.size() > 0) {
-            p.plnI("try {");
-        }
-
-        if (version == StubVersion.VCOMPAT) {
-            p.plnI("if (useNewInvoke) {");
-        }
-        if (version == StubVersion.VCOMPAT ||
-            version == StubVersion.V1_2)
-        {
-            if (!Util.isVoid(returnType)) {
-                p.p("Object $result = ");               // REMIND: why $?
-            }
-            p.p("ref.invoke(this, " + methodFieldNames[opnum] + ", ");
-            if (paramTypes.length > 0) {
-                p.p("new java.lang.Object[] {");
-                for (int i = 0; i < paramTypes.length; i++) {
-                    if (i > 0)
-                        p.p(", ");
-                    p.p(wrapArgumentCode(paramTypes[i], paramNames[i]));
-                }
-                p.p("}");
-            } else {
-                p.p("null");
-            }
-            p.pln(", " + method.methodHash() + "L);");
-            if (!Util.isVoid(returnType)) {
-                p.pln("return " +
-                    unwrapArgumentCode(returnType, "$result") + ";");
-            }
-        }
-        if (version == StubVersion.VCOMPAT) {
-            p.pOlnI("} else {");
-        }
-        if (version == StubVersion.V1_1 ||
-            version == StubVersion.VCOMPAT)
-        {
-            p.pln(REMOTE_CALL + " call = ref.newCall((" + REMOTE_OBJECT +
-                ") this, operations, " + opnum + ", interfaceHash);");
-
-            if (paramTypes.length > 0) {
-                p.plnI("try {");
-                p.pln("java.io.ObjectOutput out = call.getOutputStream();");
-                writeMarshalArguments(p, "out", paramTypes, paramNames);
-                p.pOlnI("} catch (java.io.IOException e) {");
-                p.pln("throw new " + MARSHAL_EXCEPTION +
-                    "(\"error marshalling arguments\", e);");
-                p.pOln("}");
-            }
-
-            p.pln("ref.invoke(call);");
-
-            if (Util.isVoid(returnType)) {
-                p.pln("ref.done(call);");
-            } else {
-                p.pln(returnType.toString() + " $result;");
-                                                        // REMIND: why $?
-                p.plnI("try {");
-                p.pln("java.io.ObjectInput in = call.getInputStream();");
-                boolean objectRead =
-                    writeUnmarshalArgument(p, "in", returnType, "$result");
-                p.pln(";");
-                p.pOlnI("} catch (java.io.IOException e) {");
-                p.pln("throw new " + UNMARSHAL_EXCEPTION +
-                    "(\"error unmarshalling return\", e);");
-                /*
-                 * If any only if readObject has been invoked, we must catch
-                 * ClassNotFoundException as well as IOException.
-                 */
-                if (objectRead) {
-                    p.pOlnI("} catch (java.lang.ClassNotFoundException e) {");
-                    p.pln("throw new " + UNMARSHAL_EXCEPTION +
-                        "(\"error unmarshalling return\", e);");
-                }
-                p.pOlnI("} finally {");
-                p.pln("ref.done(call);");
-                p.pOln("}");
-                p.pln("return $result;");
-            }
-        }
-        if (version == StubVersion.VCOMPAT) {
-            p.pOln("}");                // end if/else (useNewInvoke) block
-        }
-
-        /*
-         * If we need to catch any particular exceptions, finally write
-         * the catch blocks for them, rethrow any other Exceptions with an
-         * UnexpectedException, and end the try block.
-         */
-        if (catchList.size() > 0) {
-            for (ClassDoc catchClass : catchList) {
-                p.pOlnI("} catch (" + catchClass.qualifiedName() + " e) {");
-                p.pln("throw e;");
-            }
-            p.pOlnI("} catch (java.lang.Exception e) {");
-            p.pln("throw new " + UNEXPECTED_EXCEPTION +
-                "(\"undeclared checked exception\", e);");
-            p.pOln("}");                // end try/catch block
-        }
-
-        p.pOln("}");                    // end stub method
-    }
-
-    /**
-     * Computes the exceptions that need to be caught and rethrown in
-     * a stub method before wrapping Exceptions in
-     * UnexpectedExceptions, given the exceptions declared in the
-     * throws clause of the method.  Returns a list containing the
-     * exception to catch.  Each exception is guaranteed to be unique,
-     * i.e. not a subclass of any of the other exceptions in the list,
-     * so the catch blocks for these exceptions may be generated in
-     * any order relative to each other.
-     *
-     * RemoteException and RuntimeException are each automatically
-     * placed in the returned list (unless any of their superclasses
-     * are already present), since those exceptions should always be
-     * directly rethrown by a stub method.
-     *
-     * The returned list will be empty if java.lang.Exception or one
-     * of its superclasses is in the throws clause of the method,
-     * indicating that no exceptions need to be caught.
-     **/
-    private List<ClassDoc> computeUniqueCatchList(ClassDoc[] exceptions) {
-        List<ClassDoc> uniqueList = new ArrayList<ClassDoc>();
-
-        uniqueList.add(env.docRuntimeException());
-        uniqueList.add(env.docRemoteException()); // always catch/rethrow these
-
-        /* For each exception declared by the stub method's throws clause: */
-    nextException:
-        for (ClassDoc ex : exceptions) {
-            if (env.docException().subclassOf(ex)) {
-                /*
-                 * If java.lang.Exception (or a superclass) was declared
-                 * in the throws clause of this stub method, then we don't
-                 * have to bother catching anything; clear the list and
-                 * return.
-                 */
-                uniqueList.clear();
-                break;
-            } else if (!ex.subclassOf(env.docException())) {
-                /*
-                 * Ignore other Throwables that do not extend Exception,
-                 * because they cannot be thrown by the invoke methods.
-                 */
-                continue;
-            }
-            /*
-             * Compare this exception against the current list of
-             * exceptions that need to be caught:
-             */
-            for (Iterator<ClassDoc> i = uniqueList.iterator(); i.hasNext();) {
-                ClassDoc ex2 = i.next();
-                if (ex.subclassOf(ex2)) {
-                    /*
-                     * If a superclass of this exception is already on
-                     * the list to catch, then ignore this one and continue;
-                     */
-                    continue nextException;
-                } else if (ex2.subclassOf(ex)) {
-                    /*
-                     * If a subclass of this exception is on the list
-                     * to catch, then remove it;
-                     */
-                    i.remove();
-                }
-            }
-            /* This exception is unique: add it to the list to catch. */
-            uniqueList.add(ex);
-        }
-        return uniqueList;
-    }
-
-    /**
-     * Writes the skeleton for the remote class to a stream.
-     **/
-    void writeSkeleton(IndentingWriter p) throws IOException {
-        if (version == StubVersion.V1_2) {
-            throw new AssertionError(
-                "should not generate skeleton for version " + version);
-        }
-
-        /*
-         * Write boiler plate comment.
-         */
-        p.pln("// Skeleton class generated by rmic, do not edit.");
-        p.pln("// Contents subject to change without notice.");
-        p.pln();
-
-        /*
-         * If remote implementation class was in a particular package,
-         * declare the skeleton class to be in the same package.
-         */
-        if (!packageName.equals("")) {
-            p.pln("package " + packageName + ";");
-            p.pln();
-        }
-
-        /*
-         * Declare the skeleton class.
-         */
-        p.plnI("public final class " + skeletonClassSimpleName);
-        p.pln("implements " + SKELETON);
-        p.pOlnI("{");
-
-        writeOperationsArray(p);
-        p.pln();
-
-        writeInterfaceHash(p);
-        p.pln();
-
-        /*
-         * Define the getOperations() method.
-         */
-        p.plnI("public " + OPERATION + "[] getOperations() {");
-        p.pln("return (" + OPERATION + "[]) operations.clone();");
-        p.pOln("}");
-        p.pln();
-
-        /*
-         * Define the dispatch() method.
-         */
-        p.plnI("public void dispatch(" + REMOTE + " obj, " +
-            REMOTE_CALL + " call, int opnum, long hash)");
-        p.pln("throws java.lang.Exception");
-        p.pOlnI("{");
-
-        if (version == StubVersion.VCOMPAT) {
-            p.plnI("if (opnum < 0) {");
-            if (remoteMethods.length > 0) {
-                for (int opnum = 0; opnum < remoteMethods.length; opnum++) {
-                    if (opnum > 0)
-                        p.pO("} else ");
-                    p.plnI("if (hash == " +
-                        remoteMethods[opnum].methodHash() + "L) {");
-                    p.pln("opnum = " + opnum + ";");
-                }
-                p.pOlnI("} else {");
-            }
-            /*
-             * Skeleton throws UnmarshalException if it does not recognize
-             * the method hash; this is what UnicastServerRef.dispatch()
-             * would do.
-             */
-            p.pln("throw new " +
-                UNMARSHAL_EXCEPTION + "(\"invalid method hash\");");
-            if (remoteMethods.length > 0) {
-                p.pOln("}");
-            }
-            /*
-             * Ignore the validation of the interface hash if the
-             * operation number was negative, since it is really a
-             * method hash instead.
-             */
-            p.pOlnI("} else {");
-        }
-
-        p.plnI("if (hash != interfaceHash)");
-        p.pln("throw new " +
-            SKELETON_MISMATCH_EXCEPTION + "(\"interface hash mismatch\");");
-        p.pO();
-
-        if (version == StubVersion.VCOMPAT) {
-            p.pOln("}");                // end if/else (opnum < 0) block
-        }
-        p.pln();
-
-        /*
-         * Cast remote object reference to the remote implementation
-         * class, if it's not private.  We don't use the binary name
-         * of the class like previous implementations did because that
-         * would not compile with javac (since 1.4.1).  If the remote
-         * implementation class is private, then we can't cast to it
-         * like previous implementations did because that also would
-         * not compile with javac-- so instead, we'll have to try to
-         * cast to the remote interface for each remote method.
-         */
-        if (!remoteClass.classDoc().isPrivate()) {
-            p.pln(remoteClass.classDoc().qualifiedName() + " server = (" +
-                  remoteClass.classDoc().qualifiedName() + ") obj;");
-        }
-
-        /*
-         * Process call according to the operation number.
-         */
-        p.plnI("switch (opnum) {");
-        for (int opnum = 0; opnum < remoteMethods.length; opnum++) {
-            writeSkeletonDispatchCase(p, opnum);
-        }
-        p.pOlnI("default:");
-        /*
-         * Skeleton throws UnmarshalException if it does not recognize
-         * the operation number; this is consistent with the case of an
-         * unrecognized method hash.
-         */
-        p.pln("throw new " + UNMARSHAL_EXCEPTION +
-            "(\"invalid method number\");");
-        p.pOln("}");                    // end switch statement
-
-        p.pOln("}");                    // end dispatch() method
-
-        p.pOln("}");                    // end skeleton class
-    }
-
-    /**
-     * Writes the case block for the skeleton's dispatch method for
-     * the remote method with the given "opnum".
-     **/
-    private void writeSkeletonDispatchCase(IndentingWriter p, int opnum)
-        throws IOException
-    {
-        RemoteClass.Method method = remoteMethods[opnum];
-        MethodDoc methodDoc = method.methodDoc();
-        String methodName = methodDoc.name();
-        Type paramTypes[] = method.parameterTypes();
-        String paramNames[] = nameParameters(paramTypes);
-        Type returnType = methodDoc.returnType();
-
-        p.pOlnI("case " + opnum + ": // " +
-            Util.getFriendlyUnqualifiedSignature(methodDoc));
-        /*
-         * Use nested block statement inside case to provide an independent
-         * namespace for local variables used to unmarshal parameters for
-         * this remote method.
-         */
-        p.pOlnI("{");
-
-        if (paramTypes.length > 0) {
-            /*
-             * Declare local variables to hold arguments.
-             */
-            for (int i = 0; i < paramTypes.length; i++) {
-                p.pln(paramTypes[i].toString() + " " + paramNames[i] + ";");
-            }
-
-            /*
-             * Unmarshal arguments from call stream.
-             */
-            p.plnI("try {");
-            p.pln("java.io.ObjectInput in = call.getInputStream();");
-            boolean objectsRead = writeUnmarshalArguments(p, "in",
-                paramTypes, paramNames);
-            p.pOlnI("} catch (java.io.IOException e) {");
-            p.pln("throw new " + UNMARSHAL_EXCEPTION +
-                "(\"error unmarshalling arguments\", e);");
-            /*
-             * If any only if readObject has been invoked, we must catch
-             * ClassNotFoundException as well as IOException.
-             */
-            if (objectsRead) {
-                p.pOlnI("} catch (java.lang.ClassNotFoundException e) {");
-                p.pln("throw new " + UNMARSHAL_EXCEPTION +
-                    "(\"error unmarshalling arguments\", e);");
-            }
-            p.pOlnI("} finally {");
-            p.pln("call.releaseInputStream();");
-            p.pOln("}");
-        } else {
-            p.pln("call.releaseInputStream();");
-        }
-
-        if (!Util.isVoid(returnType)) {
-            /*
-             * Declare variable to hold return type, if not void.
-             */
-            p.p(returnType.toString() + " $result = ");
-                                                        // REMIND: why $?
-        }
-
-        /*
-         * Invoke the method on the server object.  If the remote
-         * implementation class is private, then we don't have a
-         * reference cast to it, and so we try to cast to the remote
-         * object reference to the method's declaring interface here.
-         */
-        String target = remoteClass.classDoc().isPrivate() ?
-            "((" + methodDoc.containingClass().qualifiedName() + ") obj)" :
-            "server";
-        p.p(target + "." + methodName + "(");
-        for (int i = 0; i < paramNames.length; i++) {
-            if (i > 0)
-                p.p(", ");
-            p.p(paramNames[i]);
-        }
-        p.pln(");");
-
-        /*
-         * Always invoke getResultStream(true) on the call object to send
-         * the indication of a successful invocation to the caller.  If
-         * the return type is not void, keep the result stream and marshal
-         * the return value.
-         */
-        p.plnI("try {");
-        if (!Util.isVoid(returnType)) {
-            p.p("java.io.ObjectOutput out = ");
-        }
-        p.pln("call.getResultStream(true);");
-        if (!Util.isVoid(returnType)) {
-            writeMarshalArgument(p, "out", returnType, "$result");
-            p.pln(";");
-        }
-        p.pOlnI("} catch (java.io.IOException e) {");
-        p.pln("throw new " +
-            MARSHAL_EXCEPTION + "(\"error marshalling return\", e);");
-        p.pOln("}");
-
-        p.pln("break;");                // break from switch statement
-
-        p.pOlnI("}");                   // end nested block statement
-        p.pln();
-    }
-
-    /**
-     * Writes declaration and initializer for "operations" static array.
-     **/
-    private void writeOperationsArray(IndentingWriter p)
-        throws IOException
-    {
-        p.plnI("private static final " + OPERATION + "[] operations = {");
-        for (int i = 0; i < remoteMethods.length; i++) {
-            if (i > 0)
-                p.pln(",");
-            p.p("new " + OPERATION + "(\"" +
-                remoteMethods[i].operationString() + "\")");
-        }
-        p.pln();
-        p.pOln("};");
-    }
-
-    /**
-     * Writes declaration and initializer for "interfaceHash" static field.
-     **/
-    private void writeInterfaceHash(IndentingWriter p)
-        throws IOException
-    {
-        p.pln("private static final long interfaceHash = " +
-            remoteClass.interfaceHash() + "L;");
-    }
-
-    /**
-     * Writes declaration for java.lang.reflect.Method static fields
-     * corresponding to each remote method in a stub.
-     **/
-    private void writeMethodFieldDeclarations(IndentingWriter p)
-        throws IOException
-    {
-        for (String name : methodFieldNames) {
-            p.pln("private static java.lang.reflect.Method " + name + ";");
-        }
-    }
-
-    /**
-     * Writes code to initialize the static fields for each method
-     * using the Java Reflection API.
-     **/
-    private void writeMethodFieldInitializers(IndentingWriter p)
-        throws IOException
-    {
-        for (int i = 0; i < methodFieldNames.length; i++) {
-            p.p(methodFieldNames[i] + " = ");
-            /*
-             * Look up the Method object in the somewhat arbitrary
-             * interface that we find in the Method object.
-             */
-            RemoteClass.Method method = remoteMethods[i];
-            MethodDoc methodDoc = method.methodDoc();
-            String methodName = methodDoc.name();
-            Type paramTypes[] = method.parameterTypes();
-
-            p.p(methodDoc.containingClass().qualifiedName() + ".class.getMethod(\"" +
-                methodName + "\", new java.lang.Class[] {");
-            for (int j = 0; j < paramTypes.length; j++) {
-                if (j > 0)
-                    p.p(", ");
-                p.p(paramTypes[j].toString() + ".class");
-            }
-            p.pln("});");
-        }
-    }
-
-
-    /*
-     * Following are a series of static utility methods useful during
-     * the code generation process:
-     */
-
-    /**
-     * Generates an array of names for fields correspondins to the
-     * given array of remote methods.  Each name in the returned array
-     * is guaranteed to be unique.
-     *
-     * The name of a method is included in its corresponding field
-     * name to enhance readability of the generated code.
-     **/
-    private static String[] nameMethodFields(RemoteClass.Method[] methods) {
-        String[] names = new String[methods.length];
-        for (int i = 0; i < names.length; i++) {
-            names[i] = "$method_" + methods[i].methodDoc().name() + "_" + i;
-        }
-        return names;
-    }
-
-    /**
-     * Generates an array of names for parameters corresponding to the
-     * given array of types for the parameters.  Each name in the
-     * returned array is guaranteed to be unique.
-     *
-     * A representation of the type of a parameter is included in its
-     * corresponding parameter name to enhance the readability of the
-     * generated code.
-     **/
-    private static String[] nameParameters(Type[] types) {
-        String[] names = new String[types.length];
-        for (int i = 0; i < names.length; i++) {
-            names[i] = "$param_" +
-                generateNameFromType(types[i]) + "_" + (i + 1);
-        }
-        return names;
-    }
-
-    /**
-     * Generates a readable string representing the given type
-     * suitable for embedding within a Java identifier.
-     **/
-    private static String generateNameFromType(Type type) {
-        String name = type.typeName().replace('.', '$');
-        int dimensions = type.dimension().length() / 2;
-        for (int i = 0; i < dimensions; i++) {
-            name = "arrayOf_" + name;
-        }
-        return name;
-    }
-
-    /**
-     * Writes a snippet of Java code to marshal a value named "name"
-     * of type "type" to the java.io.ObjectOutput stream named
-     * "stream".
-     *
-     * Primitive types are marshalled with their corresponding methods
-     * in the java.io.DataOutput interface, and objects (including
-     * arrays) are marshalled using the writeObject method.
-     **/
-    private static void writeMarshalArgument(IndentingWriter p,
-                                             String streamName,
-                                             Type type, String name)
-        throws IOException
-    {
-        if (type.dimension().length() > 0 || type.asClassDoc() != null) {
-            p.p(streamName + ".writeObject(" + name + ")");
-        } else if (type.typeName().equals("boolean")) {
-            p.p(streamName + ".writeBoolean(" + name + ")");
-        } else if (type.typeName().equals("byte")) {
-            p.p(streamName + ".writeByte(" + name + ")");
-        } else if (type.typeName().equals("char")) {
-            p.p(streamName + ".writeChar(" + name + ")");
-        } else if (type.typeName().equals("short")) {
-            p.p(streamName + ".writeShort(" + name + ")");
-        } else if (type.typeName().equals("int")) {
-            p.p(streamName + ".writeInt(" + name + ")");
-        } else if (type.typeName().equals("long")) {
-            p.p(streamName + ".writeLong(" + name + ")");
-        } else if (type.typeName().equals("float")) {
-            p.p(streamName + ".writeFloat(" + name + ")");
-        } else if (type.typeName().equals("double")) {
-            p.p(streamName + ".writeDouble(" + name + ")");
-        } else {
-            throw new AssertionError(type);
-        }
-    }
-
-    /**
-     * Writes Java statements to marshal a series of values in order
-     * as named in the "names" array, with types as specified in the
-     * "types" array, to the java.io.ObjectOutput stream named
-     * "stream".
-     **/
-    private static void writeMarshalArguments(IndentingWriter p,
-                                              String streamName,
-                                              Type[] types, String[] names)
-        throws IOException
-    {
-        assert types.length == names.length;
-
-        for (int i = 0; i < types.length; i++) {
-            writeMarshalArgument(p, streamName, types[i], names[i]);
-            p.pln(";");
-        }
-    }
-
-    /**
-     * Writes a snippet of Java code to unmarshal a value of type
-     * "type" from the java.io.ObjectInput stream named "stream" into
-     * a variable named "name" (if "name" is null, the value is
-     * unmarshalled and discarded).
-     *
-     * Primitive types are unmarshalled with their corresponding
-     * methods in the java.io.DataInput interface, and objects
-     * (including arrays) are unmarshalled using the readObject
-     * method.
-     *
-     * Returns true if code to invoke readObject was written, and
-     * false otherwise.
-     **/
-    private static boolean writeUnmarshalArgument(IndentingWriter p,
-                                                  String streamName,
-                                                  Type type, String name)
-        throws IOException
-    {
-        boolean readObject = false;
-
-        if (name != null) {
-            p.p(name + " = ");
-        }
-
-        if (type.dimension().length() > 0 || type.asClassDoc() != null) {
-            p.p("(" + type.toString() + ") " + streamName + ".readObject()");
-            readObject = true;
-        } else if (type.typeName().equals("boolean")) {
-            p.p(streamName + ".readBoolean()");
-        } else if (type.typeName().equals("byte")) {
-            p.p(streamName + ".readByte()");
-        } else if (type.typeName().equals("char")) {
-            p.p(streamName + ".readChar()");
-        } else if (type.typeName().equals("short")) {
-            p.p(streamName + ".readShort()");
-        } else if (type.typeName().equals("int")) {
-            p.p(streamName + ".readInt()");
-        } else if (type.typeName().equals("long")) {
-            p.p(streamName + ".readLong()");
-        } else if (type.typeName().equals("float")) {
-            p.p(streamName + ".readFloat()");
-        } else if (type.typeName().equals("double")) {
-            p.p(streamName + ".readDouble()");
-        } else {
-            throw new AssertionError(type);
-        }
-
-        return readObject;
-    }
-
-    /**
-     * Writes Java statements to unmarshal a series of values in order
-     * of types as in the "types" array from the java.io.ObjectInput
-     * stream named "stream" into variables as named in "names" (for
-     * any element of "names" that is null, the corresponding value is
-     * unmarshalled and discarded).
-     **/
-    private static boolean writeUnmarshalArguments(IndentingWriter p,
-                                                   String streamName,
-                                                   Type[] types,
-                                                   String[] names)
-        throws IOException
-    {
-        assert types.length == names.length;
-
-        boolean readObject = false;
-        for (int i = 0; i < types.length; i++) {
-            if (writeUnmarshalArgument(p, streamName, types[i], names[i])) {
-                readObject = true;
-            }
-            p.pln(";");
-        }
-        return readObject;
-    }
-
-    /**
-     * Returns a snippet of Java code to wrap a value named "name" of
-     * type "type" into an object as appropriate for use by the Java
-     * Reflection API.
-     *
-     * For primitive types, an appropriate wrapper class is
-     * instantiated with the primitive value.  For object types
-     * (including arrays), no wrapping is necessary, so the value is
-     * named directly.
-     **/
-    private static String wrapArgumentCode(Type type, String name) {
-        if (type.dimension().length() > 0 || type.asClassDoc() != null) {
-            return name;
-        } else if (type.typeName().equals("boolean")) {
-            return ("(" + name +
-                    " ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE)");
-        } else if (type.typeName().equals("byte")) {
-            return "new java.lang.Byte(" + name + ")";
-        } else if (type.typeName().equals("char")) {
-            return "new java.lang.Character(" + name + ")";
-        } else if (type.typeName().equals("short")) {
-            return "new java.lang.Short(" + name + ")";
-        } else if (type.typeName().equals("int")) {
-            return "new java.lang.Integer(" + name + ")";
-        } else if (type.typeName().equals("long")) {
-            return "new java.lang.Long(" + name + ")";
-        } else if (type.typeName().equals("float")) {
-            return "new java.lang.Float(" + name + ")";
-        } else if (type.typeName().equals("double")) {
-            return "new java.lang.Double(" + name + ")";
-        } else {
-            throw new AssertionError(type);
-        }
-    }
-
-    /**
-     * Returns a snippet of Java code to unwrap a value named "name"
-     * into a value of type "type", as appropriate for the Java
-     * Reflection API.
-     *
-     * For primitive types, the value is assumed to be of the
-     * corresponding wrapper class, and a method is called on the
-     * wrapper to retrieve the primitive value.  For object types
-     * (include arrays), no unwrapping is necessary; the value is
-     * simply cast to the expected real object type.
-     **/
-    private static String unwrapArgumentCode(Type type, String name) {
-        if (type.dimension().length() > 0 || type.asClassDoc() != null) {
-            return "((" + type.toString() + ") " + name + ")";
-        } else if (type.typeName().equals("boolean")) {
-            return "((java.lang.Boolean) " + name + ").booleanValue()";
-        } else if (type.typeName().equals("byte")) {
-            return "((java.lang.Byte) " + name + ").byteValue()";
-        } else if (type.typeName().equals("char")) {
-            return "((java.lang.Character) " + name + ").charValue()";
-        } else if (type.typeName().equals("short")) {
-            return "((java.lang.Short) " + name + ").shortValue()";
-        } else if (type.typeName().equals("int")) {
-            return "((java.lang.Integer) " + name + ").intValue()";
-        } else if (type.typeName().equals("long")) {
-            return "((java.lang.Long) " + name + ").longValue()";
-        } else if (type.typeName().equals("float")) {
-            return "((java.lang.Float) " + name + ").floatValue()";
-        } else if (type.typeName().equals("double")) {
-            return "((java.lang.Double) " + name + ").doubleValue()";
-        } else {
-            throw new AssertionError(type);
-        }
-    }
-}
--- a/src/jdk.rmic/share/classes/sun/rmi/rmic/newrmic/jrmp/Util.java	Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,149 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.rmi.rmic.newrmic.jrmp;
-
-import com.sun.javadoc.ClassDoc;
-import com.sun.javadoc.MethodDoc;
-import com.sun.javadoc.Parameter;
-import com.sun.javadoc.Type;
-
-/**
- * Provides static utility methods.
- *
- * WARNING: The contents of this source file are not part of any
- * supported API.  Code that depends on them does so at its own risk:
- * they are subject to change or removal without notice.
- *
- * @author Peter Jones
- **/
-final class Util {
-
-    private Util() { throw new AssertionError(); }
-
-    /**
-     * Returns the binary name of the class or interface represented
-     * by the specified ClassDoc.
-     **/
-    static String binaryNameOf(ClassDoc cl) {
-        String flat = cl.name().replace('.', '$');
-        String packageName = cl.containingPackage().name();
-        return packageName.equals("") ? flat : packageName + "." + flat;
-    }
-
-    /**
-     * Returns the method descriptor for the specified method.
-     *
-     * See section 4.3.3 of The Java Virtual Machine Specification
-     * Second Edition for the definition of a "method descriptor".
-     **/
-    static String methodDescriptorOf(MethodDoc method) {
-        String desc = "(";
-        Parameter[] parameters = method.parameters();
-        for (int i = 0; i < parameters.length; i++) {
-            desc += typeDescriptorOf(parameters[i].type());
-        }
-        desc += ")" + typeDescriptorOf(method.returnType());
-        return desc;
-    }
-
-    /**
-     * Returns the descriptor for the specified type, as appropriate
-     * for either a parameter or return type in a method descriptor.
-     **/
-    private static String typeDescriptorOf(Type type) {
-        String desc;
-        ClassDoc classDoc = type.asClassDoc();
-        if (classDoc == null) {
-            /*
-             * Handle primitive types.
-             */
-            String name = type.typeName();
-            if (name.equals("boolean")) {
-                desc = "Z";
-            } else if (name.equals("byte")) {
-                desc = "B";
-            } else if (name.equals("char")) {
-                desc = "C";
-            } else if (name.equals("short")) {
-                desc = "S";
-            } else if (name.equals("int")) {
-                desc = "I";
-            } else if (name.equals("long")) {
-                desc = "J";
-            } else if (name.equals("float")) {
-                desc = "F";
-            } else if (name.equals("double")) {
-                desc = "D";
-            } else if (name.equals("void")) {
-                desc = "V";
-            } else {
-                throw new AssertionError(
-                    "unrecognized primitive type: " + name);
-            }
-        } else {
-            /*
-             * Handle non-array reference types.
-             */
-            desc = "L" + binaryNameOf(classDoc).replace('.', '/') + ";";
-        }
-
-        /*
-         * Handle array types.
-         */
-        int dimensions = type.dimension().length() / 2;
-        for (int i = 0; i < dimensions; i++) {
-            desc = "[" + desc;
-        }
-
-        return desc;
-    }
-
-    /**
-     * Returns a reader-friendly string representation of the
-     * specified method's signature.  Names of reference types are not
-     * package-qualified.
-     **/
-    static String getFriendlyUnqualifiedSignature(MethodDoc method) {
-        String sig = method.name() + "(";
-        Parameter[] parameters = method.parameters();
-        for (int i = 0; i < parameters.length; i++) {
-            if (i > 0) {
-                sig += ", ";
-            }
-            Type paramType = parameters[i].type();
-            sig += paramType.typeName() + paramType.dimension();
-        }
-        sig += ")";
-        return sig;
-    }
-
-    /**
-     * Returns true if the specified type is void.
-     **/
-    static boolean isVoid(Type type) {
-        return type.asClassDoc() == null && type.typeName().equals("void");
-    }
-}
--- a/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/Console.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/Console.java	Wed Nov 08 16:03:35 2017 -0500
@@ -25,7 +25,6 @@
 
 package jdk.nashorn.tools.jjs;
 
-import java.awt.event.ActionListener;
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
@@ -69,7 +68,7 @@
         });
         in.addCompleter(completer);
         Runtime.getRuntime().addShutdownHook(new Thread((Runnable)this::saveHistory));
-        bind(DOCUMENTATION_SHORTCUT, (ActionListener)evt -> showDocumentation(docHelper));
+        bind(DOCUMENTATION_SHORTCUT, (Runnable) ()->showDocumentation(docHelper));
         try {
             Signal.handle(new Signal("CONT"), new Handler() {
                 @Override public void handle(Signal sig) {
--- a/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/EditObject.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/EditObject.java	Wed Nov 08 16:03:35 2017 -0500
@@ -117,7 +117,7 @@
         final SaveHandler saveHandler = new SaveHandler(initText);
         if (editor != null && !editor.isEmpty()) {
             ExternalEditor.edit(editor, errorHandler, initText, saveHandler, console);
-        } else if (! Main.HEADLESS) {
+        } else {
             try {
                 ServiceLoader<BuildInEditorProvider> sl
                         = ServiceLoader.load(BuildInEditorProvider.class);
@@ -136,8 +136,6 @@
             } catch (RuntimeException ex) {
                 errorHandler.accept(Main.getMessage("jjs.err.cant.launch.editor"));
             }
-        } else {
-            errorHandler.accept(Main.getMessage("no.editor"));
         }
         return UNDEFINED;
     }
--- a/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/Main.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/Main.java	Wed Nov 08 16:03:35 2017 -0500
@@ -27,8 +27,6 @@
 
 import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
 
-import java.awt.Desktop;
-import java.awt.GraphicsEnvironment;
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.InputStream;
@@ -65,7 +63,6 @@
     private static final String DOC_PROPERTY_NAME = "__doc__";
 
     static final boolean DEBUG = Boolean.getBoolean("nashorn.jjs.debug");
-    static final boolean HEADLESS = GraphicsEnvironment.isHeadless();
 
     // file where history is persisted.
     private static final File HIST_FILE = new File(new File(System.getProperty("user.home")), ".jjs.history");
@@ -120,7 +117,49 @@
         final Global oldGlobal = Context.getGlobal();
         final boolean globalChanged = (oldGlobal != global);
         final PropertiesHelper propsHelper = new PropertiesHelper(context);
-        final NashornCompleter completer = new NashornCompleter(context, global, this, propsHelper);
+
+        if (globalChanged) {
+            Context.setGlobal(global);
+        }
+
+        // Check if java.desktop module is available and we're running in non-headless mode.
+        // We access AWT via script to avoid direct dependency on java.desktop module.
+        final boolean isHeadless = (boolean) context.eval(global,
+            "(function() { \n" +
+            "    var env = java.awt.GraphicsEnvironment; \n" +
+            "    return env && typeof env.isHeadless == 'function'? \n" +
+            "        env.isHeadless() : true; \n" +
+            "})()",
+            global, "<headless-check>");
+
+        // Function that shows a JFileChooser dialog and returns the file name chosen (if chosen).
+        // We access swing from script to avoid direct dependency on java.desktop module.
+        final ScriptFunction fileChooserFunc = isHeadless? null : (ScriptFunction) context.eval(global,
+            "(function() { \n" +
+            "    var ExtensionFilter = javax.swing.filechooser.FileNameExtensionFilter; \n" +
+            "    var JFileChooser = javax.swing.JFileChooser; \n" +
+            "    function run() { \n" +
+            "        var chooser = new JFileChooser(); \n" +
+            "        chooser.fileFilter = new ExtensionFilter('JavaScript Files', 'js'); \n" +
+            "        var retVal = chooser.showOpenDialog(null);  \n" +
+            "        return retVal == JFileChooser.APPROVE_OPTION ?  \n" +
+            "            chooser.selectedFile.absolutePath : null; \n" +
+            "    }; \n" +
+            "    var fileChooserTask = new java.util.concurrent.FutureTask(run); \n" +
+            "    javax.swing.SwingUtilities.invokeLater(fileChooserTask); \n" +
+            "    return fileChooserTask.get(); \n" +
+            "})",
+            global, "<file-chooser>");
+
+        final NashornCompleter completer = new NashornCompleter(context, global, this, propsHelper, fileChooserFunc);
+
+        // Function that opens up the desktop browser application with the given URI.
+        // We access AWT from script to avoid direct dependency on java.desktop module.
+        final ScriptFunction browseFunc = isHeadless? null : (ScriptFunction) context.eval(global,
+            "(function(uri) { \n" +
+            "    java.awt.Desktop.desktop.browse(uri); \n" +
+            "})",
+            global, "<browse>");
 
         try (final Console in = new Console(System.in, System.out, HIST_FILE, completer,
                 str -> {
@@ -128,14 +167,14 @@
                         final Object res = context.eval(global, str, global, "<shell>");
                         if (res != null && res != UNDEFINED) {
                             // Special case Java types: show the javadoc for the class.
-                            if (NativeJava.isType(UNDEFINED, res)) {
+                            if (!isHeadless && NativeJava.isType(UNDEFINED, res)) {
                                 final String typeName = NativeJava.typeName(UNDEFINED, res).toString();
                                 final String url = typeName.replace('.', '/').replace('$', '.') + ".html";
-                                openBrowserForJavadoc(url);
-                            } else if (res instanceof NativeJavaPackage) {
+                                openBrowserForJavadoc(browseFunc, url);
+                            } else if (!isHeadless && res instanceof NativeJavaPackage) {
                                 final String pkgName = ((NativeJavaPackage)res).getName();
                                 final String url = pkgName.replace('.', '/') + "/package-summary.html";
-                                openBrowserForJavadoc(url);
+                                openBrowserForJavadoc(browseFunc, url);
                             } else if (res instanceof ScriptObject) {
                                 final ScriptObject sobj = (ScriptObject)res;
                                 if (sobj.has(DOC_PROPERTY_NAME)) {
@@ -153,10 +192,6 @@
                      return null;
                 })) {
 
-            if (globalChanged) {
-                Context.setGlobal(global);
-            }
-
             global.addShellBuiltins();
 
             // redefine readLine to use jline Console's readLine!
@@ -282,11 +317,10 @@
     }
 
     private static String JAVADOC_BASE = "https://docs.oracle.com/javase/9/docs/api/";
-
-    private static void openBrowserForJavadoc(String relativeUrl) {
+    private static void openBrowserForJavadoc(ScriptFunction browse, String relativeUrl) {
         try {
             final URI uri = new URI(JAVADOC_BASE + relativeUrl);
-            Desktop.getDesktop().browse(uri);
+            ScriptRuntime.apply(browse, null, uri);
         } catch (Exception ignored) {
         }
     }
--- a/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/NashornCompleter.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/NashornCompleter.java	Wed Nov 08 16:03:35 2017 -0500
@@ -29,12 +29,8 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.FutureTask;
+import java.util.Objects;
 import java.util.regex.Pattern;
-import javax.swing.JFileChooser;
-import javax.swing.filechooser.FileNameExtensionFilter;
-import javax.swing.SwingUtilities;
 import jdk.internal.jline.console.completer.Completer;
 import jdk.internal.jline.console.UserInterruptException;
 import jdk.nashorn.api.tree.AssignmentTree;
@@ -60,6 +56,7 @@
 import jdk.nashorn.internal.runtime.ECMAException;
 import jdk.nashorn.internal.runtime.Context;
 import jdk.nashorn.internal.runtime.ScriptEnvironment;
+import jdk.nashorn.internal.runtime.ScriptFunction;
 import jdk.nashorn.internal.runtime.ScriptRuntime;
 
 /**
@@ -72,16 +69,19 @@
     private final ScriptEnvironment env;
     private final PartialParser partialParser;
     private final PropertiesHelper propsHelper;
+    private final ScriptFunction fileChooserFunc;
     private final Parser parser;
     private static final boolean BACKSLASH_FILE_SEPARATOR = File.separatorChar == '\\';
 
     NashornCompleter(final Context context, final Global global,
-            final PartialParser partialParser, final PropertiesHelper propsHelper) {
+            final PartialParser partialParser, final PropertiesHelper propsHelper,
+            final ScriptFunction fileChooserFunc) {
         this.context = context;
         this.global = global;
         this.env = context.getEnv();
         this.partialParser = partialParser;
         this.propsHelper = propsHelper;
+        this.fileChooserFunc = fileChooserFunc;
         this.parser = createParser(env);
     }
 
@@ -236,8 +236,9 @@
 
         final ExpressionTree topExpr = getTopLevelExpression(parser, completeExpr);
         if (topExpr == null) {
-            // special case for load call that looks like "load(" with optional whitespaces
-            if (LOAD_CALL.matcher(test).matches()) {
+            // Special case for load call that looks like "load(" with optional whitespaces.
+            // If we have a fileChooserFunc then call it, so that the user can select a file.
+            if (fileChooserFunc != null && LOAD_CALL.matcher(test).matches()) {
                 String name = readFileName(context.getErr());
                 if (name != null) {
                     // handle '\' file separator
@@ -269,26 +270,11 @@
     // Internals only below this point
 
     // read file name from the user using by showing a swing file chooser diablog
-    private static String readFileName(final PrintWriter err) {
-        // if running on AWT Headless mode, don't attempt swing dialog box!
-        if (Main.HEADLESS) {
-            return null;
-        }
-
-        final FutureTask<String> fileChooserTask = new FutureTask<String>(() -> {
-            // show a file chooser dialog box
-            final JFileChooser chooser = new JFileChooser();
-            chooser.setFileFilter(new FileNameExtensionFilter("JavaScript Files", "js"));
-            final int retVal = chooser.showOpenDialog(null);
-            return retVal == JFileChooser.APPROVE_OPTION ?
-                chooser.getSelectedFile().getAbsolutePath() : null;
-        });
-
-        SwingUtilities.invokeLater(fileChooserTask);
-
+    private String readFileName(final PrintWriter err) {
         try {
-            return fileChooserTask.get();
-        } catch (final ExecutionException | InterruptedException e) {
+            final Object res = ScriptRuntime.apply(fileChooserFunc, null);
+            return res instanceof String? (String)res : null;
+        } catch (final Exception e) {
             err.println(e);
             if (Main.DEBUG) {
                 e.printStackTrace();
--- a/src/jdk.scripting.nashorn.shell/share/classes/module-info.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/src/jdk.scripting.nashorn.shell/share/classes/module-info.java	Wed Nov 08 16:03:35 2017 -0500
@@ -39,7 +39,6 @@
  */
 module jdk.scripting.nashorn.shell {
     requires java.compiler;
-    requires java.desktop;
     requires jdk.internal.le;
     requires jdk.scripting.nashorn;
     requires jdk.internal.ed;
--- a/test/TestCommon.gmk	Mon Nov 06 19:45:47 2017 +0100
+++ b/test/TestCommon.gmk	Wed Nov 08 16:03:35 2017 -0500
@@ -188,6 +188,16 @@
   CLEAN_ARCHIVE_BUNDLE = @$(RM) $(ARCHIVE_BUNDLE)
 endif
 
+# AddressSanitizer
+ifeq ($(ASAN_ENABLED), yes)
+  export ASAN_OPTIONS="handle_segv=0 detect_leaks=0"
+  JTREG_BASIC_OPTIONS += -e:ASAN_OPTIONS=$(ASAN_OPTIONS)
+  ifneq ($(DEVKIT_LIB_DIR),)
+    export LD_LIBRARY_PATH:=$(LD_LIBRARY_PATH):$(DEVKIT_LIB_DIR)
+    JTREG_BASIC_OPTIONS += -e:LD_LIBRARY_PATH=$(LD_LIBRARY_PATH)
+  endif
+endif
+
 # important results files
 SUMMARY_TXT = $(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/JTreport/text/summary.txt")
 STATS_TXT_NAME = Stats.txt
--- a/test/hotspot/jtreg/TEST.groups	Mon Nov 06 19:45:47 2017 +0100
+++ b/test/hotspot/jtreg/TEST.groups	Wed Nov 08 16:03:35 2017 -0500
@@ -107,15 +107,11 @@
   -compiler/loopopts/Test7052494.java \
   -compiler/runtime/Test6826736.java
 
-hotspot_tier1_compiler_closed = \
-  sanity/ExecuteInternalVMTests.java
-
 hotspot_not_fast_compiler = \
   :hotspot_compiler \
   -:hotspot_tier1_compiler_1 \
   -:hotspot_tier1_compiler_2 \
   -:hotspot_tier1_compiler_3 \
-  -:hotspot_tier1_compiler_closed
 
 hotspot_tier1_gc_1 = \
   gc/g1/
@@ -130,9 +126,6 @@
   -gc/cms/TestMBeanCMS.java \
   -gc/metaspace/CompressedClassSpaceSizeInJmapHeap.java
 
-hotspot_tier1_gc_closed = \
-  sanity/ExecuteInternalVMTests.java
-
 hotspot_tier1_gc_gcold = \
   gc/stress/gcold/TestGCOldWithG1.java
   gc/stress/gcold/TestGCOldWithCMS.java
@@ -204,10 +197,8 @@
   :hotspot_tier1_compiler_1 \
   :hotspot_tier1_compiler_2 \
   :hotspot_tier1_compiler_3 \
-  :hotspot_tier1_compiler_closed \
   :hotspot_tier1_gc_1 \
   :hotspot_tier1_gc_2 \
-  :hotspot_tier1_gc_closed \
   :hotspot_tier1_gc_gcold \
   :hotspot_tier1_runtime \
   :hotspot_tier1_serviceability
--- a/test/hotspot/jtreg/gc/stress/systemgc/TestSystemGC.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/test/hotspot/jtreg/gc/stress/systemgc/TestSystemGC.java	Wed Nov 08 16:03:35 2017 -0500
@@ -103,6 +103,8 @@
 }
 
 public class TestSystemGC {
+    private static long endTime;
+
     private static final int numGroups = 7;
     private static final int numGCsPerGroup = 4;
 
@@ -133,8 +135,11 @@
 
         for (int i = 0; i < numGroups; i++) {
             for (int j = 0; j < numGCsPerGroup; j++) {
-                System.gc();
-                ThreadUtils.sleep(getDelayMS(i));
+               System.gc();
+               if (System.currentTimeMillis() >= endTime) {
+                   return;
+               }
+               ThreadUtils.sleep(getDelayMS(i));
             }
         }
     }
@@ -159,7 +164,7 @@
     }
 
     private static void runAllPhases() {
-        for (int i = 0; i < 4; i++) {
+        for (int i = 0; i < 4 && System.currentTimeMillis() < endTime; i++) {
             SystemGCTask gcTask =
                 (i % 2 == 1) ? createSystemGCTask(numGroups / 3) : null;
             ShortLivedAllocationTask shortTask =
@@ -181,12 +186,15 @@
         }
     }
 
-    public static void main(String[] args) {
+    public static void main(String[] args) throws Exception {
+        if (args.length == 0) {
+            throw new IllegalArgumentException("Must specify timeout in seconds as first argument");
+        }
+        int timeout = Integer.parseInt(args[0]) * 1000;
+        System.out.println("Running with timeout of " + timeout + "ms");
+        endTime = System.currentTimeMillis() + timeout;
         // First allocate the long lived objects and then run all phases.
         populateLongLived();
         runAllPhases();
-        if (args.length > 0 && args[0].equals("long")) {
-            runAllPhases();
-        }
     }
 }
--- a/test/hotspot/jtreg/gc/stress/systemgc/TestSystemGCWithCMS.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/test/hotspot/jtreg/gc/stress/systemgc/TestSystemGCWithCMS.java	Wed Nov 08 16:03:35 2017 -0500
@@ -24,14 +24,15 @@
 
 /*
  * @test TestSystemGCWithCMS
+ * @bug 8190703
  * @key gc
  * @key stress
  * @requires vm.gc.ConcMarkSweep
  * @summary Stress the CMS GC full GC by allocating objects of different lifetimes concurrently with System.gc().
- * @run main/othervm/timeout=300 -Xlog:gc*=info -Xmx512m -XX:+UseConcMarkSweepGC TestSystemGCWithCMS
+ * @run main/othervm/timeout=300 -Xlog:gc*=info -Xmx512m -XX:+UseConcMarkSweepGC TestSystemGCWithCMS 270
  */
 public class TestSystemGCWithCMS {
-    public static void main(String[] args) {
+    public static void main(String[] args) throws Exception {
         TestSystemGC.main(args);
     }
 }
--- a/test/hotspot/jtreg/gc/stress/systemgc/TestSystemGCWithG1.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/test/hotspot/jtreg/gc/stress/systemgc/TestSystemGCWithG1.java	Wed Nov 08 16:03:35 2017 -0500
@@ -24,14 +24,15 @@
 
 /*
  * @test TestSystemGCWithG1
+ * @bug 8190703
  * @key gc
  * @key stress
  * @requires vm.gc.G1
  * @summary Stress the G1 GC full GC by allocating objects of different lifetimes concurrently with System.gc().
- * @run main/othervm/timeout=300 -Xlog:gc*=info -Xmx512m -XX:+UseG1GC TestSystemGCWithG1
+ * @run main/othervm/timeout=300 -Xlog:gc*=info -Xmx512m -XX:+UseG1GC TestSystemGCWithG1 270
  */
 public class TestSystemGCWithG1 {
-    public static void main(String[] args) {
+    public static void main(String[] args) throws Exception {
         TestSystemGC.main(args);
     }
 }
--- a/test/hotspot/jtreg/gc/stress/systemgc/TestSystemGCWithParallel.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/test/hotspot/jtreg/gc/stress/systemgc/TestSystemGCWithParallel.java	Wed Nov 08 16:03:35 2017 -0500
@@ -24,14 +24,15 @@
 
 /*
  * @test TestSystemGCWithParallel
+ * @bug 8190703
  * @key gc
  * @key stress
  * @requires vm.gc.Parallel
  * @summary Stress the Parallel GC full GC by allocating objects of different lifetimes concurrently with System.gc().
- * @run main/othervm/timeout=300 -Xlog:gc*=info -Xmx512m -XX:+UseParallelGC TestSystemGCWithParallel
+ * @run main/othervm/timeout=300 -Xlog:gc=info -Xmx512m -XX:+UseParallelGC TestSystemGCWithParallel 270
  */
 public class TestSystemGCWithParallel {
-    public static void main(String[] args) {
+    public static void main(String[] args) throws Exception {
         TestSystemGC.main(args);
     }
 }
--- a/test/hotspot/jtreg/gc/stress/systemgc/TestSystemGCWithSerial.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/test/hotspot/jtreg/gc/stress/systemgc/TestSystemGCWithSerial.java	Wed Nov 08 16:03:35 2017 -0500
@@ -24,14 +24,15 @@
 
 /*
  * @test TestSystemGCWithSerial
+ * @bug 8190703
  * @key gc
  * @key stress
  * @requires vm.gc.Serial
  * @summary Stress the Serial GC full GC by allocating objects of different lifetimes concurrently with System.gc().
- * @run main/othervm/timeout=300 -Xlog:gc*=info -Xmx512m -XX:+UseSerialGC TestSystemGCWithSerial
+ * @run main/othervm/timeout=300 -Xlog:gc*=info -Xmx512m -XX:+UseSerialGC TestSystemGCWithSerial 270
  */
 public class TestSystemGCWithSerial {
-    public static void main(String[] args) {
+    public static void main(String[] args) throws Exception {
         TestSystemGC.main(args);
     }
 }
--- a/test/hotspot/jtreg/runtime/constantPool/ConstModule.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/test/hotspot/jtreg/runtime/constantPool/ConstModule.java	Wed Nov 08 16:03:35 2017 -0500
@@ -47,13 +47,13 @@
 
         // Test that the JVM throws CFE for constant pool CONSTANT_Module type, for
         // class file version 53, when ACC_MODULE is not set in the access_flags.
-        ConstModule.write_and_load(Opcodes.V1_9,
+        ConstModule.write_and_load(Opcodes.V9,
             Opcodes.ACC_INTERFACE + Opcodes.ACC_ABSTRACT + Opcodes.ACC_SYNTHETIC,
             "jdk.fooMod", "FooMod", MODULE_TEST, CFE_EXCEPTION);
 
         // Test that the JVM throws NCDFE for constant pool CONSTANT_Module type,
         // for class file version 53, when ACC_MODULE is set in the access_flags.
-        ConstModule.write_and_load(Opcodes.V1_9,
+        ConstModule.write_and_load(Opcodes.V9,
             Opcodes.ACC_INTERFACE + Opcodes.ACC_ABSTRACT + Opcodes.ACC_SYNTHETIC + ACC_MODULE,
             "jdk.fooModACC", "FooModACC", MODULE_TEST, NCDFE_EXCEPTION);
 
@@ -65,13 +65,13 @@
 
         // Test that the JVM throws CFE for constant pool CONSTANT_Package type, for
         // class file version 53, when ACC_MODULE is not set in the access_flags.
-        ConstModule.write_and_load(Opcodes.V1_9,
+        ConstModule.write_and_load(Opcodes.V9,
             Opcodes.ACC_INTERFACE + Opcodes.ACC_ABSTRACT + Opcodes.ACC_SYNTHETIC,
             "jdk.fooPkg", "FooPkg", PACKAGE_TEST, CFE_EXCEPTION);
 
         // Test that the JVM throws NCDFE for constant pool CONSTANT_Package type,
         // for class file version 53, when ACC_MODULE is set in the access_flags.
-        ConstModule.write_and_load(Opcodes.V1_9,
+        ConstModule.write_and_load(Opcodes.V9,
             Opcodes.ACC_INTERFACE + Opcodes.ACC_ABSTRACT + Opcodes.ACC_SYNTHETIC + ACC_MODULE,
             "jdk.fooModACC", "FooModACC", PACKAGE_TEST, NCDFE_EXCEPTION);
 
--- a/test/jdk/ProblemList.txt	Mon Nov 06 19:45:47 2017 +0100
+++ b/test/jdk/ProblemList.txt	Wed Nov 08 16:03:35 2017 -0500
@@ -200,6 +200,8 @@
 
 java/rmi/activation/ActivationGroup/downloadActivationGroup/DownloadActivationGroup.java 8169569 windows-all
 
+java/rmi/activation/rmidViaInheritedChannel/InheritedChannelNotServerSocket.java 8170562 generic-all
+
 java/rmi/registry/readTest/CodebaseTest.java                    8173324 windows-all
 
 ############################################################################
@@ -308,8 +310,12 @@
 
 com/sun/jndi/ldap/DeadSSLLdapTimeoutTest.java                   8169942 linux-i586,macosx-all,windows-x64
 
-javax/rmi/PortableRemoteObject/8146975/RmiIiopReturnValueTest.java 8169737 linux-all
-
+javax/rmi/PortableRemoteObject/8146975/RmiIiopReturnValueTest.java 8169737 generic-all
+ 
 org/omg/CORBA/OrbPropertiesTest.java			        8175177 generic-all
 
+javax/rmi/PortableRemoteObject/ConcurrentHashMapTest.java       8080643 generic-all
+
+javax/rmi/ssl/SSLSocketParametersTest.sh                        8162906 generic-all
+
 ############################################################################
--- a/test/jdk/com/sun/awt/Translucency/WindowOpacity.java	Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,467 +0,0 @@
-/*
- * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
-  @test %W% %E%
-  @key headful
-  @bug 6594131
-  @summary Tests the AWTUtilities.get/setWindowOpacity() methods
-  @author anthony.petrov@...: area=awt.toplevel
-  @modules java.desktop/com.sun.awt
-  @run main WindowOpacity
-*/
-
-import java.awt.*;
-import java.awt.event.*;
-
-import com.sun.awt.AWTUtilities;
-
-public class WindowOpacity
-{
-    //*** test-writer defined static variables go here ***
-
-   private static Robot robot;
-
-
-    private static void init()
-    {
-        //*** Create instructions for the user here ***
-        String[] instructions =
-        {
-            "This is an AUTOMATIC test, simply wait until it is done.",
-            "The result (passed or failed) will be shown in the",
-            "message window below."
-        };
-        Sysout.createDialog( );
-        Sysout.printInstructions( instructions );
-
-        if (!AWTUtilities.isTranslucencySupported(AWTUtilities.Translucency.TRANSLUCENT)) {
-            System.out.println("Either the Toolkit or the native system does not support controlling the window opacity level.");
-            pass();
-        }
-        try {
-            robot = new Robot();
-        }catch(Exception ex) {
-            ex.printStackTrace();
-            throw new RuntimeException ("Unexpected failure");
-        }
-
-        boolean passed;
-
-        Frame f = new Frame("Opacity test");
-        f.setUndecorated(true);
-
-        passed = false;
-        try {
-            AWTUtilities.getWindowOpacity(null);
-        } catch (NullPointerException e) {
-            passed = true;
-        }
-        if (!passed) {
-            fail("getWindowOpacity() allows passing null.");
-        }
-
-
-        passed = false;
-        try {
-            AWTUtilities.setWindowOpacity(null, 0.5f);
-        } catch (NullPointerException e) {
-            passed = true;
-        }
-        if (!passed) {
-            fail("setWindowOpacity() allows passing null.");
-        }
-
-
-        float curOpacity = AWTUtilities.getWindowOpacity(f);
-        if (curOpacity < 1.0f || curOpacity > 1.0f) {
-            fail("getWindowOpacity() reports the initial opacity level other than 1.0: " + curOpacity);
-        }
-
-
-
-        passed = false;
-        try {
-            AWTUtilities.setWindowOpacity(f, -0.5f);
-        } catch (IllegalArgumentException e) {
-            passed = true;
-        }
-        if (!passed) {
-            fail("setWindowOpacity() allows passing negative opacity level.");
-        }
-
-
-
-        passed = false;
-        try {
-            AWTUtilities.setWindowOpacity(f, 1.5f);
-        } catch (IllegalArgumentException e) {
-            passed = true;
-        }
-        if (!passed) {
-            fail("setWindowOpacity() allows passing opacity level greater than 1.0.");
-        }
-
-
-        AWTUtilities.setWindowOpacity(f, 0.5f);
-
-        curOpacity = AWTUtilities.getWindowOpacity(f);
-        if (curOpacity < 0.5f || curOpacity > 0.5f) {
-            fail("getWindowOpacity() reports the opacity level that differs from the value set with setWindowOpacity: " + curOpacity);
-        }
-
-
-        AWTUtilities.setWindowOpacity(f, 0.75f);
-
-        curOpacity = AWTUtilities.getWindowOpacity(f);
-        if (curOpacity < 0.75f || curOpacity > 0.75f) {
-            fail("getWindowOpacity() reports the opacity level that differs from the value set with setWindowOpacity the second time: " + curOpacity);
-        }
-
-
-        f.setBounds(100, 100, 300, 200);
-        f.setVisible(true);
-
-        robot.waitForIdle();
-
-        curOpacity = AWTUtilities.getWindowOpacity(f);
-        if (curOpacity < 0.75f || curOpacity > 0.75f) {
-            fail("getWindowOpacity() reports the opacity level that differs from the value set with setWindowOpacity before showing the frame: " + curOpacity);
-        }
-
-
-
-        AWTUtilities.setWindowOpacity(f, 0.5f);
-        robot.waitForIdle();
-
-        curOpacity = AWTUtilities.getWindowOpacity(f);
-        if (curOpacity < 0.5f || curOpacity > 0.5f) {
-            fail("getWindowOpacity() reports the opacity level that differs from the value set with setWindowOpacity after showing the frame: " + curOpacity);
-        }
-
-        WindowOpacity.pass();
-
-    }//End  init()
-
-
-
-    /*****************************************************
-     * Standard Test Machinery Section
-     * DO NOT modify anything in this section -- it's a
-     * standard chunk of code which has all of the
-     * synchronisation necessary for the test harness.
-     * By keeping it the same in all tests, it is easier
-     * to read and understand someone else's test, as
-     * well as insuring that all tests behave correctly
-     * with the test harness.
-     * There is a section following this for test-
-     * classes
-     ******************************************************/
-    private static boolean theTestPassed = false;
-    private static boolean testGeneratedInterrupt = false;
-    private static String failureMessage = "";
-
-    private static Thread mainThread = null;
-
-    private static int sleepTime = 300000;
-
-    // Not sure about what happens if multiple of this test are
-    //  instantiated in the same VM.  Being static (and using
-    //  static vars), it aint gonna work.  Not worrying about
-    //  it for now.
-    public static void main( String args[] ) throws InterruptedException
-    {
-        mainThread = Thread.currentThread();
-        try
-        {
-            init();
-        }
-        catch( TestPassedException e )
-        {
-            //The test passed, so just return from main and harness will
-            // interepret this return as a pass
-            return;
-        }
-        //At this point, neither test pass nor test fail has been
-        // called -- either would have thrown an exception and ended the
-        // test, so we know we have multiple threads.
-
-        //Test involves other threads, so sleep and wait for them to
-        // called pass() or fail()
-        try
-        {
-            Thread.sleep( sleepTime );
-            //Timed out, so fail the test
-            throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" );
-        }
-        catch (InterruptedException e)
-        {
-            //The test harness may have interrupted the test.  If so, rethrow the exception
-            // so that the harness gets it and deals with it.
-            if( ! testGeneratedInterrupt ) throw e;
-
-            //reset flag in case hit this code more than once for some reason (just safety)
-            testGeneratedInterrupt = false;
-
-            if ( theTestPassed == false )
-            {
-                throw new RuntimeException( failureMessage );
-            }
-        }
-
-    }//main
-
-    public static synchronized void setTimeoutTo( int seconds )
-    {
-        sleepTime = seconds * 1000;
-    }
-
-    public static synchronized void pass()
-    {
-        Sysout.println( "The test passed." );
-        Sysout.println( "The test is over, hit  Ctl-C to stop Java VM" );
-        //first check if this is executing in main thread
-        if ( mainThread == Thread.currentThread() )
-        {
-            //Still in the main thread, so set the flag just for kicks,
-            // and throw a test passed exception which will be caught
-            // and end the test.
-            theTestPassed = true;
-            throw new TestPassedException();
-        }
-        theTestPassed = true;
-        testGeneratedInterrupt = true;
-        mainThread.interrupt();
-    }//pass()
-
-    public static synchronized void fail()
-    {
-        //test writer didn't specify why test failed, so give generic
-        fail( "it just plain failed! :-)" );
-    }
-
-    public static synchronized void fail( String whyFailed )
-    {
-        Sysout.println( "The test failed: " + whyFailed );
-        Sysout.println( "The test is over, hit  Ctl-C to stop Java VM" );
-        //check if this called from main thread
-        if ( mainThread == Thread.currentThread() )
-        {
-            //If main thread, fail now 'cause not sleeping
-            throw new RuntimeException( whyFailed );
-        }
-        theTestPassed = false;
-        testGeneratedInterrupt = true;
-        failureMessage = whyFailed;
-        mainThread.interrupt();
-    }//fail()
-
-}// class WindowOpacity
-
-//This exception is used to exit from any level of call nesting
-// when it's determined that the test has passed, and immediately
-// end the test.
-class TestPassedException extends RuntimeException
-{
-}
-
-//*********** End Standard Test Machinery Section **********
-
-
-//************ Begin classes defined for the test ****************
-
-// if want to make listeners, here is the recommended place for them, then instantiate
-//  them in init()
-
-/* Example of a class which may be written as part of a test
-class NewClass implements anInterface
- {
-   static int newVar = 0;
-
-   public void eventDispatched(AWTEvent e)
-    {
-      //Counting events to see if we get enough
-      eventCount++;
-
-      if( eventCount == 20 )
-       {
-         //got enough events, so pass
-
-         WindowOpacity.pass();
-       }
-      else if( tries == 20 )
-       {
-         //tried too many times without getting enough events so fail
-
-         WindowOpacity.fail();
-       }
-
-    }// eventDispatched()
-
- }// NewClass class
-
-*/
-
-
-//************** End classes defined for the test *******************
-
-
-
-
-/****************************************************
- Standard Test Machinery
- DO NOT modify anything below -- it's a standard
-  chunk of code whose purpose is to make user
-  interaction uniform, and thereby make it simpler
-  to read and understand someone else's test.
- ****************************************************/
-
-/**
- This is part of the standard test machinery.
- It creates a dialog (with the instructions), and is the interface
-  for sending text messages to the user.
- To print the instructions, send an array of strings to Sysout.createDialog
-  WithInstructions method.  Put one line of instructions per array entry.
- To display a message for the tester to see, simply call Sysout.println
-  with the string to be displayed.
- This mimics System.out.println but works within the test harness as well
-  as standalone.
- */
-
-class Sysout
-{
-    private static TestDialog dialog;
-
-    public static void createDialogWithInstructions( String[] instructions )
-    {
-        dialog = new TestDialog( new Frame(), "Instructions" );
-        dialog.printInstructions( instructions );
-        dialog.setVisible(true);
-        println( "Any messages for the tester will display here." );
-    }
-
-    public static void createDialog( )
-    {
-        dialog = new TestDialog( new Frame(), "Instructions" );
-        String[] defInstr = { "Instructions will appear here. ", "" } ;
-        dialog.printInstructions( defInstr );
-        dialog.setVisible(true);
-        println( "Any messages for the tester will display here." );
-    }
-
-
-    public static void printInstructions( String[] instructions )
-    {
-        dialog.printInstructions( instructions );
-    }
-
-
-    public static void println( String messageIn )
-    {
-        dialog.displayMessage( messageIn );
-        System.out.println(messageIn);
-    }
-
-}// Sysout  class
-
-/**
-  This is part of the standard test machinery.  It provides a place for the
-   test instructions to be displayed, and a place for interactive messages
-   to the user to be displayed.
-  To have the test instructions displayed, see Sysout.
-  To have a message to the user be displayed, see Sysout.
-  Do not call anything in this dialog directly.
-  */
-class TestDialog extends Dialog
-{
-
-    TextArea instructionsText;
-    TextArea messageText;
-    int maxStringLength = 80;
-
-    //DO NOT call this directly, go through Sysout
-    public TestDialog( Frame frame, String name )
-    {
-        super( frame, name );
-        int scrollBoth = TextArea.SCROLLBARS_BOTH;
-        instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
-        add( "North", instructionsText );
-
-        messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
-        add("Center", messageText);
-
-        pack();
-
-        setVisible(true);
-    }// TestDialog()
-
-    //DO NOT call this directly, go through Sysout
-    public void printInstructions( String[] instructions )
-    {
-        //Clear out any current instructions
-        instructionsText.setText( "" );
-
-        //Go down array of instruction strings
-
-        String printStr, remainingStr;
-        for( int i=0; i < instructions.length; i++ )
-        {
-            //chop up each into pieces maxSringLength long
-            remainingStr = instructions[ i ];
-            while( remainingStr.length() > 0 )
-            {
-                //if longer than max then chop off first max chars to print
-                if( remainingStr.length() >= maxStringLength )
-                {
-                    //Try to chop on a word boundary
-                    int posOfSpace = remainingStr.
-                        lastIndexOf( ' ', maxStringLength - 1 );
-
-                    if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1;
-
-                    printStr = remainingStr.substring( 0, posOfSpace + 1 );
-                    remainingStr = remainingStr.substring( posOfSpace + 1 );
-                }
-                //else just print
-                else
-                {
-                    printStr = remainingStr;
-                    remainingStr = "";
-                }
-
-                instructionsText.append( printStr + "\n" );
-
-            }// while
-
-        }// for
-
-    }//printInstructions()
-
-    //DO NOT call this directly, go through Sysout
-    public void displayMessage( String messageIn )
-    {
-        messageText.append( messageIn + "\n" );
-        System.out.println(messageIn);
-    }
-
-}// TestDialog  class
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/awt/Dialog/SiblingChildOrder/SiblingChildOrderTest.java	Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 8190230
+ * @summary [macosx] Order of overlapping of modal dialogs is wrong
+ * @run main SiblingChildOrderTest
+ */
+
+import javax.swing.*;
+import java.awt.*;
+
+public class SiblingChildOrderTest
+
+{
+    static Color[] colors = new Color[]{Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW};
+    static int[] x = new int[]{200, 150, 100, 50};
+    static int[] y = new int[]{200, 150, 100, 50};
+    static JDialog[] dlgs = new JDialog[4];
+    private static JFrame frame;
+
+    public static void main(String args[]) throws Exception {
+        SwingUtilities.invokeAndWait(() -> {
+            frame = new JFrame("FRAME");
+            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+            frame.setBounds(50, 50, 400, 400);
+            frame.setVisible(true);
+        });
+
+        for (int i = 0; i < colors.length; i++) {
+            int finalI = i;
+            SwingUtilities.invokeLater(() -> {
+                dlgs[finalI] = new JDialog(frame, "DLG " + finalI, true);
+                dlgs[finalI].getContentPane().setBackground(colors[finalI]);
+                dlgs[finalI].setBounds(x[finalI], y[finalI], 200, 200);
+                dlgs[finalI].setVisible(true);
+
+            });
+        }
+
+        Robot robot = new Robot();
+        robot.waitForIdle();
+        robot.delay(200);
+
+        for (int i = 0; i < colors.length; i++) {
+            Color c = robot.getPixelColor(x[i] + 190, y[i] + 190);
+            if (!c.equals(colors[i])) {
+                throw new RuntimeException("Expected " + colors[i] + " got " + c);
+            }
+        }
+
+        for (int i = 0; i < colors.length; i++) {
+            SwingUtilities.invokeLater(dlgs[i]::dispose);
+        }
+
+        SwingUtilities.invokeLater(frame::dispose);
+
+    }
+}
--- a/test/jdk/java/awt/Window/ScreenLocation/ScreenLocationTest.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/test/jdk/java/awt/Window/ScreenLocation/ScreenLocationTest.java	Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,7 +24,7 @@
 /*
  * @test
  * @key headful
- * @bug 8011616
+ * @bug 8011616 8145795
  * @summary JWindow.getLocation and JWindow.getLocationOnScreen return different
  *          values on Unity
  * @author Semyon Sadetsky
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/awt/Window/ShapedAndTranslucentWindows/WindowOpacity.java	Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+  @test
+  @key headful
+  @bug 6594131 8186617
+  @summary Tests the Window.get/setOpacity() methods
+*/
+
+import java.awt.AWTException;
+import java.awt.Frame;
+import java.awt.GraphicsDevice;
+import java.awt.GraphicsEnvironment;
+import java.awt.Robot;
+
+public class WindowOpacity {
+
+    public static void main(String[] args) throws Exception {
+        GraphicsDevice gd =
+                GraphicsEnvironment.getLocalGraphicsEnvironment()
+                        .getDefaultScreenDevice();
+        if (!gd.isWindowTranslucencySupported(
+                GraphicsDevice.WindowTranslucency.TRANSLUCENT)) {
+            System.out.println(
+                    "Either the Toolkit or the native system does not support"
+                            + " controlling the window opacity level.");
+            return;
+        }
+        Frame f = new Frame("Opacity test");
+        try {
+            test(f);
+        } finally {
+            f.dispose();
+        }
+    }
+
+    private static void test(final Frame f) throws AWTException {
+        boolean passed;
+
+        f.setUndecorated(true);
+        float curOpacity = f.getOpacity();
+        if (curOpacity < 1.0f || curOpacity > 1.0f) {
+            throw new RuntimeException(
+                    "getOpacity() reports the initial opacity level "
+                            + "other than 1.0: " + curOpacity);
+        }
+
+
+        passed = false;
+        try {
+            f.setOpacity(-0.5f);
+        } catch (IllegalArgumentException e) {
+            passed = true;
+        }
+        if (!passed) {
+            throw new RuntimeException(
+                    "setOpacity() allows passing negative opacity level.");
+        }
+
+
+        passed = false;
+        try {
+            f.setOpacity(1.5f);
+        } catch (IllegalArgumentException e) {
+            passed = true;
+        }
+        if (!passed) {
+            throw new RuntimeException(
+                    "setOpacity() allows passing opacity level greater than 1.0.");
+        }
+
+
+        f.setOpacity(0.5f);
+        curOpacity = f.getOpacity();
+        if (curOpacity < 0.5f || curOpacity > 0.5f) {
+            throw new RuntimeException(
+                    "setOpacity() reports the opacity level that "
+                            + "differs from the value set with "
+                            + "setWindowOpacity: " + curOpacity);
+        }
+
+
+        f.setOpacity(0.75f);
+        curOpacity = f.getOpacity();
+        if (curOpacity < 0.75f || curOpacity > 0.75f) {
+            throw new RuntimeException(
+                    "getOpacity() reports the opacity level that "
+                            + "differs from the value set with "
+                            + "setWindowOpacity the second time: "
+                            + curOpacity);
+        }
+
+
+        f.setBounds(100, 100, 300, 200);
+        f.setVisible(true);
+        Robot robot = new Robot();
+        robot.waitForIdle();
+
+        curOpacity = f.getOpacity();
+        if (curOpacity < 0.75f || curOpacity > 0.75f) {
+            throw new RuntimeException(
+                    "getOpacity() reports the opacity level that "
+                            + "differs from the value set with "
+                            + "setWindowOpacity before showing the frame: "
+                            + curOpacity);
+        }
+        f.setOpacity(0.5f);
+        robot.waitForIdle();
+        curOpacity = f.getOpacity();
+        if (curOpacity < 0.5f || curOpacity > 0.5f) {
+            throw new RuntimeException(
+                    "getOpacity() reports the opacity level that "
+                            + "differs from the value set with "
+                            + "setWindowOpacity after showing the frame: "
+                            + curOpacity);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/awt/dnd/DnDTestWithHIDPI/DragTestWithHIDPI.java	Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @key headful
+ * @bug 8159062
+ * @summary Tests DnD property with HIDPI scale set to non-interger value 2.5
+ * @run main/othervm -Dsun.java2d.uiScale=2.5 DragTestWithHIDPI
+ */
+
+import javax.swing.JList;
+import javax.swing.TransferHandler;
+import javax.swing.JFrame;
+import javax.swing.JComponent;
+import javax.swing.SwingUtilities;
+
+import java.awt.Robot;
+import java.awt.BorderLayout;
+import java.awt.Point;
+import java.awt.Dimension;
+import java.awt.MouseInfo;
+import java.awt.event.InputEvent;
+
+public class DragTestWithHIDPI extends TransferHandler {
+
+    private static boolean didDrag = false;
+    private static int threshold = 10;
+    private static int DEFAULT_DELAY = 550;
+
+    private Robot robot = null;
+    private static JList list = null;
+    private static Point listLocation = null;
+    private static Dimension listSize = null;
+    private static JFrame f = null;
+
+    private enum Direction {
+        RIGHT, LEFT, BOTTOM, TOP
+    }
+
+    public static void main(String[] args) throws Exception {
+        DragTestWithHIDPI test = new DragTestWithHIDPI();
+
+        // set the mouse move drag threshold
+        System.setProperty("awt.dnd.drag.threshold", String.valueOf(threshold));
+
+        test.createGUI();
+        test.doTest();
+        System.out.println("Test Passed");
+        test.disposeGUI();
+    }
+
+    public void exportAsDrag(JComponent comp, InputEvent e, int action) {
+        didDrag = true;
+    }
+
+    public DragTestWithHIDPI() {
+        super("foreground");
+    }
+
+    private void createGUI() throws Exception{
+        SwingUtilities.invokeAndWait(() -> {
+            String[] listData =
+                    new String[]{"Pacific Ocean", "Atlantic Ocean", "Indian Ocean",
+                            "Arctic Ocean"};
+            list = new JList(listData);
+            list.setDragEnabled(true);
+            list.setTransferHandler(new DragTestWithHIDPI());
+
+            f = new JFrame("DragTestWithHIDPI");
+            f.getContentPane().add(list, BorderLayout.CENTER);
+            f.pack();
+            f.toFront();
+            f.setVisible(true);
+
+            listLocation = list.getLocationOnScreen();
+            listSize = list.getSize();
+        });
+    }
+
+    private void disposeGUI () throws  Exception {
+        SwingUtilities.invokeAndWait(() -> {
+            f.dispose();
+        });
+    }
+
+    private void doTest() throws Exception {
+
+        robot = new Robot();
+        robot.waitForIdle();
+
+        for (Direction direction : Direction.values()) {
+            //Drag should not start only by moving (threshold - 1) pixels
+            didDrag = false;
+            test(threshold - 1, direction);
+            if (didDrag) {
+                disposeGUI();
+                throw new RuntimeException(
+                        "Shouldn't start drag until > " + threshold +
+                                " pixels " + " while moving " + direction);
+            }
+
+            // Drag should not start only by moving threshold pixels
+            didDrag = false;
+            test(threshold, direction);
+            if (didDrag) {
+                disposeGUI();
+                throw new RuntimeException(
+                        "Shouldn't start drag until > " + threshold +
+                                " pixels" + " while moving " + direction);
+            }
+
+            // Drag should start after moving threshold + 1 pixel
+            didDrag = false;
+            test(threshold + 1, direction);
+            if (!didDrag) {
+                disposeGUI();
+                throw new RuntimeException(
+                        "Should start drag after > " + threshold + " pixels" +
+                                " while moving " + direction);
+            }
+        }
+    }
+
+    private void test(int threshold, Direction direction) {
+        clickMouseOnList(InputEvent.BUTTON1_DOWN_MASK);
+        Point p = MouseInfo.getPointerInfo().getLocation();
+        robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
+        robot.delay(DEFAULT_DELAY);
+        glide(p, direction, threshold);
+        robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
+    }
+
+    private void glide(Point p, Direction direction, int toAdd) {
+        switch (direction) {
+            case RIGHT:
+                // move towards right
+                glide(p.x, p.y, p.x + toAdd, p.y);
+                break;
+            case LEFT:
+                // move towards left
+                glide(p.x, p.y, p.x - toAdd, p.y);
+                break;
+            case BOTTOM:
+                // move towards bottom
+                glide(p.x, p.y, p.x, p.y + toAdd);
+                break;
+            case TOP:
+                // move towards top
+                glide(p.x, p.y, p.x, p.y - toAdd);
+                break;
+
+        }
+    }
+
+    /*
+    Some utilities functions from JRobot class.
+     */
+    private void moveMouseToList() {
+        int x = listLocation.x + listSize.width/2;
+        int y = listLocation.y + listSize.height/2;
+        robot.mouseMove(x, y);
+        robot.delay(DEFAULT_DELAY);
+    }
+
+    private void clickMouse(int buttons) {
+        robot.mousePress(buttons);
+        robot.mouseRelease(buttons);
+        robot.delay(DEFAULT_DELAY);
+    }
+
+    private void clickMouseOnList(int buttons) {
+        moveMouseToList();
+        clickMouse(buttons);
+    }
+
+    private void glide(int x0, int y0, int x1, int y1) {
+        float dmax = (float)Math.max(Math.abs(x1 - x0), Math.abs(y1 - y0));
+        float dx = (x1 - x0) / dmax;
+        float dy = (y1 - y0) / dmax;
+
+        robot.mouseMove(x0, y0);
+        for (int i=1; i<=dmax; i++) {
+            robot.mouseMove((int)(x0 + dx*i), (int)(y0 + dy*i));
+        }
+        robot.delay(DEFAULT_DELAY);
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/awt/image/RescaleOp/RescaleOpExceptionTest.java	Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 8180501
+ * @summary Verify RescaleOp.filter() throws exception for different sized
+            source and destination.
+ * @run main RescaleOpExceptionTest
+ */
+
+import java.awt.image.BufferedImage;
+import static java.awt.image.BufferedImage.TYPE_INT_RGB;
+import java.awt.image.RescaleOp;
+import java.awt.image.WritableRaster;
+
+public class RescaleOpExceptionTest {
+
+    public static void main(String[] args) throws Exception {
+
+        RescaleOp op = new RescaleOp(1.0f, 0.0f, null);
+
+        BufferedImage srcI = new BufferedImage(1, 1, TYPE_INT_RGB);
+        BufferedImage dstI = new BufferedImage(1, 2, TYPE_INT_RGB);
+
+        boolean caughtIAE = false;
+        try {
+             op.filter(srcI, dstI);
+        } catch (IllegalArgumentException e) {
+            caughtIAE = true;
+        }
+        if (!caughtIAE) {
+            throw new RuntimeException("Expected IllegalArgumentException");
+        }
+
+        WritableRaster srcR = srcI.getRaster();
+        WritableRaster dstR = dstI.getRaster();
+
+        caughtIAE = false;
+        try {
+             op.filter(srcR, dstR);
+        } catch (IllegalArgumentException e) {
+            caughtIAE = true;
+        }
+        if (!caughtIAE) {
+            throw new RuntimeException("Expected IllegalArgumentException");
+        }
+    }
+}
--- a/test/jdk/java/lang/ModuleTests/AnnotationsTest.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/test/jdk/java/lang/ModuleTests/AnnotationsTest.java	Wed Nov 08 16:03:35 2017 -0500
@@ -34,13 +34,13 @@
 import java.util.List;
 import java.util.Set;
 
-import jdk.internal.module.ClassFileAttributes;
 import jdk.internal.org.objectweb.asm.AnnotationVisitor;
 import jdk.internal.org.objectweb.asm.Attribute;
 import jdk.internal.org.objectweb.asm.ClassReader;
 import jdk.internal.org.objectweb.asm.ClassVisitor;
 import jdk.internal.org.objectweb.asm.ClassWriter;
 import jdk.internal.org.objectweb.asm.Opcodes;
+import jdk.internal.org.objectweb.asm.commons.ModuleTargetAttribute;
 
 import org.testng.annotations.Test;
 import static org.testng.Assert.*;
@@ -48,6 +48,7 @@
 /**
  * @test
  * @modules java.base/jdk.internal.org.objectweb.asm
+ *          java.base/jdk.internal.org.objectweb.asm.commons
  *          java.base/jdk.internal.module
  *          java.xml
  * @run testng AnnotationsTest
@@ -113,14 +114,11 @@
             ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS
                                              + ClassWriter.COMPUTE_FRAMES);
 
-            ClassVisitor cv = new ClassVisitor(Opcodes.ASM5, cw) { };
+            ClassVisitor cv = new ClassVisitor(Opcodes.ASM6, cw) { };
 
             ClassReader cr = new ClassReader(in);
-
             List<Attribute> attrs = new ArrayList<>();
-            attrs.add(new ClassFileAttributes.ModuleAttribute());
-            attrs.add(new ClassFileAttributes.ModulePackagesAttribute());
-            attrs.add(new ClassFileAttributes.ModuleTargetAttribute());
+            attrs.add(new ModuleTargetAttribute());
             cr.accept(cv, attrs.toArray(new Attribute[0]), 0);
 
             AnnotationVisitor annotationVisitor
--- a/test/jdk/java/lang/invoke/DefineClassTest.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/test/jdk/java/lang/invoke/DefineClassTest.java	Wed Nov 08 16:03:35 2017 -0500
@@ -243,7 +243,7 @@
     byte[] generateClass(String className) {
         ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS
                                          + ClassWriter.COMPUTE_FRAMES);
-        cw.visit(V1_9,
+        cw.visit(V9,
                 ACC_PUBLIC + ACC_SUPER,
                 className.replace(".", "/"),
                 null,
@@ -272,7 +272,7 @@
 
         ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS
                                          + ClassWriter.COMPUTE_FRAMES);
-        cw.visit(V1_9,
+        cw.visit(V9,
                 ACC_PUBLIC + ACC_SUPER,
                 className.replace(".", "/"),
                 null,
@@ -309,7 +309,7 @@
 
         ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS
                                          + ClassWriter.COMPUTE_FRAMES);
-        cw.visit(V1_9,
+        cw.visit(V9,
                 ACC_PUBLIC + ACC_SUPER,
                 className.replace(".", "/"),
                 null,
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/lang/management/RuntimeMXBean/ProcessIdTest.java	Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 8044122
+ * @summary check the correctness of process ID returned by RuntimeMXBean.getPid()
+ * @run main ProcessIdTest
+ */
+
+import java.lang.management.ManagementFactory;
+import java.lang.management.RuntimeMXBean;
+import java.lang.ProcessHandle;
+
+public class ProcessIdTest {
+    public static void main(String args[]) {
+        RuntimeMXBean mbean = ManagementFactory.getRuntimeMXBean();
+        long mbeanPid = mbean.getPid();
+        long pid = ProcessHandle.current().pid();
+        long pid1 = Long.parseLong(mbean.getName().split("@")[0]);
+        if(mbeanPid != pid || mbeanPid != pid1) {
+            throw new RuntimeException("Incorrect process ID returned");
+        }
+
+        System.out.println("Test Passed");
+    }
+
+}
+
--- a/test/jdk/java/nio/channels/Channels/Basic.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/test/jdk/java/nio/channels/Channels/Basic.java	Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -167,6 +167,11 @@
             readAndCheck(blah);
             blah.delete();
 
+            testNewChannelWriteAfterClose(blah);
+
+            testNewChannelReadAfterClose(blah);
+            blah.delete();
+
             writeOut(blah, ITERATIONS);
             testNewChannelIn(blah);
             test4481572(blah);
@@ -255,6 +260,7 @@
     private static void testNewChannelOut(File blah) throws Exception {
         ExtendedFileOutputStream fos = new ExtendedFileOutputStream(blah);
         WritableByteChannel wbc = Channels.newChannel(fos);
+
         for (int i=0; i<ITERATIONS; i++)
             wbc.write(ByteBuffer.wrap(message.getBytes(encoding)));
         wbc.close();
@@ -287,6 +293,37 @@
         fis.close();
     }
 
+    private static void testNewChannelWriteAfterClose(File blah)
+        throws Exception {
+        try (ExtendedFileOutputStream fos =
+            new ExtendedFileOutputStream(blah)) {
+            WritableByteChannel wbc = Channels.newChannel(fos);
+
+            wbc.close();
+            try {
+                wbc.write(ByteBuffer.allocate(0));
+                throw new RuntimeException
+                    ("No ClosedChannelException on WritableByteChannel::write");
+            } catch (ClosedChannelException expected) {
+            }
+        }
+    }
+
+    private static void testNewChannelReadAfterClose(File blah)
+        throws Exception {
+        try (ExtendedFileInputStream fis = new ExtendedFileInputStream(blah)) {
+            ReadableByteChannel rbc = Channels.newChannel(fis);
+
+            rbc.close();
+            try {
+                rbc.read(ByteBuffer.allocate(0));
+                throw new RuntimeException
+                    ("No ClosedChannelException on ReadableByteChannel::read");
+            } catch (ClosedChannelException expected) {
+            }
+        }
+    }
+
     // Causes BufferOverflowException if bug 4481572 is present.
     private static void test4481572(File blah) throws Exception {
         ExtendedFileInputStream fis = new ExtendedFileInputStream(blah);
--- a/test/jdk/java/nio/file/Files/probeContentType/Basic.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/test/jdk/java/nio/file/Files/probeContentType/Basic.java	Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -114,7 +114,7 @@
                     failures++;
                 } else if (!type.equals(expectedTypes[i])) {
                     System.err.printf("Content type: %s; expected: %s%n",
-                        type, expectedTypes);
+                        type, expectedTypes[i]);
                     failures++;
                 }
             } finally {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/util/Properties/InitialCapacity.java	Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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.Properties;
+import org.testng.annotations.Test;
+
+/*
+ * @test
+ * @bug 8189319
+ * @summary Test that Properties(int initialCapacity) throws exceptions (or
+            doesn't) as expected
+ * @run testng InitialCapacity
+ */
+public class InitialCapacity {
+    @Test(expectedExceptions = IllegalArgumentException.class)
+    public void negativeInitCap() { Properties p = new Properties(-1); }
+
+    @Test
+    public void positiveInitCap() { Properties p = new Properties(10); }
+}
--- a/test/jdk/java/util/ServiceLoader/BadProvidersTest.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/test/jdk/java/util/ServiceLoader/BadProvidersTest.java	Wed Nov 08 16:03:35 2017 -0500
@@ -209,7 +209,7 @@
 
         ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS
                                          + ClassWriter.COMPUTE_FRAMES);
-        cw.visit(V1_9,
+        cw.visit(V9,
                 ACC_PUBLIC + ACC_SUPER,
                 "p/ProviderFactory",
                 null,
--- a/test/jdk/java/util/stream/test/org/openjdk/tests/java/util/stream/CollectAndSummaryStatisticsTest.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/test/jdk/java/util/stream/test/org/openjdk/tests/java/util/stream/CollectAndSummaryStatisticsTest.java	Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,7 +24,7 @@
 /*
  * @test
  * @summary primtive stream collection with summary statistics
- * @bug 8044047
+ * @bug 8044047 8178117
  */
 
 package org.openjdk.tests.java.util.stream;
@@ -91,11 +91,19 @@
         instances.add(countTo(1000).stream().mapToInt(i -> i).collect(IntSummaryStatistics::new,
                                                                       IntSummaryStatistics::accept,
                                                                       IntSummaryStatistics::combine));
+        instances.add(countTo(1000).stream().mapToInt(i -> i).collect(() -> new IntSummaryStatistics(0, -1, 1001, 2),
+                                                                      IntSummaryStatistics::accept,
+                                                                      IntSummaryStatistics::combine));
         instances.add(countTo(1000).parallelStream().collect(Collectors.summarizingInt(i -> i)));
         instances.add(countTo(1000).parallelStream().mapToInt(i -> i).summaryStatistics());
         instances.add(countTo(1000).parallelStream().mapToInt(i -> i).collect(IntSummaryStatistics::new,
                                                                               IntSummaryStatistics::accept,
                                                                               IntSummaryStatistics::combine));
+        instances.add(countTo(1000).parallelStream().mapToInt(i -> i).collect(() -> new IntSummaryStatistics(0, -1, 1001, 2),
+                                                                              IntSummaryStatistics::accept,
+                                                                              IntSummaryStatistics::combine));
+        IntSummaryStatistics original = instances.get(0);
+        instances.add(new IntSummaryStatistics(original.getCount(), original.getMin(), original.getMax(), original.getSum()));
 
         for (IntSummaryStatistics stats : instances) {
             assertEquals(stats.getCount(), 1000);
@@ -104,6 +112,9 @@
             assertEquals(stats.getMax(), 1000);
             assertEquals(stats.getMin(), 1);
         }
+
+        expectThrows(IllegalArgumentException.class, () -> new IntSummaryStatistics(-1, 0, 0, 0));
+        expectThrows(IllegalArgumentException.class, () -> new IntSummaryStatistics(1, 3, 2, 0));
     }
 
 
@@ -114,11 +125,19 @@
         instances.add(countTo(1000).stream().mapToLong(i -> i).collect(LongSummaryStatistics::new,
                                                                        LongSummaryStatistics::accept,
                                                                        LongSummaryStatistics::combine));
+        instances.add(countTo(1000).stream().mapToInt(i -> i).collect(() -> new LongSummaryStatistics(0, -1, 1001, 2),
+                                                                      LongSummaryStatistics::accept,
+                                                                      LongSummaryStatistics::combine));
         instances.add(countTo(1000).parallelStream().collect(Collectors.summarizingLong(i -> i)));
         instances.add(countTo(1000).parallelStream().mapToLong(i -> i).summaryStatistics());
         instances.add(countTo(1000).parallelStream().mapToLong(i -> i).collect(LongSummaryStatistics::new,
                                                                                LongSummaryStatistics::accept,
                                                                                LongSummaryStatistics::combine));
+        instances.add(countTo(1000).parallelStream().mapToInt(i -> i).collect(() -> new LongSummaryStatistics(0, -1, 1001, 2),
+                                                                              LongSummaryStatistics::accept,
+                                                                              LongSummaryStatistics::combine));
+        LongSummaryStatistics original = instances.get(0);
+        instances.add(new LongSummaryStatistics(original.getCount(), original.getMin(), original.getMax(), original.getSum()));
 
         for (LongSummaryStatistics stats : instances) {
             assertEquals(stats.getCount(), 1000);
@@ -127,6 +146,9 @@
             assertEquals(stats.getMax(), 1000L);
             assertEquals(stats.getMin(), 1L);
         }
+
+        expectThrows(IllegalArgumentException.class, () -> new LongSummaryStatistics(-1, 0, 0, 0));
+        expectThrows(IllegalArgumentException.class, () -> new LongSummaryStatistics(1, 3, 2, 0));
     }
 
     public void testDoubleStatistics() {
@@ -136,11 +158,19 @@
         instances.add(countTo(1000).stream().mapToDouble(i -> i).collect(DoubleSummaryStatistics::new,
                                                                          DoubleSummaryStatistics::accept,
                                                                          DoubleSummaryStatistics::combine));
+        instances.add(countTo(1000).stream().mapToInt(i -> i).collect(() -> new DoubleSummaryStatistics(0, -1, 1001, 2),
+                                                                      DoubleSummaryStatistics::accept,
+                                                                      DoubleSummaryStatistics::combine));
         instances.add(countTo(1000).parallelStream().collect(Collectors.summarizingDouble(i -> i)));
         instances.add(countTo(1000).parallelStream().mapToDouble(i -> i).summaryStatistics());
         instances.add(countTo(1000).parallelStream().mapToDouble(i -> i).collect(DoubleSummaryStatistics::new,
                                                                                  DoubleSummaryStatistics::accept,
                                                                                  DoubleSummaryStatistics::combine));
+        instances.add(countTo(1000).parallelStream().mapToInt(i -> i).collect(() -> new DoubleSummaryStatistics(0, -1, 1001, 2),
+                                                                              DoubleSummaryStatistics::accept,
+                                                                              DoubleSummaryStatistics::combine));
+        DoubleSummaryStatistics original = instances.get(0);
+        instances.add(new DoubleSummaryStatistics(original.getCount(), original.getMin(), original.getMax(), original.getSum()));
 
         for (DoubleSummaryStatistics stats : instances) {
             assertEquals(stats.getCount(), 1000);
@@ -149,5 +179,18 @@
             assertEquals(stats.getMax(), 1000.0);
             assertEquals(stats.getMin(), 1.0);
         }
+
+        expectThrows(IllegalArgumentException.class, () -> new DoubleSummaryStatistics(-1, 0, 0, 0));
+        expectThrows(IllegalArgumentException.class, () -> new DoubleSummaryStatistics(1, 3, 2, 0));
+        double[] values = {1.0, Double.NaN};
+        for (var min : values) {
+            for (var max : values) {
+                for (var sum : values) {
+                    if (Double.isNaN(min) && Double.isNaN(max) && Double.isNaN(sum)) continue;
+                    if (!Double.isNaN(min) && !Double.isNaN(max) && !Double.isNaN(sum)) continue;
+                    expectThrows(IllegalArgumentException.class, () -> new DoubleSummaryStatistics(1, min, max, sum));
+                }
+            }
+        }
     }
 }
--- a/test/jdk/javax/swing/JComponent/6683775/bug6683775.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/test/jdk/javax/swing/JComponent/6683775/bug6683775.java	Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,19 +24,23 @@
 /*
  * @test
  * @key headful
- * @bug 6683775 6794764
- * @summary Painting artifacts is seen when panel is made setOpaque(false) for a translucent window
- * @author Alexander Potochkin
- * @modules java.desktop/com.sun.awt
- *          java.desktop/sun.awt
- * @run main bug6683775
+ * @bug 6683775 6794764 8186617
+ * @summary Painting artifacts is seen when panel is made setOpaque(false) for a
+ *          translucent window
  */
 
-import com.sun.awt.AWTUtilities;
+import java.awt.Color;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsDevice;
+import java.awt.GraphicsEnvironment;
+import java.awt.Rectangle;
+import java.awt.Robot;
+import java.awt.Window;
+import java.awt.image.BufferedImage;
 
-import javax.swing.*;
-import java.awt.*;
-import java.awt.image.BufferedImage;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.SwingUtilities;
 
 public class bug6683775 {
     static final int LOC = 100,
@@ -44,9 +48,8 @@
 
     public static void main(String[] args) throws Exception {
         GraphicsConfiguration gc = getGC();
-       if (!AWTUtilities.isTranslucencySupported(
-               AWTUtilities.Translucency.PERPIXEL_TRANSLUCENT)
-                || gc == null) {
+        if (gc == null || !gc.getDevice().isWindowTranslucencySupported(
+                GraphicsDevice.WindowTranslucency.PERPIXEL_TRANSLUCENT)) {
             return;
         }
         Robot robot = new Robot();
@@ -65,7 +68,7 @@
             JPanel p = new JPanel();
             p.setOpaque(false);
             testFrame.add(p);
-            AWTUtilities.setWindowOpaque(testFrame, false);
+            setOpaque(testFrame, false);
             testFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
             testFrame.setBounds(LOC, LOC, SIZE, SIZE);
             testFrame.setVisible(true);
@@ -78,17 +81,28 @@
         BufferedImage capture =
                 robot.createScreenCapture(new Rectangle(LOC, LOC, SIZE, SIZE));
 
+        SwingUtilities.invokeAndWait(testFrame::dispose);
+
         int redRGB = Color.RED.getRGB();
         if (redRGB != capture.getRGB(SIZE/2, SIZE/2)) {
             throw new RuntimeException("Transparent frame is not transparent!");
         }
     }
 
+    public static void setOpaque(Window window, boolean opaque) {
+        Color bg = window.getBackground();
+        if (bg == null) {
+            bg = new Color(0, 0, 0, 0);
+        }
+        window.setBackground(new Color(bg.getRed(), bg.getGreen(), bg.getBlue(),
+                                       opaque ? 255 : 0));
+    }
+
     private static GraphicsConfiguration getGC() {
         GraphicsConfiguration transparencyCapableGC =
                 GraphicsEnvironment.getLocalGraphicsEnvironment()
                         .getDefaultScreenDevice().getDefaultConfiguration();
-        if (!AWTUtilities.isTranslucencyCapable(transparencyCapableGC)) {
+        if (!transparencyCapableGC.isTranslucencyCapable()) {
             transparencyCapableGC = null;
 
             GraphicsEnvironment env =
@@ -98,7 +112,7 @@
             for (int i = 0; i < devices.length && transparencyCapableGC == null; i++) {
                 GraphicsConfiguration[] configs = devices[i].getConfigurations();
                 for (int j = 0; j < configs.length && transparencyCapableGC == null; j++) {
-                    if (AWTUtilities.isTranslucencyCapable(configs[j])) {
+                    if (configs[j].isTranslucencyCapable()) {
                         transparencyCapableGC = configs[j];
                     }
                 }
--- a/test/jdk/javax/swing/JInternalFrame/6726866/bug6726866.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/test/jdk/javax/swing/JInternalFrame/6726866/bug6726866.java	Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -22,15 +22,20 @@
  */
 
 /* @test
-   @bug 6726866
-   @summary Repainting artifacts when resizing or dragging JInternalFrames in non-opaque toplevel
-   @author Alexander Potochkin
+   @bug 6726866 8186617
+   @summary Repainting artifacts when resizing or dragging JInternalFrames in
+            non-opaque toplevel
    @run applet/manual=yesno bug6726866.html
 */
 
-import javax.swing.*;
-import java.awt.*;
-import java.lang.reflect.Method;
+import java.awt.Color;
+import java.awt.Window;
+
+import javax.swing.JApplet;
+import javax.swing.JDesktopPane;
+import javax.swing.JFrame;
+import javax.swing.JInternalFrame;
+import javax.swing.JLabel;
 
 public class bug6726866 extends JApplet {
 
@@ -54,14 +59,12 @@
         frame.toFront();
     }
 
-    private void setWindowNonOpaque(Window w) {
-        try {
-            Class<?> c = Class.forName("com.sun.awt.AWTUtilities");
-            Method m = c.getMethod("setWindowOpaque", Window.class, boolean.class);
-            m.invoke(null, w, false);
+    public static void setWindowNonOpaque(Window window) {
+        Color bg = window.getBackground();
+        if (bg == null) {
+            bg = new Color(0, 0, 0, 0);
         }
-        catch (Exception e) {
-            e.printStackTrace();
-        }
+        window.setBackground(
+                new Color(bg.getRed(), bg.getGreen(), bg.getBlue(), 0));
     }
 }
--- a/test/jdk/javax/swing/JPopupMenu/7156657/bug7156657.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/test/jdk/javax/swing/JPopupMenu/7156657/bug7156657.java	Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -21,23 +21,33 @@
  * questions.
  */
 
-import com.sun.awt.AWTUtilities;
-import sun.awt.SunToolkit;
-
-import javax.swing.*;
-import java.awt.*;
+import java.awt.AlphaComposite;
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Rectangle;
+import java.awt.Robot;
+import java.awt.Toolkit;
+import java.awt.Window;
 import java.awt.image.BufferedImage;
 import java.util.concurrent.Callable;
 
+import javax.swing.JFrame;
+import javax.swing.JMenuItem;
+import javax.swing.JPanel;
+import javax.swing.JPopupMenu;
+import javax.swing.SwingUtilities;
+
+import sun.awt.SunToolkit;
+
 /*
    @test
-  @key headful
-   @bug 7156657
-   @summary Version 7 doesn't support translucent popup menus against a translucent window
+   @key headful
+   @bug 7156657 8186617
+   @summary Version 7 doesn't support translucent popup menus against a
+            translucent window
    @library ../../regtesthelpers
-   @author Pavel Porvatov
-   @modules java.desktop/com.sun.awt
-            java.desktop/sun.awt
+   @modules java.desktop/sun.awt
 */
 public class bug7156657 {
     private static JFrame lowerFrame;
@@ -54,8 +64,7 @@
             @Override
             public Boolean call() throws Exception {
                 frame = createFrame();
-
-                if (!AWTUtilities.isTranslucencyCapable(frame.getGraphicsConfiguration())) {
+                if (!frame.getGraphicsConfiguration().isTranslucencyCapable()) {
                     System.out.println("Translucency is not supported, the test skipped");
 
                     return true;
@@ -71,7 +80,7 @@
                 popupMenu.add(new TransparentMenuItem("2222"));
                 popupMenu.add(new TransparentMenuItem("3333"));
 
-                AWTUtilities.setWindowOpaque(frame, false);
+                setOpaque(frame, false);
                 JPanel pnContent = new JPanel();
                 pnContent.setBackground(new Color(255, 255, 255, 128));
                 frame.add(pnContent);
@@ -132,6 +141,14 @@
         System.out.println("The test passed");
     }
 
+    public static void setOpaque(Window window, boolean opaque) {
+        Color bg = window.getBackground();
+        if (bg == null) {
+            bg = new Color(0, 0, 0, 0);
+        }
+        window.setBackground(new Color(bg.getRed(), bg.getGreen(), bg.getBlue(),
+                                       opaque ? 255 : 0));
+    }
 
     private static JFrame createFrame() {
         JFrame result = new JFrame();
--- a/test/jdk/javax/swing/JTextPane/bug8025082.java	Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,109 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
- * @key headful
- * @bug 8025082
- * @summary The behaviour of the highlight will be lost after clicking the set
- * button.
- * @run main bug8025082
- */
-import java.awt.*;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.awt.event.InputEvent;
-import javax.swing.*;
-
-public class bug8025082 {
-
-    private static JButton button;
-    private static JFrame frame;
-
-    public static void main(String[] args) throws Exception {
-        Robot robo = new Robot();
-        robo.delay(500);
-
-        SwingUtilities.invokeAndWait(new Runnable() {
-            public void run() {
-                createUI();
-            }
-        });
-
-        robo.waitForIdle();
-        Point point = getButtonLocationOnScreen();
-        robo.mouseMove(point.x, point.y);
-        robo.mousePress(InputEvent.BUTTON1_MASK);
-        robo.mouseRelease(InputEvent.BUTTON1_MASK);
-        robo.waitForIdle();
-
-        SwingUtilities.invokeAndWait(new Runnable() {
-            public void run() {
-                frame.dispose();
-            }
-        });
-    }
-
-    private static void createUI() {
-        frame = new JFrame();
-        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
-        frame.setSize(500, 500);
-        JTextPane textpane = new JTextPane();
-        textpane.setText("Select Me");
-        textpane.selectAll();
-
-        JPanel panel = new JPanel(new BorderLayout());
-        panel.add(textpane, BorderLayout.CENTER);
-        button = new JButton("Press Me");
-        panel.add(button, BorderLayout.SOUTH);
-
-        button.addActionListener(new ActionListener() {
-            @Override
-            public void actionPerformed(ActionEvent e) {
-                if (!textpane.getCaret().isSelectionVisible()) {
-                    throw new RuntimeException("Highlight removed after "
-                            + "button click");
-                }
-            }
-        });
-
-        frame.getContentPane().add(panel);
-        frame.setLocationRelativeTo(null);
-        frame.setVisible(true);
-    }
-
-    private static Point getButtonLocationOnScreen() throws Exception {
-        final Point[] result = new Point[1];
-
-        SwingUtilities.invokeAndWait(new Runnable() {
-            @Override
-            public void run() {
-                Point point = button.getLocationOnScreen();
-                point.x += button.getWidth() / 2;
-                point.y += button.getHeight() / 2;
-                result[0] = point;
-            }
-        });
-        return result[0];
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/swing/text/DefaultCaret/HidingSelection/HidingSelectionTest.java	Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.InputEvent;
+import java.awt.image.BufferedImage;
+
+/**
+ * @test
+ * @bug 8188081
+ * @summary  Text selection does not clear after focus is lost
+ * @run main HidingSelectionTest
+ */
+
+public class HidingSelectionTest {
+
+    private static JTextField field1;
+    private static JTextField field2;
+    private static JFrame frame;
+    private static Rectangle bounds;
+    private static JMenu menu;
+    private static JTextField anotherWindow;
+    private static Point menuLoc;
+    private static JFrame frame2;
+
+    public static void main(String[] args) throws Exception {
+        SwingUtilities.invokeAndWait(() -> {
+            frame = new JFrame();
+            field1 = new JTextField("field1                       ");
+            field2 = new JTextField("field2                       ");
+            field1.setEditable(false);
+            field2.setEditable(false);
+            frame.getContentPane().setLayout(new FlowLayout());
+            frame.getContentPane().add(field1);
+            frame.getContentPane().add(field2);
+            JMenuBar menuBar = new JMenuBar();
+            menu = new JMenu("menu");
+            menu.add(new JMenuItem("item"));
+            menuBar.add(menu);
+            frame.setJMenuBar(menuBar);
+            frame.pack();
+            frame.setVisible(true);
+        });
+
+        Robot robot = new Robot();
+        robot.waitForIdle();
+        robot.delay(200);
+        SwingUtilities.invokeAndWait(() -> {
+            bounds = field2.getBounds();
+            bounds.setLocation(field2.getLocationOnScreen());
+        });
+        BufferedImage nosel = robot.createScreenCapture(bounds);
+
+        SwingUtilities.invokeAndWait(field2::requestFocus);
+        SwingUtilities.invokeAndWait(field2::selectAll);
+        robot.waitForIdle();
+        robot.delay(200);
+        BufferedImage sel = robot.createScreenCapture(bounds);
+
+        SwingUtilities.invokeAndWait(() -> {
+            menuLoc = menu.getLocationOnScreen();
+            menuLoc.translate(10, 10);
+        });
+        robot.mouseMove(menuLoc.x, menuLoc.y);
+        robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
+        robot.delay(50);
+        robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
+        robot.waitForIdle();
+        robot.delay(200);
+        if (!biEqual(robot.createScreenCapture(bounds), sel)) {
+            throw new RuntimeException("Test fails: menu hides selection");
+        }
+
+        SwingUtilities.invokeAndWait(
+                      MenuSelectionManager.defaultManager()::clearSelectedPath);
+        SwingUtilities.invokeAndWait(field1::requestFocus);
+        robot.waitForIdle();
+        robot.delay(200);
+        if (!biEqual(robot.createScreenCapture(bounds), nosel)) {
+            throw new RuntimeException(
+                    "Test fails: focus lost doesn't hide selection");
+        }
+
+        SwingUtilities.invokeAndWait(field2::requestFocus);
+        robot.waitForIdle();
+        SwingUtilities.invokeAndWait(() ->{
+            frame2 = new JFrame();
+            Point loc = frame.getLocationOnScreen();
+            loc.translate(0, frame.getHeight());
+            frame2.setLocation(loc);
+            anotherWindow = new JTextField("textField3");
+            frame2.add(anotherWindow);
+            frame2.pack();
+            frame2.setVisible(true);
+        });
+        robot.waitForIdle();
+        SwingUtilities.invokeAndWait(anotherWindow::requestFocus);
+        robot.waitForIdle();
+        robot.delay(200);
+        if (biEqual(robot.createScreenCapture(bounds), nosel)) {
+            throw new RuntimeException(
+                    "Test fails: switch window hides selection");
+        }
+
+        SwingUtilities.invokeAndWait(anotherWindow::selectAll);
+        robot.waitForIdle();
+        robot.delay(200);
+        if (biEqual(robot.createScreenCapture(bounds), sel)) {
+            throw new RuntimeException(
+                "Test fails: selection ownership is lost selection is shown");
+        }
+
+        SwingUtilities.invokeLater(frame2::dispose);
+        SwingUtilities.invokeLater(frame::dispose);
+    }
+
+    static boolean biEqual(BufferedImage i1, BufferedImage i2) {
+        if (i1.getWidth() == i2.getWidth() &&
+                                         i1.getHeight() == i2.getHeight()) {
+            for (int x = 0; x < i1.getWidth(); x++) {
+                for (int y = 0; y < i1.getHeight(); y++) {
+                    if (i1.getRGB(x, y) != i2.getRGB(x, y)) {
+                        return false;
+                    }
+                }
+            }
+            return true;
+        }
+        return false;
+    }
+}
--- a/test/jdk/lib/testlibrary/ModuleTargetHelper.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/test/jdk/lib/testlibrary/ModuleTargetHelper.java	Wed Nov 08 16:03:35 2017 -0500
@@ -29,13 +29,9 @@
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
-import jdk.internal.module.ClassFileConstants;
-import jdk.internal.module.ClassFileAttributes;
-import jdk.internal.module.ClassFileAttributes.ModuleTargetAttribute;
-import jdk.internal.org.objectweb.asm.Attribute;
-import jdk.internal.org.objectweb.asm.ClassReader;
-import jdk.internal.org.objectweb.asm.ClassVisitor;
-import jdk.internal.org.objectweb.asm.Opcodes;
+
+import jdk.internal.module.ModuleInfo;
+import jdk.internal.module.ModuleInfo.Attributes;
 
 public class ModuleTargetHelper {
     private ModuleTargetHelper() {}
@@ -60,29 +56,12 @@
     }
 
     public static ModuleTarget read(InputStream in) throws IOException {
-        ModuleTargetAttribute[] modTargets = new ModuleTargetAttribute[1];
-        ClassVisitor cv = new ClassVisitor(Opcodes.ASM5) {
-            @Override
-            public void visitAttribute(Attribute attr) {
-                if (attr instanceof ModuleTargetAttribute) {
-                    modTargets[0] = (ModuleTargetAttribute)attr;
-                }
-            }
-        };
-
-        // prototype of attributes that should be parsed
-        Attribute[] attrs = new Attribute[] {
-            new ModuleTargetAttribute()
-        };
-
-        // parse module-info.class
-        ClassReader cr = new ClassReader(in);
-        cr.accept(cv, attrs, 0);
-        if (modTargets[0] != null) {
-            return new ModuleTarget(modTargets[0].targetPlatform());
+        ModuleInfo.Attributes attrs = ModuleInfo.read(in, null);
+        if (attrs.target() != null) {
+            return new ModuleTarget(attrs.target().targetPlatform());
+        } else {
+            return null;
         }
-
-        return null;
     }
 
     public static ModuleTarget read(ModuleReference modRef) throws IOException {
--- a/test/jdk/sun/rmi/rmic/newrmic/equivalence/Agent.java	Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * 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.*;
-import java.io.*;
-
-/**
- * Object interface for agent
- */
-
-public interface Agent extends Serializable, Runnable {
-
-    /**
-     * Run method controls the execution of agent and is called by servers.
-     */
-    void run();
-
-    /**
-     * getInfo method is called by home server to collect the information
-     * that the agent has collected.
-     */
-    Vector getInfo();
-
-    /**
-     * getErrors returns String of errors encountered by Agent
-     */
-    String getErrors();
-}
--- a/test/jdk/sun/rmi/rmic/newrmic/equivalence/AgentServer.java	Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * 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.rmi.*;
-
-/**
- * Define the remote interface
- */
-public interface AgentServer extends Remote {
-
-    /**
-     * Accepts the agent, creates new thread and starts it.
-     */
-    void accept (Agent agent)
-        throws RemoteException; //, InvalidAgentException;
-
-    /**
-     * Method for home server to accept agent returning home and
-     * report gathered information to STDOUT.
-     */
-    void returnHome (Agent agent)
-        throws RemoteException; //, InvalidAgentException;
-}
--- a/test/jdk/sun/rmi/rmic/newrmic/equivalence/AgentServerImpl.java	Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,126 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * 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.rmi.*;
-import java.rmi.server.*;
-import java.util.*;
-import java.io.*;
-
-
-/**
- * Server accepts agents and could test for validity.  Acts as both a home
- * server and a regular server.  The agent will jump to this host and
- * the server will create a thread and allow the agent to run inside of
- * it.  The agent just queries the system.properties for machine info.
- */
-public class AgentServerImpl
-    extends UnicastRemoteObject
-    implements AgentServer
-{
-
-    /**
-     * Constructor
-     *
-     * @exception RemoteException If a network problem occurs.
-     */
-    public AgentServerImpl() throws RemoteException {
-        // Could use to set up state of server
-    }
-
-    /**
-     * Instantiates Agent Server Implementation and sets security
-     * manager
-     */
-    public static void main(String args[]) {
-
-        // Set the security Manager
-        //System.setSecurityManager(new MyRMISecurityManager());
-
-        try {
-            AgentServerImpl server = new AgentServerImpl();
-            Naming.rebind("/AgentServer", server);
-            System.out.println("Ready to receive agents.");
-                System.err.println("DTI_DoneInitializing");
-        } catch (Exception e) {
-                System.err.println("DTI_Error");
-            System.err.println("Did not establish server");
-            e.printStackTrace();
-        }
-    }
-
-    /**
-     * Remote method called by Agent to have server accept it.
-     */
-    public synchronized void accept(Agent agent)
-        throws RemoteException //, InvalidAgentException
-    {
-        Thread t;
-
-        // Could check validity of agent here
-        // checkValid(agent);
-
-        // Create new thread to run agent
-        t = new Thread(agent);
-
-        System.out.println("Agent Accepted: " + t);
-
-        // Start agent
-        t.start();
-    }
-
-    /**
-     * Remote method called by Agent to return to final server.
-     */
-    public synchronized void returnHome(Agent agent)
-        throws RemoteException //, InvalidAgentException
-    {
-        Enumeration info = null;
-        boolean bErrorsOccurred = false;
-
-        // Could check validity of agent here
-        // checkValid(agent);
-
-        // Grab and print collected info from agent
-        info = agent.getInfo().elements();
-        System.out.println("Collected information:");
-        while (info.hasMoreElements()) {
-            System.out.println("     " + (String) info.nextElement());
-        }
-
-        System.out.println("\nErrors:");
-        System.out.println(agent.getErrors());
-        if(!(agent.getErrors()).equals(""))
-                bErrorsOccurred = true;
-
-        if(bErrorsOccurred)
-    {
-                System.err.println("DTI_Error");
-                System.err.println("DTI_DoneExecuting");
-        }
-        else
-    {
-                System.err.println("DTI_DoneExecuting");
-    }
-
-        }
-}
--- a/test/jdk/sun/rmi/rmic/newrmic/equivalence/Apple.java	Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-public interface Apple extends java.rmi.Remote {
-
-    public void notify(AppleEvent[] e) throws java.rmi.RemoteException;
-
-    public Orange newOrange(String name) throws java.rmi.RemoteException;
-}
--- a/test/jdk/sun/rmi/rmic/newrmic/equivalence/AppleEvent.java	Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * 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.Date;
-
-/**
- * The AppleEvent class is simply an object to be passed back to a
- * remote objct exported by an applet to verify proper object
- * serialization.
- */
-public class AppleEvent implements java.io.Serializable {
-
-    public static final int BUY   = 0;
-    public static final int EAT   = 1;
-    public static final int THROW = 2;
-
-    private int what;
-
-    private java.util.Date when;
-
-    public AppleEvent(int what)
-    {
-        this.what = what;
-        this.when = new Date();
-    }
-
-    public String toString()
-    {
-        String desc = "[";
-        switch (what) {
-        case BUY:
-            desc += "BUY";
-            break;
-        case EAT:
-            desc += "EAT";
-            break;
-        case THROW:
-            desc += "THROW";
-            break;
-        }
-        desc += " @ " + when + "]";
-        return desc;
-    }
-}
--- a/test/jdk/sun/rmi/rmic/newrmic/equivalence/AppleImpl.java	Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,95 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * 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.rmi.RemoteException;
-import java.rmi.server.UnicastRemoteObject;
-import java.util.logging.Logger;
-import java.util.logging.Level;
-
-/**
- * The AppleImpl class implements the behavior of the remote "apple"
- * objects exported by the application.
- */
-public class AppleImpl
-    extends UnicastRemoteObject
-    implements Apple
-{
-
-    private static Logger logger = Logger.getLogger("reliability.apple");
-    private String name;
-
-    public AppleImpl(String name) throws RemoteException {
-        this.name = name;
-    }
-
-    /**
-     * Receive an array of AppleEvent objects.
-     */
-    public void notify(AppleEvent[] events) {
-        try {
-            String threadName = Thread.currentThread().getName();
-            logger.log(Level.FINEST,
-                threadName + ": " + toString() + ".notify: BEGIN");
-
-            for (int i = 0; i < events.length; ++ i) {
-                logger.log(Level.FINEST,
-                    threadName + ": " + toString() +
-                        ".notify(): events[" + i + "] = " +
-                        events[i].toString());
-            }
-
-            logger.log(Level.FINEST,
-                threadName + ": " + toString() + ".notify(): END");
-        } catch (RuntimeException e) {
-            logger.log(Level.SEVERE, toString() + ".notify():", e);
-            throw e;
-        }
-    }
-
-    /**
-     * Return a newly created and exported orange implementation.
-     */
-    public Orange newOrange(String name) throws RemoteException {
-        try {
-            String threadName = Thread.currentThread().getName();
-            logger.log(Level.FINEST,
-                threadName + ": " + toString() +
-                ".newOrange(" + name + "): BEGIN");
-
-            Orange orange = new OrangeImpl(name);
-
-            logger.log(Level.FINEST,
-                threadName + ": " + toString() +
-                ".newOrange(" + name + "): END");
-
-            return orange;
-        } catch (RuntimeException e) {
-            logger.log(Level.SEVERE, toString() + ".newOrange():", e);
-            throw e;
-        }
-    }
-
-    public String toString() {
-        return name;
-    }
-}
--- a/test/jdk/sun/rmi/rmic/newrmic/equivalence/AppleUser.java	Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * 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.rmi.Remote;
-import java.rmi.RemoteException;
-
-public interface AppleUser extends Remote {
-    public void startTest() throws RemoteException;
-    public void reportException(Exception status) throws RemoteException;
-    public void useApple(Apple apple) throws RemoteException;
-}
--- a/test/jdk/sun/rmi/rmic/newrmic/equivalence/AppleUserImpl.java	Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,317 +0,0 @@
-/*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * 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.rmi.RemoteException;
-import java.rmi.Naming;
-import java.rmi.server.UnicastRemoteObject;
-import java.rmi.registry.LocateRegistry;
-import java.rmi.registry.Registry;
-import java.util.Random;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.logging.Logger;
-import java.util.logging.Level;
-
-/**
- * The AppleUserImpl class implements the behavior of the remote
- * "apple user" objects exported by the server.  The application server
- * passes each of its remote "apple" objects to an apple user, and an
- * AppleUserThread is created for each apple.
- */
-public class AppleUserImpl
-    extends UnicastRemoteObject
-    implements AppleUser
-{
-    private static Logger logger = Logger.getLogger("reliability.appleuser");
-    private static int threadNum = 0;
-    private static long testDuration = 0;
-    private static int maxLevel = 7;
-    private static Thread server = null;
-    private static Exception status = null;
-    private static Random random = new Random();
-
-    public AppleUserImpl() throws RemoteException {
-    }
-
-    /**
-     * Allows the other server process to indicate that it is ready
-     * to start "juicing".
-     */
-    public synchronized void startTest() throws RemoteException {
-        this.notifyAll();
-    }
-
-    /**
-     * Allows the other server process to report an exception to this
-     * process and thereby terminate the test.
-     */
-    public void reportException(Exception status) throws RemoteException {
-        synchronized (AppleUserImpl.class) {
-            this.status = status;
-            AppleUserImpl.class.notifyAll();
-        }
-    }
-
-    /**
-     * "Use" supplied apple object.  Create an AppleUserThread to
-     * stress it out.
-     */
-    public synchronized void useApple(Apple apple) throws RemoteException {
-        String threadName = Thread.currentThread().getName();
-        logger.log(Level.FINEST,
-            threadName + ": AppleUserImpl.useApple(): BEGIN");
-
-        AppleUserThread t =
-            new AppleUserThread("AppleUserThread-" + (++threadNum), apple);
-        t.start();
-
-        logger.log(Level.FINEST,
-            threadName + ": AppleUserImpl.useApple(): END");
-    }
-
-    /**
-     * The AppleUserThread class repeatedly invokes calls on its associated
-     * Apple object to stress the RMI system.
-     */
-    class AppleUserThread extends Thread {
-
-        Apple apple;
-
-        public AppleUserThread(String name, Apple apple) {
-            super(name);
-            this.apple = apple;
-        }
-
-        public void run() {
-            int orangeNum = 0;
-            long stopTime = System.currentTimeMillis() + testDuration;
-            Logger logger = Logger.getLogger("reliability.appleuserthread");
-
-            try {
-                do { // loop until stopTime is reached
-
-                    /*
-                     * Notify apple with some apple events.  This tests
-                     * serialization of arrays.
-                     */
-                    int numEvents = Math.abs(random.nextInt() % 5);
-                    AppleEvent[] events = new AppleEvent[numEvents];
-                    for (int i = 0; i < events.length; ++ i) {
-                        events[i] = new AppleEvent(orangeNum % 3);
-                    }
-                    apple.notify(events);
-
-                    /*
-                     * Request a new orange object be created in
-                     * the application server.
-                     */
-                    Orange orange = apple.newOrange(
-                        "Orange(" + getName() + ")-" + (++orangeNum));
-
-                    /*
-                     * Create a large message of random ints to pass to orange.
-                     */
-                    int msgLength = 1000 + Math.abs(random.nextInt() % 3000);
-                    int[] message = new int[msgLength];
-                    for (int i = 0; i < message.length; ++ i) {
-                        message[i] = random.nextInt();
-                    }
-
-                    /*
-                     * Invoke recursive call on the orange.  Base case
-                     * of recursion inverts messgage.
-                     */
-                    OrangeEchoImpl echo = new OrangeEchoImpl(
-                        "OrangeEcho(" + getName() + ")-" + orangeNum);
-                    int[] response = orange.recurse(echo, message,
-                        2 + Math.abs(random.nextInt() % (maxLevel + 1)));
-
-                    /*
-                     * Verify message was properly inverted and not corrupted
-                     * through all the recursive method invocations.
-                     */
-                    if (response.length != message.length) {
-                        throw new RuntimeException(
-                            "ERROR: CORRUPTED RESPONSE: " +
-                            "wrong length of returned array " + "(should be " +
-                            message.length + ", is " + response.length + ")");
-                    }
-                    for (int i = 0; i < message.length; ++ i) {
-                        if (~message[i] != response[i]) {
-                            throw new RuntimeException(
-                                "ERROR: CORRUPTED RESPONSE: " +
-                                "at element " + i + "/" + message.length +
-                                " of returned array (should be " +
-                                Integer.toHexString(~message[i]) + ", is " +
-                                Integer.toHexString(response[i]) + ")");
-                        }
-                    }
-
-                    try {
-                        Thread.sleep(Math.abs(random.nextInt() % 10) * 1000);
-                    } catch (InterruptedException e) {
-                    }
-
-                } while (System.currentTimeMillis() < stopTime);
-
-            } catch (Exception e) {
-                status = e;
-            }
-            synchronized (AppleUserImpl.class) {
-                AppleUserImpl.class.notifyAll();
-            }
-        }
-    }
-
-    private static void usage() {
-        System.out.println("Usage: AppleUserImpl [-hours <hours> | " +
-                                                 "-seconds <seconds>]");
-        System.out.println("                     [-maxLevel <maxLevel>]");
-        System.out.println("  hours    The number of hours to run the juicer.");
-        System.out.println("           The default is 0 hours.");
-        System.out.println("  seconds  The number of seconds to run the juicer.");
-        System.out.println("           The default is 0 seconds.");
-        System.out.println("  maxLevel The maximum number of levels to ");
-        System.out.println("           recurse on each call.");
-        System.out.println("           The default is 7 levels.");
-        //TestLibrary.bomb("Bad argument");
-    }
-
-    /**
-     * Entry point for the "juicer" server process.  Create and export
-     * an apple user implementation in an rmiregistry running on localhost.
-     */
-    public static void main(String[] args)
-
-    {
-        //TestLibrary.suggestSecurityManager("java.rmi.RMISecurityManager");
-        long startTime = 0;
-        String durationString = null;
-
-        // parse command line args
-        try {
-            for (int i = 0; i < args.length ; i++ ) {
-                String arg = args[i];
-                if (arg.equals("-hours")) {
-                    if (durationString != null) {
-                        usage();
-                    }
-                    i++;
-                    int hours = Integer.parseInt(args[i]);
-                    durationString = hours + " hours";
-                    testDuration = hours * 60 * 60 * 1000;
-                } else if (arg.equals("-seconds")) {
-                    if (durationString != null) {
-                        usage();
-                    }
-                    i++;
-                    long seconds = Long.parseLong(args[i]);
-                    durationString = seconds + " seconds";
-                    testDuration = seconds * 1000;
-                } else if (arg.equals("-maxLevel")) {
-                    i++;
-                    maxLevel = Integer.parseInt(args[i]);
-                } else {
-                    usage();
-                }
-            }
-            if (durationString == null) {
-                durationString = testDuration + " milliseconds";
-            }
-        } catch (Throwable t) {
-            usage();
-        }
-
-        AppleUserImpl user = null;
-        try {
-            user = new AppleUserImpl();
-        } catch (RemoteException e) {
-            //TestLibrary.bomb("Failed to create AppleUser", e);
-        }
-
-        synchronized (user) {
-            int port = -1;
-            // create new registry and bind new AppleUserImpl in registry
-            try {
-                Registry registry = TestLibrary.createRegistryOnEphemeralPort();
-                port = TestLibrary.getRegistryPort(registry);
-                Naming.rebind("rmi://localhost:" + port + "/AppleUser",user);
-            } catch (RemoteException e) {
-                //TestLibrary.bomb("Failed to bind AppleUser", e);
-            } catch (java.net.MalformedURLException e) {
-                //TestLibrary.bomb("Failed to bind AppleUser", e);
-            }
-
-            // start the other server if available
-            try {
-                Class app = Class.forName("ApplicationServer");
-                java.lang.reflect.Constructor appConstructor =
-                        app.getDeclaredConstructor(new Class[] {Integer.TYPE});
-                server = new Thread((Runnable) appConstructor.newInstance(port));
-            } catch (ClassNotFoundException e) {
-                // assume the other server is running in a separate process
-                logger.log(Level.INFO, "Application server must be " +
-                    "started in separate process");
-            } catch (Exception ie) {
-                //TestLibrary.bomb("Could not instantiate server", ie);
-            }
-
-            // wait for other server to call startTest method
-            try {
-                logger.log(Level.INFO, "Waiting for application server " +
-                    "process to start");
-                user.wait();
-            } catch (InterruptedException ie) {
-                //TestLibrary.bomb("AppleUserImpl interrupted", ie);
-            }
-        }
-
-        startTime = System.currentTimeMillis();
-        logger.log(Level.INFO, "Test starting");
-
-        // wait for exception to be reported or first thread to complete
-        try {
-            logger.log(Level.INFO, "Waiting " + durationString + " for " +
-                "test to complete or exception to be thrown");
-
-            synchronized (AppleUserImpl.class) {
-                AppleUserImpl.class.wait();
-            }
-
-            if (status != null) {
-                //TestLibrary.bomb("juicer server reported an exception", status);
-            } else {
-                logger.log(Level.INFO, "TEST PASSED");
-            }
-        } catch (Exception e) {
-            logger.log(Level.INFO, "TEST FAILED");
-            //TestLibrary.bomb("unexpected exception", e);
-        } finally {
-            logger.log(Level.INFO, "Test finished");
-            long actualDuration = System.currentTimeMillis() - startTime;
-            logger.log(Level.INFO, "Test duration was " +
-                (actualDuration/1000) + " seconds " +
-                "(" + (actualDuration/3600000) + " hours)");
-        }
-    }
-}
--- a/test/jdk/sun/rmi/rmic/newrmic/equivalence/Callback.java	Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * 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.rmi.*;
-import java.rmi.registry.*;
-import java.rmi.server.*;
-
-
-
-public interface Callback extends Remote
-{
-        void callback() throws RemoteException;
-}
--- a/test/jdk/sun/rmi/rmic/newrmic/equivalence/ComputeServer.java	Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * 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.rmi.*;
-
-/**
- * Remote interface for the Compute Server
- */
-public interface ComputeServer extends Remote {
-
-    /**
-     * Called by the task and passes itself as an object
-     */
-    Object compute(Task task) throws RemoteException;
-}
--- a/test/jdk/sun/rmi/rmic/newrmic/equivalence/ComputeServerImpl.java	Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,60 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * 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.rmi.*;
-import java.rmi.server.*;
-import java.io.*;
-
-/**
- * Class accepts a task and runs it in its own space.
- */
-public class ComputeServerImpl
-    extends UnicastRemoteObject
-    implements ComputeServer
-{
-        public ComputeServerImpl() throws RemoteException
-        {
-
-    }
-
-    /**
-     * Accepts task and runs it
-     */
-    public Object compute(Task task) {
-        return task.run();
-    }
-
-    /**
-     * Binds compute server and waits for tasks
-     */
-    public static void main(String args[]) throws Exception
-        {
-                // use the default, restrictive security manager
-                System.setSecurityManager(new RMISecurityManager());
-
-                Naming.rebind("/ComputeServer", new ComputeServerImpl());
-                System.out.println("Ready to receive tasks.");
-
-                System.err.println("DTI_DoneInitializing");
-    }
-}
--- a/test/jdk/sun/rmi/rmic/newrmic/equivalence/CountInterface.java	Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * 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.
- */
-
-// RMI Activation Functional Test
-
-import java.rmi.*;
-import java.rmi.activation.*;
-
-// CountInterface
-
-public interface CountInterface extends Remote {
-
-    public void ping() throws RemoteException;
-
-    public int incrementCount() throws RemoteException;
-
-    public int decrementCount() throws RemoteException;
-
-    public int getCount() throws RemoteException;
-
-    public int getClassCount() throws RemoteException;
-
-    public String getProperty(String s) throws RemoteException;
-
-    public void exit() throws RemoteException;
-
-    // Methods specific to dealing with activatable objects
-
-    public boolean unexportObject(boolean b) throws RemoteException;
-
-    public ActivationID getActivationID() throws RemoteException;
-
-    public ActivationGroupID getCurrentGroupID() throws RemoteException;
-
-    public void inactive()
-        throws RemoteException, UnknownObjectException, ActivationException;
-
-    public void register()
-        throws RemoteException, UnknownObjectException, ActivationException;
-
-    public void unregister()
-        throws RemoteException, UnknownObjectException, ActivationException;
-}
--- a/test/jdk/sun/rmi/rmic/newrmic/equivalence/CountServerImpl.java	Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,176 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * 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.
- */
-
-// RMI Activation Functional Test
-
-import java.rmi.*;
-import java.rmi.server.*;
-import java.rmi.activation.*;
-import java.util.*;
-
-// CountServerImpl
-
-public class CountServerImpl
-    extends Activatable
-    implements CountInterface {
-
-    private static final String PROG_NAME       = "CountServerImpl";
-    private static final String SERVER_OBJECT   = "CountServer";
-    private static final String CLASS_NAME      = "activation.CountServerImpl";
-
-    private static final String POLICY_FILE   = "policy_file";
-
-    private static final String USER_DIR      =
-                        System.getProperty("user.dir").replace('\\', '/');
-
-    private static final String CODE_LOCATION = "file:"+USER_DIR+"/";
-
-    private static final MarshalledObject DATA = null;
-    private static ActivationDesc ACTIVATION_DESC = null;
-
-    // Class variable
-    private static int classCount = 0;
-
-    // Instance variable
-    private int instanceCount;
-    private TestInterface ref;
-
-    public CountServerImpl(ActivationID id, MarshalledObject data)
-        throws RemoteException {
-        super(id, 0);
-        instanceCount = 0;
-        classCount++;
-        if (data != null) {
-            try {
-                ref = (TestInterface)data.get();
-                ref.ping(SERVER_OBJECT);
-            }
-            catch (Exception e) {
-                System.err.println("Exception: " + e);
-            }
-        }
-    }
-
-    public void ping() throws RemoteException {}
-
-    public int getCount() throws RemoteException {
-        return instanceCount;
-    }
-
-    public int incrementCount() throws RemoteException {
-        return ++instanceCount;
-    }
-
-    public int decrementCount() throws RemoteException {
-        return --instanceCount;
-    }
-
-    public int getClassCount() throws RemoteException {
-        return classCount;
-    }
-
-    public String getProperty(String s) throws RemoteException {
-        return System.getProperty(s);
-    }
-
-    public void exit() throws RemoteException {
-        System.exit(0);
-    }
-
-    public boolean unexportObject(boolean force) {
-        boolean succeeded = false;
-        try {
-            succeeded = Activatable.unexportObject(this, force);
-        }
-        catch (Exception e) {
-            System.err.println("Exception: " + e);
-            e.printStackTrace();
-        }
-        return succeeded;
-    }
-
-    public ActivationID getActivationID() throws RemoteException {
-        return super.getID();
-    }
-
-    public void inactive()
-        throws RemoteException, ActivationException, UnknownObjectException {
-
-        //ShutDown s = new ShutDown(super.getID(),this,ShutDown.NORMAL_SHUTDOWN);
-    }
-
-    public void unregister()
-        throws RemoteException, ActivationException, UnknownObjectException {
-        unregister(super.getID());
-    }
-
-    public void register()
-        throws RemoteException, ActivationException, UnknownObjectException {
-        register(ACTIVATION_DESC);
-    }
-
-    public ActivationGroupID getCurrentGroupID() throws RemoteException {
-        return ActivationGroup.currentGroupID();
-    }
-
-    private static void setup() {
-
-        try {
-
-          CountInterface rsi;   // Remote server interface
-
-          System.setSecurityManager(new RMISecurityManager());
-
-          rsi = (CountInterface)Activatable.register(ACTIVATION_DESC);
-          System.out.println("Got stub for "+SERVER_OBJECT+" implementation");
-
-          Naming.rebind(SERVER_OBJECT, rsi);
-          System.out.println("Exported "+SERVER_OBJECT+" implementation");
-
-        } catch (Exception e) {
-            System.err.println("Exception: " + e);
-            e.printStackTrace();
-        }
-    }
-
-    public static void main(String[] args) {
-
-        try {
-            Properties props = new Properties();
-            props.setProperty("java.security.policy", POLICY_FILE);
-
-            ActivationGroupDesc agd = new ActivationGroupDesc(props, null);
-
-            ActivationGroupID agid = ActivationGroup.getSystem().registerGroup(agd);
-
-            ACTIVATION_DESC = new ActivationDesc(agid,
-                        CLASS_NAME, CODE_LOCATION, DATA, false);
-        }
-        catch (Exception e) {
-            System.err.println("Exception: " + e);
-            e.printStackTrace();
-        }
-
-        setup();
-    }
-}
--- a/test/jdk/sun/rmi/rmic/newrmic/equivalence/DayTimeInterface.java	Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * 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.
- */
-
-// RMI Activation Functional Test
-
-import java.rmi.*;
-import java.rmi.activation.*;
-
-// DayTimeInterface
-
-public interface DayTimeInterface extends Remote {
-
-    public void ping() throws RemoteException;
-
-    public java.util.Date getDayTime() throws java.rmi.RemoteException;
-
-    public void exit() throws RemoteException;
-
-    public ActivationID getActivationID() throws RemoteException;
-
-    public ActivationGroupID getCurrentGroupID() throws RemoteException;
-
-    public void inactive()
-        throws RemoteException, UnknownObjectException, ActivationException;
-
-    public void register()
-        throws RemoteException, UnknownObjectException, ActivationException;
-
-    public void unregister()
-        throws RemoteException, UnknownObjectException, ActivationException;
-}
--- a/test/jdk/sun/rmi/rmic/newrmic/equivalence/DayTimeServerImpl.java	Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,140 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * 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.
- */
-
-// RMI Activation Functional Test
-
-import java.rmi.*;
-import java.rmi.activation.*;
-import java.util.*;
-
-// DayTimeServerImpl
-
-public class DayTimeServerImpl
-    extends Activatable
-    implements DayTimeInterface {
-
-    private static final String PROG_NAME       = "DayTimeServerImpl";
-    private static final String SERVER_OBJECT   = "DayTimeServer";
-    private static final String CLASS_NAME      = "activation.DayTimeServerImpl";
-
-    private static final String POLICY_FILE   = "policy_file";
-
-    private static final String USER_DIR      =
-                        System.getProperty("user.dir").replace('\\', '/');
-
-    private static final String CODE_LOCATION = "file:"+USER_DIR+"/";
-
-    private static final MarshalledObject DATA = null;
-    private static ActivationDesc ACTIVATION_DESC = null;
-
-    private TestInterface ref;
-
-    public void ping() throws RemoteException {}
-
-    public ActivationID getActivationID() throws RemoteException {
-        return super.getID();
-    }
-
-    public DayTimeServerImpl(ActivationID id, MarshalledObject data)
-        throws RemoteException {
-        super(id, 0);
-        if (data != null) {
-            try {
-                ref = (TestInterface)data.get();
-                ref.ping(SERVER_OBJECT);
-            }
-            catch (Exception e) {
-                System.err.println("Exception: " + e);
-            }
-        }
-    }
-
-    public Date getDayTime() throws RemoteException {
-        return new Date();
-    }
-
-    public void exit() throws RemoteException {
-        System.exit(0);
-    }
-
-    public void inactive()
-        throws RemoteException, ActivationException, UnknownObjectException {
-
-        //ShutDown s = new ShutDown(super.getID(),this,ShutDown.NORMAL_SHUTDOWN);
-    }
-
-    public void unregister()
-        throws RemoteException, ActivationException, UnknownObjectException {
-        unregister(super.getID());
-    }
-
-    public void register()
-        throws RemoteException, ActivationException, UnknownObjectException {
-        register(ACTIVATION_DESC);
-    }
-
-    public ActivationGroupID getCurrentGroupID() throws RemoteException {
-        return ActivationGroup.currentGroupID();
-    }
-
-    private static void setup() {
-
-        try {
-
-          DayTimeInterface rsi; // Remote server interface
-
-          System.setSecurityManager(new RMISecurityManager());
-
-          rsi = (DayTimeInterface)Activatable.register(ACTIVATION_DESC);
-          System.out.println("Got stub for "+SERVER_OBJECT+" implementation");
-
-          Naming.rebind(SERVER_OBJECT, rsi);
-          System.out.println("Exported "+SERVER_OBJECT+" implementation");
-
-        } catch (Exception e) {
-            System.err.println("Exception: " + e);
-            e.printStackTrace();
-        }
-    }
-
-    public static void main(String[] args) {
-
-        try {
-            Properties props = new Properties();
-            props.setProperty("java.security.policy", POLICY_FILE);
-
-            ActivationGroupDesc agd = new ActivationGroupDesc(props, null);
-
-            ActivationGroupID agid = ActivationGroup.getSystem().registerGroup(agd);
-
-            ACTIVATION_DESC = new ActivationDesc(agid,
-                        CLASS_NAME, CODE_LOCATION, DATA, false);
-        }
-        catch (Exception e) {
-            System.err.println("Exception: " + e);
-            e.printStackTrace();
-        }
-
-        setup();
-    }
-}
--- a/test/jdk/sun/rmi/rmic/newrmic/equivalence/G1.java	Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * 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.rmi.Remote;
-import java.rmi.RemoteException;
-
-public interface G1 extends Remote {
-    void m() throws RemoteException;
-}
--- a/test/jdk/sun/rmi/rmic/newrmic/equivalence/G1Impl.java	Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-public class G1Impl implements G1 {
-    public void m() { }
-}
--- a/test/jdk/sun/rmi/rmic/newrmic/equivalence/MyObject.java	Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * 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.rmi.*;
-
-public interface MyObject extends Remote {
-    public void method1(MyObject obj) throws RemoteException;
-
-    public void method2(MyObject[] objs) throws RemoteException;
-
-    public void method3() throws RemoteException;
-}
--- a/test/jdk/sun/rmi/rmic/newrmic/equivalence/MyObjectImpl.java	Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * 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.rmi.*;
-import java.rmi.server.*;
-
-public class MyObjectImpl extends UnicastRemoteObject implements MyObject {
-    private int clientNum = -1;
-    private byte[] data = null;
-    //private MyObjectFactory mof = null;
-    private boolean AliveMyObjectsCounterWasIncremented = false;
-
-    public MyObjectImpl() throws RemoteException {
-        super();
-    }
-
-    public MyObjectImpl(int c, int size) //MyObjectFactory mof, int c, int size)
-                        throws RemoteException {
-        super();
-        //this.mof = mof;
-        this.clientNum = c;
-        this.data = new byte[size];
-        //mof.incAliveMyObjects(1);
-        AliveMyObjectsCounterWasIncremented = true;
-    }
-
-    public void method1(MyObject obj) throws RemoteException {
-    }
-
-    public void method2(MyObject[] objs) throws RemoteException {
-    }
-
-    public void method3() throws RemoteException {
-    }
-
-    protected void finalize() throws Throwable {
-        if(AliveMyObjectsCounterWasIncremented)
-            ; //mof.decAliveMyObjects(1);
-        super.finalize();
-    }
-}
--- a/test/jdk/sun/rmi/rmic/newrmic/equivalence/NotActivatableInterface.java	Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * 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.
- */
-
-// RMI Activation Functional Test
-
-// NotActivatableInterface
-
-public interface NotActivatableInterface extends java.rmi.Remote {
-
-    public void ping() throws java.rmi.RemoteException;
-
-    public void exit() throws java.rmi.RemoteException;
-}
--- a/test/jdk/sun/rmi/rmic/newrmic/equivalence/NotActivatableServerImpl.java	Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,99 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * 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.
- */
-
-// RMI Activation Functional Test
-
-import java.rmi.*;
-import java.rmi.activation.*;
-import java.rmi.server.*;
-import java.util.*;
-
-// NotActivatableServerImpl
-
-public class NotActivatableServerImpl
-    extends UnicastRemoteObject
-    implements NotActivatableInterface {
-
-    private static final String PROG_NAME       = "NotActivatableServerImpl";
-    private static final String SERVER_OBJECT   = "NotActivatableServer";
-    private static final String CLASS_NAME      = "activation.NotActivatableServerImpl";
-
-    private static final String POLICY_FILE   = "policy_file";
-
-    private static final String USER_DIR      =
-                        System.getProperty("user.dir").replace('\\', '/');
-
-    private static final String CODE_LOCATION = "file:"+USER_DIR+"/";
-
-    private static final MarshalledObject DATA = null;
-    private static ActivationDesc ACTIVATION_DESC = null;
-
-    public NotActivatableServerImpl() throws RemoteException {}
-
-    public void ping() throws RemoteException {}
-
-    public void exit() throws RemoteException {
-        System.exit(0);
-    }
-
-    private static void setup() {
-
-        try {
-
-          NotActivatableInterface rsi;  // Remote server interface
-
-          System.setSecurityManager(new RMISecurityManager());
-
-          rsi = (NotActivatableInterface)Activatable.register(ACTIVATION_DESC);
-          System.out.println("Got stub for "+SERVER_OBJECT+" implementation");
-
-          Naming.rebind(SERVER_OBJECT, rsi);
-          System.out.println("Exported "+SERVER_OBJECT+" implementation");
-
-        } catch (Exception e) {
-            System.err.println("Exception: " + e);
-            e.printStackTrace();
-        }
-    }
-
-    public static void main(String[] args) {
-
-        try {
-            Properties props = new Properties();
-            props.setProperty("java.security.policy", POLICY_FILE);
-
-            ActivationGroupDesc agd = new ActivationGroupDesc(props, null);
-
-            ActivationGroupID agid = ActivationGroup.getSystem().registerGroup(agd);
-
-            ACTIVATION_DESC = new ActivationDesc(agid,
-                        CLASS_NAME, CODE_LOCATION, DATA, false);
-        }
-        catch (Exception e) {
-            System.err.println("Exception: " + e);
-            e.printStackTrace();
-        }
-
-        setup();
-    }
-}
--- a/test/jdk/sun/rmi/rmic/newrmic/equivalence/Orange.java	Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-public interface Orange extends java.rmi.Remote {
-
-    public int[] recurse(OrangeEcho echo, int[] message, int level)
-        throws java.rmi.RemoteException;
-}
--- a/test/jdk/sun/rmi/rmic/newrmic/equivalence/OrangeEcho.java	Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-public interface OrangeEcho extends java.rmi.Remote {
-
-    public int[] recurse(Orange orange, int[] message, int level)
-        throws java.rmi.RemoteException;
-}
--- a/test/jdk/sun/rmi/rmic/newrmic/equivalence/OrangeEchoImpl.java	Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,73 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * 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.rmi.RemoteException;
-import java.rmi.server.UnicastRemoteObject;
-import java.util.logging.Logger;
-import java.util.logging.Level;
-
-/**
- * The OrangeEchoImpl class implements the behavior of the remote "orange
- * echo" objects exported by the server.  The purpose of these objects
- * is simply to recursively call back to their caller.
- */
-public class OrangeEchoImpl
-    extends UnicastRemoteObject
-    implements OrangeEcho
-{
-
-    private static Logger logger = Logger.getLogger("reliability.orangeecho");
-    String name;
-
-    public OrangeEchoImpl(String name) throws RemoteException {
-        this.name = name;
-    }
-
-    /**
-     * Call back on supplied "orange" object (presumably the caller)
-     * with the same message data and a decremented recursion level.
-     */
-    public int[] recurse(Orange orange, int[] message, int level)
-        throws RemoteException
-    {
-        String threadName = Thread.currentThread().getName();
-
-        logger.log(Level.FINEST,
-            threadName + ": " + toString() +
-            ".recurse(message[" + message.length + "], " +
-            level + "): BEGIN");
-
-        int[] response = orange.recurse(this, message, level - 1);
-
-        logger.log(Level.FINEST,
-            threadName + ": " + toString() +
-            ".recurse(message[" + message.length + "], " +
-            level + "): END");
-
-        return response;
-    }
-
-    public String toString() {
-        return name;
-    }
-}
--- a/test/jdk/sun/rmi/rmic/newrmic/equivalence/OrangeImpl.java	Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * 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.rmi.RemoteException;
-import java.rmi.server.UnicastRemoteObject;
-import java.util.logging.Logger;
-import java.util.logging.Level;
-
-/**
- * The OrangeImpl class implements the behavior of the remote "orange"
- * objects exported by the appplication.
- */
-public class OrangeImpl
-    extends UnicastRemoteObject
-    implements Orange
-{
-
-    private static Logger logger = Logger.getLogger("reliability.orange");
-    private String name;
-
-    public OrangeImpl(String name) throws RemoteException {
-        this.name = name;
-    }
-
-    /**
-     * Return inverted message data, call through supplied OrangeEcho
-     * object if not at recursion level zero.
-     */
-    public int[] recurse(OrangeEcho echo, int[] message, int level)
-        throws RemoteException
-    {
-        try {
-            String threadName = Thread.currentThread().getName();
-            logger.log(Level.FINEST,
-                threadName + ": " + toString() +
-                ".recurse(message[" + message.length + "], " +
-                level + "): BEGIN");
-
-            int[] response;
-            if (level > 0)
-                response = echo.recurse(this, message, level);
-            else {
-                for (int i = 0; i < message.length; ++ i)
-                    message[i] = ~message[i];
-                response = message;
-            }
-
-            logger.log(Level.FINEST,
-                threadName + ": " + toString() +
-                ".recurse(message[" + message.length + "], " +
-                level + "): END");
-
-            return response;
-        } catch (RuntimeException e) {
-            logger.log(Level.SEVERE, toString() + ".recurse():", e);
-            throw e;
-        }
-    }
-
-    public String toString() {
-        return name;
-    }
-}
--- a/test/jdk/sun/rmi/rmic/newrmic/equivalence/Server.java	Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * 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.rmi.*;
-import java.rmi.registry.*;
-import java.rmi.server.*;
-
-
-
-public interface Server extends Remote
-{
-        public String sayHello(Callback c) throws RemoteException;
-}
--- a/test/jdk/sun/rmi/rmic/newrmic/equivalence/ServerImpl.java	Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,79 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * 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.*;
-import java.rmi.*;
-import java.rmi.server.UnicastRemoteObject;
-
-public class ServerImpl
-    extends UnicastRemoteObject
-    implements Server
-{
-    private String name;
-    Callback cLocal;
-
-    public ServerImpl(String s) throws java.rmi.RemoteException {
-        super();
-        name = s;
-    }
-
-    public String sayHello(Callback c) throws RemoteException {
-        System.out.println("Calling Callback method from the ServerImpl");
-        cLocal = c;
-        new Thread(new Runnable() {
-            public void run() {
-                System.out.println(
-                    "+ running a new thread in sayHello method!");
-                try {
-                    cLocal.callback();
-                } catch(RemoteException e) {
-                    System.out.println(
-                        "ServerImpl.main: exception while calling callback " +
-                        "method:");
-                    e.printStackTrace();
-                }
-            }
-        }).start();
-        return "Hello Callback!";
-    }
-
-    public static void main(String args[]) {
-        // Create and install the security manager
-        System.setSecurityManager(new RMISecurityManager());
-
-        ServerImpl obj = null;
-
-        try {
-            obj = new ServerImpl("ServerImpl");
-            Naming.rebind("/ServerImpl", obj);
-            System.out.println("ServerImpl created and bound in the registry" +
-                " to the name ServerImpl");
-            System.err.println("DTI_DoneInitializing");
-        } catch (Exception e) {
-            System.out.println("ServerImpl.main: an exception occurred:");
-            e.printStackTrace();
-            System.err.println("DTI_Error");
-        }
-
-    }
-}
--- a/test/jdk/sun/rmi/rmic/newrmic/equivalence/Task.java	Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * 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.
- */
-
-/**
- * Interface Task that must be serializable so that the task can be
- * passed to the compute server.
- */
-public interface Task extends java.io.Serializable {
-
-    /**
-     * Called by compute server and returns an object.
-     */
-    Object run();
-}
--- a/test/jdk/sun/rmi/rmic/newrmic/equivalence/TestInterface.java	Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * 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.
- */
-
-// RMI Activation Functional Test
-
-import java.rmi.*;
-import java.rmi.activation.*;
-
-// TestInterface
-
-public interface TestInterface extends Remote {
-
-    public void ping(String s) throws RemoteException;
-}
--- a/test/jdk/sun/rmi/rmic/newrmic/equivalence/batch.sh	Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,91 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
-# 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.
-#
-
-#
-# Usage: batch.sh classpath classes...
-#
-
-if [ $# -lt 2 ]
-then
-    echo "Usage: `basename $0` classpath classes..."
-    exit 1
-fi
-
-if [ "${TESTJAVA}" = "" ]
-then
-    echo "TESTJAVA not set.  Test cannot execute.  Failed."
-    exit 1
-fi
-
-refv11dir=./ref-v1.1-output
-refvcompatdir=./ref-vcompat-output
-refv12dir=./ref-v1.2-output
-
-newv11dir=./new-v1.1-output
-newvcompatdir=./new-vcompat-output
-newv12dir=./new-v1.2-output
-
-v11diffs=./diffs-v1.1
-vcompatdiffs=./diffs-vcompat
-v12diffs=./diffs-v1.2
-
-difflines=./diff-lines
-
-rm -rf $refv11dir $refvcompatdir $refv12dir
-rm -rf $newv11dir $newvcompatdir $newv12dir
-rm -f $v11diffs $vcompatdiffs $v12diffs $difflines
-
-mkdir $refv11dir $refvcompatdir $refv12dir
-mkdir $newv11dir $newvcompatdir $newv12dir
-
-set -ex
-
-${TESTJAVA}/bin/rmic       -keep -nowrite -v1.1 -d $refv11dir -classpath "$@"
-${TESTJAVA}/bin/rmic       -keep -nowrite -vcompat -d $refvcompatdir -classpath "$@"
-${TESTJAVA}/bin/rmic       -keep -nowrite -v1.2 -d $refv12dir -classpath "$@"
-
-${TESTJAVA}/bin/rmic -Xnew -keep -nowrite -v1.1 -d $newv11dir -classpath "$@"
-${TESTJAVA}/bin/rmic -Xnew -keep -nowrite -vcompat -d $newvcompatdir -classpath "$@"
-${TESTJAVA}/bin/rmic -Xnew -keep -nowrite -v1.2 -d $newv12dir -classpath "$@"
-
-set +ex
-
-diff -r $refv11dir $newv11dir > $v11diffs
-diff -r $refvcompatdir $newvcompatdir > $vcompatdiffs
-diff -r $refv12dir $newv12dir > $v12diffs
-
-cat $v11diffs $vcompatdiffs $v12diffs | grep '^[<>O]' | fgrep -v ' server = (' > $difflines
-
-if [ `cat $difflines | wc -l` -gt 0 ]
-then
-    cat $v11diffs $vcompatdiffs $v12diffs
-    echo "TEST FAILED: unexpected diffs"
-    exit 1
-fi
-
-echo "TEST PASSED: new rmic output identical to reference rmic output"
-
-rm -rf $refv11dir $refvcompatdir $refv12dir
-rm -rf $newv11dir $newvcompatdir $newv12dir
-rm -f $v11diffs $vcompatdiffs $v12diffs $difflines
--- a/test/jdk/sun/rmi/rmic/newrmic/equivalence/run.sh	Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,86 +0,0 @@
-#
-# Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-
-# @test
-# @ignore test is disabled, while further discussion on the rmic -Xnew feature
-# takes place (c.f JDK-8146299, JDK-8145980).
-# @bug 4911536
-# @summary This test verifies that the new implementation of rmic
-# generates equivalent classes as the old implementation, for a set
-# of sample input classes.
-# @author Peter Jones
-#
-# @library ../../../../../java/rmi/testlibrary
-#
-# @build TestLibrary
-#     AgentServerImpl
-#     AppleImpl
-#     AppleUserImpl
-#     ComputeServerImpl
-#     CountServerImpl
-#     DayTimeServerImpl
-#     G1Impl
-#     MyObjectImpl
-#     NotActivatableServerImpl
-#     OrangeEchoImpl
-#     OrangeImpl
-#     ServerImpl
-#
-# @run shell run.sh
-
-if [ "${TESTJAVA}" = "" ]
-then
-    echo "TESTJAVA not set.  Test cannot execute.  Failed."
-    exit 1
-fi
-
-set -ex
-
-#
-# miscellaneous remote classes collected from other tests
-#
-
-sh ${TESTSRC:-.}/batch.sh ${TESTCLASSES:-.} \
-	AgentServerImpl \
-	AppleImpl \
-	AppleUserImpl \
-	ComputeServerImpl \
-	CountServerImpl \
-	DayTimeServerImpl \
-	G1Impl \
-	MyObjectImpl \
-	NotActivatableServerImpl \
-	OrangeEchoImpl \
-	OrangeImpl \
-	ServerImpl
-
-#
-# remote classes in the J2SE implementation
-#
-
-sh ${TESTSRC:-.}/batch.sh ${TESTCLASSES:-.} \
-	sun.rmi.registry.RegistryImpl \
-	sun.rmi.server.Activation\$ActivationMonitorImpl \
-	sun.rmi.server.Activation\$ActivationSystemImpl \
-	sun.rmi.server.Activation\$ActivatorImpl \
-	java.rmi.activation.ActivationGroup
--- a/test/jdk/tools/jlink/plugins/SystemModuleDescriptors/src/m1/p1/Main.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/test/jdk/tools/jlink/plugins/SystemModuleDescriptors/src/m1/p1/Main.java	Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -34,35 +34,13 @@
 import java.util.Collections;
 import java.util.Set;
 
-import jdk.internal.module.ClassFileAttributes;
-import jdk.internal.module.ClassFileAttributes.ModuleTargetAttribute;
-import jdk.internal.module.ClassFileConstants;
-import jdk.internal.org.objectweb.asm.Attribute;
-import jdk.internal.org.objectweb.asm.ClassReader;
-import jdk.internal.org.objectweb.asm.ClassVisitor;
-import jdk.internal.org.objectweb.asm.Opcodes;
+import jdk.internal.module.ModuleInfo;
+import jdk.internal.module.ModuleInfo.Attributes;
 
 public class Main {
     private static boolean hasModuleTarget(InputStream in) throws IOException {
-        ModuleTargetAttribute[] modTargets = new ModuleTargetAttribute[1];
-        ClassVisitor cv = new ClassVisitor(Opcodes.ASM5) {
-            @Override
-            public void visitAttribute(Attribute attr) {
-                if (attr instanceof ModuleTargetAttribute) {
-                    modTargets[0] = (ModuleTargetAttribute)attr;
-                }
-            }
-        };
-
-        // prototype of attributes that should be parsed
-        Attribute[] attrs = new Attribute[] {
-            new ModuleTargetAttribute()
-        };
-
-        // parse module-info.class
-        ClassReader cr = new ClassReader(in);
-        cr.accept(cv, attrs, 0);
-        return modTargets[0] != null && modTargets[0].targetPlatform() != null;
+        ModuleInfo.Attributes attrs = ModuleInfo.read(in, null);
+        return attrs.target() != null;
     }
 
     public static void main(String... args) throws Exception {
--- a/test/jdk/tools/jlink/plugins/SystemModuleDescriptors/src/m4/p4/Main.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/test/jdk/tools/jlink/plugins/SystemModuleDescriptors/src/m4/p4/Main.java	Wed Nov 08 16:03:35 2017 -0500
@@ -35,35 +35,13 @@
 import java.util.Map;
 import java.util.Set;
 
-import jdk.internal.module.ClassFileAttributes;
-import jdk.internal.module.ClassFileAttributes.ModuleTargetAttribute;
-import jdk.internal.module.ClassFileConstants;
-import jdk.internal.org.objectweb.asm.Attribute;
-import jdk.internal.org.objectweb.asm.ClassReader;
-import jdk.internal.org.objectweb.asm.ClassVisitor;
-import jdk.internal.org.objectweb.asm.Opcodes;
+import jdk.internal.module.ModuleInfo;
+import jdk.internal.module.ModuleInfo.Attributes;
 
 public class Main {
     private static boolean hasModuleTarget(InputStream in) throws IOException {
-        ModuleTargetAttribute[] modTargets = new ModuleTargetAttribute[1];
-        ClassVisitor cv = new ClassVisitor(Opcodes.ASM5) {
-            @Override
-            public void visitAttribute(Attribute attr) {
-                if (attr instanceof ModuleTargetAttribute) {
-                    modTargets[0] = (ModuleTargetAttribute)attr;
-                }
-            }
-        };
-
-        // prototype of attributes that should be parsed
-        Attribute[] attrs = new Attribute[] {
-            new ModuleTargetAttribute()
-        };
-
-        // parse module-info.class
-        ClassReader cr = new ClassReader(in);
-        cr.accept(cv, attrs, 0);
-        return modTargets[0] != null && modTargets[0].targetPlatform() != null;
+        ModuleInfo.Attributes attrs = ModuleInfo.read(in, null);
+        return attrs.target() != null;
     }
 
     private static boolean hasModuleTarget(String modName) throws IOException {
--- a/test/langtools/jdk/jshell/MethodsTest.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/test/langtools/jdk/jshell/MethodsTest.java	Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8080357 8167643
+ * @bug 8080357 8167643 8187359
  * @summary Tests for EvaluationState.methods
  * @build KullaTesting TestingInputStream ExpectedDiagnostic
  * @run testng MethodsTest
@@ -230,6 +230,24 @@
         assertActiveKeys();
     }
 
+    public void objectMethodNamedMethodsErrors() {
+        assertDeclareFail("boolean equals(double d1, double d2) {  return d1 == d2; }",
+                new ExpectedDiagnostic("jdk.eval.error.object.method", 8, 14, 8, -1, -1, Diagnostic.Kind.ERROR));
+        assertNumberOfActiveMethods(0);
+        assertActiveKeys();
+
+        assertDeclareFail("void          wait() { }",
+                new ExpectedDiagnostic("jdk.eval.error.object.method", 14, 18, 14, -1, -1, Diagnostic.Kind.ERROR));
+        assertNumberOfActiveMethods(0);
+        assertActiveKeys();
+
+        assertDeclareFail("  String   toString() throws NullPointerException{ }",
+                new ExpectedDiagnostic("jdk.eval.error.object.method", 11, 19, 11, -1, -1, Diagnostic.Kind.ERROR));
+        assertNumberOfActiveMethods(0);
+        assertActiveKeys();
+
+    }
+
 
     public void methodsAccessModifierIgnored() {
         Snippet f = methodKey(assertEval("public String f() {return null;}",
--- a/test/langtools/jdk/jshell/StartOptionTest.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/test/langtools/jdk/jshell/StartOptionTest.java	Wed Nov 08 16:03:35 2017 -0500
@@ -22,7 +22,7 @@
  */
 
 /*
- * @test 8151754 8080883 8160089 8170162 8166581 8172102 8171343 8178023
+ * @test 8151754 8080883 8160089 8170162 8166581 8172102 8171343 8178023 8186708 8179856
  * @summary Testing start-up options.
  * @modules jdk.compiler/com.sun.tools.javac.api
  *          jdk.compiler/com.sun.tools.javac.main
@@ -147,7 +147,7 @@
         for (String opt : new String[]{"-h", "--help"}) {
             start(s -> {
                 assertTrue(s.split("\n").length >= 7, "Not enough usage lines: " + s);
-                assertTrue(s.startsWith("Usage:   jshell <options>"), "Unexpect usage start: " + s);
+                assertTrue(s.startsWith("Usage:   jshell <option>..."), "Unexpect usage start: " + s);
                 assertTrue(s.contains("--show-version"), "Expected help: " + s);
                 assertFalse(s.contains("Welcome"), "Unexpected start: " + s);
             }, null, null, opt);
@@ -172,6 +172,38 @@
               s -> assertEquals(s.trim(), "Unknown option: unknown"), "--unknown");
     }
 
+    /**
+     * Test that input is read with "-" and there is no extra output.
+     * @throws Exception
+     */
+    public void testHypenFile() throws Exception {
+        cmdInStream = new ByteArrayInputStream("System.out.print(\"Hello\");\n".getBytes());
+        startWithUserOutput("", "Hello", "", "-");
+        cmdInStream = new ByteArrayInputStream("System.out.print(\"Hello\");\n".getBytes());
+        startWithUserOutput("", "Hello", "", "-", "-");
+        Compiler compiler = new Compiler();
+        Path path = compiler.getPath("markload.jsh");
+        compiler.writeToFile(path, "System.out.print(\"===\");");
+        cmdInStream = new ByteArrayInputStream("System.out.print(\"Hello\");\n".getBytes());
+        startWithUserOutput("", "===Hello===", "", path.toString(), "-", path.toString());
+        // check that errors go to standard error
+        cmdInStream = new ByteArrayInputStream(") Foobar".getBytes());
+        start(
+                s -> assertEquals(s.trim(), "", "cmdout: empty"),
+                s -> assertEquals(s.trim(), "", "userout: empty"),
+                s -> assertTrue(s.contains("illegal start of expression"),
+                            "cmderr: illegal start of expression"),
+                "-");
+    }
+
+    /**
+     * Test that non-existent load file sends output to stderr and does not start (no welcome).
+     * @throws Exception
+     */
+    public void testUnknownLoadFile() throws Exception {
+        start("", "File 'UNKNOWN' for 'jshell' is not found.", "UNKNOWN");
+    }
+
     public void testStartup() throws Exception {
         Compiler compiler = new Compiler();
         Path p = compiler.getPath("file.txt");
--- a/test/langtools/jdk/jshell/ToolBasicTest.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/test/langtools/jdk/jshell/ToolBasicTest.java	Wed Nov 08 16:03:35 2017 -0500
@@ -45,7 +45,6 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
-import java.util.Locale;
 import java.util.Scanner;
 import java.util.function.BiFunction;
 import java.util.function.Consumer;
@@ -408,10 +407,6 @@
                 (a) -> assertCommand(a, "x", "x ==> 20.0"),
                 (a) -> assertCommand(a, "a", "a ==> 10.0")
         );
-        Path unknown = compiler.getPath("UNKNOWN.jar");
-        test(Locale.ROOT, true, new String[]{unknown.toString()},
-                "|  File '" + unknown
-                + "' for 'jshell' is not found.");
     }
 
     public void testReset() {
--- a/test/langtools/jdk/jshell/ToolProviderTest.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/test/langtools/jdk/jshell/ToolProviderTest.java	Wed Nov 08 16:03:35 2017 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,7 @@
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.InputStream;
+import java.nio.file.Path;
 import java.util.ServiceLoader;
 import java.util.function.Consumer;
 import javax.tools.Tool;
@@ -34,7 +35,7 @@
 
 /*
  * @test
- * @bug 8170044 8171343
+ * @bug 8170044 8171343 8179856
  * @summary Test ServiceLoader launching of jshell tool
  * @modules jdk.compiler/com.sun.tools.javac.api
  *          jdk.compiler/com.sun.tools.javac.main
@@ -97,4 +98,21 @@
                 null, null,
                 "--show-version");
     }
+    /**
+     * Test that input is read with "-" and there is no extra output.
+     * @throws Exception
+     */
+    @Override
+    public void testHypenFile() throws Exception {
+        cmdInStream = new ByteArrayInputStream("System.out.print(\"Hello\");\n".getBytes());
+        start("Hello", "", "-");
+        cmdInStream = new ByteArrayInputStream("System.out.print(\"Hello\");\n".getBytes());
+        start("Hello", "", "-", "-");
+        Compiler compiler = new Compiler();
+        Path path = compiler.getPath("markload.jsh");
+        compiler.writeToFile(path, "System.out.print(\"===\");");
+        cmdInStream = new ByteArrayInputStream("System.out.print(\"Hello\");\n".getBytes());
+        start("===Hello===", "", path.toString(), "-", path.toString());
+    }
+
 }
--- a/test/langtools/jdk/jshell/ToolTabCommandTest.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/test/langtools/jdk/jshell/ToolTabCommandTest.java	Wed Nov 08 16:03:35 2017 -0500
@@ -84,10 +84,6 @@
             inputSink.write("\u0003/env \011");
             waitOutput(out, "\u0005/env -\n" +
                             "-add-exports    -add-modules    -class-path     -module-path    \n" +
-                            "\r\u0005/env -");
-
-            inputSink.write("\011");
-            waitOutput(out, "-add-exports    -add-modules    -class-path     -module-path    \n" +
                             "\n" +
                             Pattern.quote(getResource("jshell.console.see.synopsis")) + "\n" +
                             "\r\u0005/env -");
--- a/test/langtools/jdk/jshell/ToolTabSnippetTest.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/test/langtools/jdk/jshell/ToolTabSnippetTest.java	Wed Nov 08 16:03:35 2017 -0500
@@ -23,7 +23,7 @@
 
 /**
  * @test
- * @bug 8177076 8185426
+ * @bug 8177076 8185426 8189595 8188072
  * @modules
  *     jdk.compiler/com.sun.tools.javac.api
  *     jdk.compiler/com.sun.tools.javac.main
@@ -191,6 +191,10 @@
             //no crash:
             inputSink.write("\u0003new Stringbuil\011");
             waitOutput(out, "\u0005new Stringbuil\u0007");
+
+            //no crash: 8188072
+            inputSink.write("\u0003for (int:\011");
+            waitOutput(out, "\u0005for \\(int:\u0007");
         });
     }
 
@@ -227,6 +231,31 @@
         });
     }
 
+    public void testNoRepeat() throws Exception {
+        doRunTest((inputSink, out) -> {
+            inputSink.write("String xyzAA;\n");
+            waitOutput(out, "\u0005");
+
+            //xyz<tab>
+            inputSink.write("String s = xyz\011");
+            waitOutput(out, "^String s = xyzAA");
+            inputSink.write(".");
+            waitOutput(out, "^\\.");
+
+            inputSink.write("\u0003");
+            waitOutput(out, "\u0005");
+
+            inputSink.write("double xyzAB;\n");
+            waitOutput(out, "\u0005");
+
+            //xyz<tab>
+            inputSink.write("String s = xyz\011");
+            String allCompletions =
+                    Pattern.quote(getResource("jshell.console.completion.all.completions"));
+            waitOutput(out, ".*xyzAA.*" + allCompletions + ".*\u0005String s = xyzA");
+        });
+    }
+
     private Path prepareZip() {
         String clazz1 =
                 "package jshelltest;\n" +
--- a/test/langtools/tools/javac/diags/examples/PatchModuleWithRelease/PatchModuleWithRelease.java	Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +0,0 @@
-/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
- * 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.
- */
-
-// key: compiler.err.patch.module.with.release
-// options: --release 9
-
-class PatchModuleWithRelease {
-}
--- a/test/langtools/tools/javac/diags/examples/PatchModuleWithRelease/patchmodule/java.base/java/lang/Test.java	Mon Nov 06 19:45:47 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.lang;
-
-class Test {
-}
--- a/test/langtools/tools/javac/options/release/ReleaseOptionUnsupported.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/test/langtools/tools/javac/options/release/ReleaseOptionUnsupported.java	Wed Nov 08 16:03:35 2017 -0500
@@ -23,7 +23,7 @@
 
 /**
  * @test
- * @bug 8178152
+ * @bug 8178152 8187681
  * @summary Verify unsupported modules and module options handling.
  * @library /tools/lib
  * @modules jdk.compiler/com.sun.tools.javac.api
@@ -263,35 +263,19 @@
         tb.createDirectories(patch);
 
         new JavacTask(tb)
-                .options("-XDrawDiagnostics",
-                         "--patch-module", "java.base=" + patch)
+                .options("--patch-module", "java.base=" + patch)
                 .outdir(classes)
                 .files(tb.findJavaFiles(src))
                 .run(Expect.SUCCESS)
-                .writeAll()
-                .getOutputLines(Task.OutputKind.DIRECT);
+                .writeAll();
 
-        List<String> log;
-        List<String> expected;
-
-        log = new JavacTask(tb)
-                .options("-XDrawDiagnostics",
-                         "--patch-module", "java.base=" + patch,
+        new JavacTask(tb)
+                .options("--patch-module", "java.base=" + patch,
                          "--release", Target.DEFAULT.multiReleaseValue())
                 .outdir(classes)
                 .files(tb.findJavaFiles(src))
-                .run(Expect.FAIL)
-                .writeAll()
-                .getOutputLines(Task.OutputKind.DIRECT);
-
-        expected = Arrays.asList(
-                "- compiler.err.patch.module.with.release: java.base",
-                "1 error"
-        );
-
-        if (!expected.equals(log)) {
-            throw new AssertionError("Unexpected output: " + log);
-        }
+                .run(Expect.SUCCESS)
+                .writeAll();
 
         //OK to patch a non-system module:
         tb.createDirectories(classes);
--- a/test/langtools/tools/javac/tree/NoPrivateTypesExported.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/test/langtools/tools/javac/tree/NoPrivateTypesExported.java	Wed Nov 08 16:03:35 2017 -0500
@@ -206,6 +206,33 @@
                 }
                 return null;
             }
+            @Override public Void visitBoolean(boolean b, Void p) {
+                return null;
+            }
+            @Override public Void visitByte(byte b, Void p) {
+                return null;
+            }
+            @Override public Void visitChar(char c, Void p) {
+                return null;
+            }
+            @Override public Void visitDouble(double d, Void p) {
+                return null;
+            }
+            @Override public Void visitFloat(float f, Void p) {
+                return null;
+            }
+            @Override public Void visitInt(int i, Void p) {
+                return null;
+            }
+            @Override public Void visitLong(long i, Void p) {
+                return null;
+            }
+            @Override public Void visitShort(short s, Void p) {
+                return null;
+            }
+            @Override public Void visitString(String s, Void p) {
+                return null;
+            }
             @Override protected Void defaultAction(Object o, Void p) {
                 error("Unexpected AnnotationValue: " + o.toString());
                 return super.defaultAction(o, p);
--- a/test/lib/sun/hotspot/WhiteBox.java	Mon Nov 06 19:45:47 2017 +0100
+++ b/test/lib/sun/hotspot/WhiteBox.java	Wed Nov 08 16:03:35 2017 -0500
@@ -525,6 +525,7 @@
   public native boolean areSharedStringsIgnored();
   public native boolean isCDSIncludedInVmBuild();
   public native Object  getResolvedReferences(Class<?> c);
+  public native boolean areOpenArchiveHeapObjectsMapped();
 
   // Compiler Directive
   public native int addCompilerDirective(String compDirect);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/nashorn/script/basic/JDK-8190698.js	Wed Nov 08 16:03:35 2017 -0500
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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-8190698: jjs tool of jdk.scripting.nashorn.shell module should not statically depend on java.desktop
+ *
+ * @test
+ * @run
+ */
+
+var optJjsMod = java.lang.ModuleLayer.boot().findModule("jdk.scripting.nashorn.shell");
+
+// make sure that the module exists!
+Assert.assertTrue(optJjsMod.isPresent());
+
+// jdk.scripting.nashorn.shell should not have java.desktop dependency
+var javaDesktopDependency = optJjsMod.get().
+        descriptor.requires().
+        stream().
+        filter(function(mod) { return mod.name() == "java.desktop" }).
+        findFirst();
+
+Assert.assertTrue(!javaDesktopDependency.isPresent());