changeset 47813:fedbf1b866a7

Merge
author coleenp
date Wed, 08 Nov 2017 16:03:35 -0500
parents b140fe4ff916 d76a6042f5d7
children 19fad4c04a15
files 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
diffstat 576 files changed, 14862 insertions(+), 15613 deletions(-) [+]
line wrap: on
line diff
--- 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);
 
-        // for tests: write the ModulePackages attribute when there are packages
-        // that aren't exported or open
+        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);
+        }
+
+        // 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