changeset 47425:194bc551c790 lambda-leftovers

Automatic merge with default
author mcimadamore
date Thu, 12 Oct 2017 22:05:47 +0200
parents 49f3d98e086a b87d7b5d5ded
children 8f62c5ed3f6f
files make/corba/Makefile src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java
diffstat 38 files changed, 1165 insertions(+), 288 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Thu Oct 05 22:05:22 2017 +0200
+++ b/.hgtags	Thu Oct 12 22:05:47 2017 +0200
@@ -450,3 +450,4 @@
 22850b3a55240253841b9a425ad60a7fcdb22d47 jdk-10+23
 3b201865d5c1f244f555cad58da599c9261286d8 jdk-10+24
 8eb5e3ccee560c28ac9b1df2670adac2b3d36fad jdk-10+25
+1129253d3bc728a2963ba411ab9dd1adf358fb6b jdk-10+26
--- a/bin/jib.sh	Thu Oct 05 22:05:22 2017 +0200
+++ b/bin/jib.sh	Thu Oct 12 22:05:47 2017 +0200
@@ -39,7 +39,7 @@
     jib_repository="jdk-virtual"
     jib_organization="jpg/infra/builddeps"
     jib_module="jib"
-    jib_revision="2.0-SNAPSHOT"
+    jib_revision="3.0-SNAPSHOT"
     jib_ext="jib.sh.gz"
 
     closed_script="${mydir}/../../closed/make/conf/jib-install.conf"
@@ -146,4 +146,9 @@
     install_jib
 fi
 
+# Provide a reasonable default for the --src-dir parameter if run out of tree
+if [ -z "${JIB_SRC_DIR}" ]; then
+    export JIB_SRC_DIR="${mydir}/../"
+fi
+
 ${installed_jib_script} "$@"
--- a/make/RunTests.gmk	Thu Oct 05 22:05:22 2017 +0200
+++ b/make/RunTests.gmk	Thu Oct 12 22:05:47 2017 +0200
@@ -351,6 +351,9 @@
 
   $1_JTREG_BASIC_OPTIONS += -automatic -keywords:\!ignore -ignore:quiet
 
+  # Make it possible to specify the JIB_DATA_DIR for tests using the
+  # JIB Artifact resolver
+  $1_JTREG_BASIC_OPTIONS += -e:JIB_DATA_DIR
   # Some tests needs to find a boot JDK using the JDK8_HOME variable.
   $1_JTREG_BASIC_OPTIONS += -e:JDK8_HOME=$$(BOOT_JDK)
 
--- a/make/autoconf/boot-jdk.m4	Thu Oct 05 22:05:22 2017 +0200
+++ b/make/autoconf/boot-jdk.m4	Thu Oct 12 22:05:47 2017 +0200
@@ -325,6 +325,27 @@
   fi
   AC_MSG_CHECKING([if Boot JDK is 32 or 64 bits])
   AC_MSG_RESULT([$BOOT_JDK_BITS])
+
+  # Try to enable CDS
+  AC_MSG_CHECKING([for local Boot JDK Class Data Sharing (CDS)])
+  BOOT_JDK_CDS_ARCHIVE=$CONFIGURESUPPORT_OUTPUTDIR/classes.jsa
+  ADD_JVM_ARG_IF_OK([-XX:+UnlockDiagnosticVMOptions -XX:-VerifySharedSpaces -XX:SharedArchiveFile=$BOOT_JDK_CDS_ARCHIVE],boot_jdk_cds_args,[$JAVA])
+
+  if test "x$boot_jdk_cds_args" != x; then
+    # Try creating a CDS archive
+    "$JAVA" $boot_jdk_cds_args -Xshare:dump > /dev/null 2>&1
+    if test $? -eq 0; then
+      BOOTJDK_USE_LOCAL_CDS=true
+      AC_MSG_RESULT([yes, created])
+    else
+      # Generation failed, don't use CDS.
+      BOOTJDK_USE_LOCAL_CDS=false
+      AC_MSG_RESULT([no, creation failed])
+    fi
+  else
+    BOOTJDK_USE_LOCAL_CDS=false
+    AC_MSG_RESULT([no, -XX:SharedArchiveFile not supported])
+  fi
 ])
 
 AC_DEFUN_ONCE([BOOTJDK_SETUP_BOOT_JDK_ARGUMENTS],
@@ -346,6 +367,14 @@
   # Force en-US environment
   ADD_JVM_ARG_IF_OK([-Duser.language=en -Duser.country=US],boot_jdk_jvmargs,[$JAVA])
 
+  if test "x$BOOTJDK_USE_LOCAL_CDS" = xtrue; then
+    # Use our own CDS archive
+    ADD_JVM_ARG_IF_OK([$boot_jdk_cds_args -Xshare:auto],boot_jdk_jvmargs,[$JAVA])
+  else
+    # Otherwise optimistically use the system-wide one, if one is present
+    ADD_JVM_ARG_IF_OK([-Xshare:auto],boot_jdk_jvmargs,[$JAVA])
+  fi
+
   # Apply user provided options.
   ADD_JVM_ARG_IF_OK([$with_boot_jdk_jvmargs],boot_jdk_jvmargs,[$JAVA])
 
@@ -355,7 +384,6 @@
   JAVA_FLAGS=$boot_jdk_jvmargs
   AC_SUBST(JAVA_FLAGS)
 
-
   AC_MSG_CHECKING([flags for boot jdk java command for big workloads])
 
   # Starting amount of heap memory.
--- a/make/autoconf/generated-configure.sh	Thu Oct 05 22:05:22 2017 +0200
+++ b/make/autoconf/generated-configure.sh	Thu Oct 12 22:05:47 2017 +0200
@@ -5117,7 +5117,7 @@
 #CUSTOM_AUTOCONF_INCLUDE
 
 # Do not change or remove the following line, it is needed for consistency checks:
-DATE_WHEN_GENERATED=1506397140
+DATE_WHEN_GENERATED=1507635096
 
 ###############################################################################
 #
@@ -31483,6 +31483,45 @@
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: $BOOT_JDK_BITS" >&5
 $as_echo "$BOOT_JDK_BITS" >&6; }
 
+  # Try to enable CDS
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for local Boot JDK Class Data Sharing (CDS)" >&5
+$as_echo_n "checking for local Boot JDK Class Data Sharing (CDS)... " >&6; }
+  BOOT_JDK_CDS_ARCHIVE=$CONFIGURESUPPORT_OUTPUTDIR/classes.jsa
+
+  $ECHO "Check if jvm arg is ok: -XX:+UnlockDiagnosticVMOptions -XX:-VerifySharedSpaces -XX:SharedArchiveFile=$BOOT_JDK_CDS_ARCHIVE" >&5
+  $ECHO "Command: $JAVA -XX:+UnlockDiagnosticVMOptions -XX:-VerifySharedSpaces -XX:SharedArchiveFile=$BOOT_JDK_CDS_ARCHIVE -version" >&5
+  OUTPUT=`$JAVA -XX:+UnlockDiagnosticVMOptions -XX:-VerifySharedSpaces -XX:SharedArchiveFile=$BOOT_JDK_CDS_ARCHIVE -version 2>&1`
+  FOUND_WARN=`$ECHO "$OUTPUT" | $GREP -i warn`
+  FOUND_VERSION=`$ECHO $OUTPUT | $GREP " version \""`
+  if test "x$FOUND_VERSION" != x && test "x$FOUND_WARN" = x; then
+    boot_jdk_cds_args="$boot_jdk_cds_args -XX:+UnlockDiagnosticVMOptions -XX:-VerifySharedSpaces -XX:SharedArchiveFile=$BOOT_JDK_CDS_ARCHIVE"
+    JVM_ARG_OK=true
+  else
+    $ECHO "Arg failed:" >&5
+    $ECHO "$OUTPUT" >&5
+    JVM_ARG_OK=false
+  fi
+
+
+  if test "x$boot_jdk_cds_args" != x; then
+    # Try creating a CDS archive
+    "$JAVA" $boot_jdk_cds_args -Xshare:dump > /dev/null 2>&1
+    if test $? -eq 0; then
+      BOOTJDK_USE_LOCAL_CDS=true
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes, created" >&5
+$as_echo "yes, created" >&6; }
+    else
+      # Generation failed, don't use CDS.
+      BOOTJDK_USE_LOCAL_CDS=false
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, creation failed" >&5
+$as_echo "no, creation failed" >&6; }
+    fi
+  else
+    BOOTJDK_USE_LOCAL_CDS=false
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, -XX:SharedArchiveFile not supported" >&5
+$as_echo "no, -XX:SharedArchiveFile not supported" >&6; }
+  fi
+
 
 
 # Check whether --with-build-jdk was given.
@@ -66232,6 +66271,42 @@
   fi
 
 
+  if test "x$BOOTJDK_USE_LOCAL_CDS" = xtrue; then
+    # Use our own CDS archive
+
+  $ECHO "Check if jvm arg is ok: $boot_jdk_cds_args -Xshare:auto" >&5
+  $ECHO "Command: $JAVA $boot_jdk_cds_args -Xshare:auto -version" >&5
+  OUTPUT=`$JAVA $boot_jdk_cds_args -Xshare:auto -version 2>&1`
+  FOUND_WARN=`$ECHO "$OUTPUT" | $GREP -i warn`
+  FOUND_VERSION=`$ECHO $OUTPUT | $GREP " version \""`
+  if test "x$FOUND_VERSION" != x && test "x$FOUND_WARN" = x; then
+    boot_jdk_jvmargs="$boot_jdk_jvmargs $boot_jdk_cds_args -Xshare:auto"
+    JVM_ARG_OK=true
+  else
+    $ECHO "Arg failed:" >&5
+    $ECHO "$OUTPUT" >&5
+    JVM_ARG_OK=false
+  fi
+
+  else
+    # Otherwise optimistically use the system-wide one, if one is present
+
+  $ECHO "Check if jvm arg is ok: -Xshare:auto" >&5
+  $ECHO "Command: $JAVA -Xshare:auto -version" >&5
+  OUTPUT=`$JAVA -Xshare:auto -version 2>&1`
+  FOUND_WARN=`$ECHO "$OUTPUT" | $GREP -i warn`
+  FOUND_VERSION=`$ECHO $OUTPUT | $GREP " version \""`
+  if test "x$FOUND_VERSION" != x && test "x$FOUND_WARN" = x; then
+    boot_jdk_jvmargs="$boot_jdk_jvmargs -Xshare:auto"
+    JVM_ARG_OK=true
+  else
+    $ECHO "Arg failed:" >&5
+    $ECHO "$OUTPUT" >&5
+    JVM_ARG_OK=false
+  fi
+
+  fi
+
   # Apply user provided options.
 
   $ECHO "Check if jvm arg is ok: $with_boot_jdk_jvmargs" >&5
@@ -66256,7 +66331,6 @@
   JAVA_FLAGS=$boot_jdk_jvmargs
 
 
-
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking flags for boot jdk java command for big workloads" >&5
 $as_echo_n "checking flags for boot jdk java command for big workloads... " >&6; }
 
--- a/make/corba/Makefile	Thu Oct 05 22:05:22 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-#
-# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.  Oracle designates this
-# particular file as subject to the "Classpath" exception as provided
-# by Oracle in the LICENSE file that accompanied this code.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-
-# Locate this Makefile
-ifeq ($(filter /%, $(lastword $(MAKEFILE_LIST))), )
-  makefile_path := $(CURDIR)/$(lastword $(MAKEFILE_LIST))
-else
-  makefile_path := $(lastword $(MAKEFILE_LIST))
-endif
-repo_dir := $(patsubst %/make/Makefile, %, $(makefile_path))
-
-# What is the name of this subsystem (langtools, corba, etc)?
-subsystem_name := $(notdir $(repo_dir))
-
-# Try to locate top-level makefile
-top_level_makefile := $(repo_dir)/../Makefile
-ifneq ($(wildcard $(top_level_makefile)), )
-  $(info Will run $(subsystem_name) target on top-level Makefile)
-  $(info WARNING: This is a non-recommended way of building!)
-  $(info ===================================================)
-else
-  $(info Cannot locate top-level Makefile. Is this repo not checked out as part of a complete forest?)
-  $(error Build from top-level Makefile instead)
-endif
-
-all:
-	@$(MAKE) -f $(top_level_makefile) $(subsystem_name)
--- a/make/test/JtregNativeHotspot.gmk	Thu Oct 05 22:05:22 2017 +0200
+++ b/make/test/JtregNativeHotspot.gmk	Thu Oct 12 22:05:47 2017 +0200
@@ -35,7 +35,7 @@
 include MakeBase.gmk
 include TestFilesCompilation.gmk
 
-$(eval $(call IncludeCustomExtension, hotspot/test/JtregNative.gmk))
+$(eval $(call IncludeCustomExtension, test/JtregNativeHotspot.gmk))
 
 ################################################################################
 # Targets for building the native tests themselves.
--- a/make/test/JtregNativeJdk.gmk	Thu Oct 05 22:05:22 2017 +0200
+++ b/make/test/JtregNativeJdk.gmk	Thu Oct 12 22:05:47 2017 +0200
@@ -35,7 +35,7 @@
 include MakeBase.gmk
 include TestFilesCompilation.gmk
 
-$(eval $(call IncludeCustomExtension, test/JtregNative.gmk))
+$(eval $(call IncludeCustomExtension, test/JtregNativeJdk.gmk))
 
 ################################################################################
 # Targets for building the native tests themselves.
--- a/src/java.base/share/classes/java/util/zip/ZipUtils.java	Thu Oct 05 22:05:22 2017 +0200
+++ b/src/java.base/share/classes/java/util/zip/ZipUtils.java	Thu Oct 12 22:05:47 2017 +0200
@@ -28,9 +28,11 @@
 import java.nio.file.attribute.FileTime;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
+import java.time.DateTimeException;
 import java.time.Instant;
 import java.time.LocalDateTime;
 import java.time.ZoneId;
+import java.util.Date;
 import java.util.concurrent.TimeUnit;
 
 import static java.util.zip.ZipConstants.ENDHDR;
@@ -78,31 +80,39 @@
     }
 
     /**
+     /*
      * Converts DOS time to Java time (number of milliseconds since epoch).
      */
     public static long dosToJavaTime(long dtime) {
-        int year;
-        int month;
-        int day;
+        int year = (int) (((dtime >> 25) & 0x7f) + 1980);
+        int month = (int) ((dtime >> 21) & 0x0f);
+        int day = (int) ((dtime >> 16) & 0x1f);
         int hour = (int) ((dtime >> 11) & 0x1f);
         int minute = (int) ((dtime >> 5) & 0x3f);
         int second = (int) ((dtime << 1) & 0x3e);
-        if ((dtime >> 16) == 0) {
-            // Interpret the 0 DOS date as 1979-11-30 for compatibility with
-            // other implementations.
-            year = 1979;
-            month = 11;
-            day = 30;
-        } else {
-            year = (int) (((dtime >> 25) & 0x7f) + 1980);
-            month = (int) ((dtime >> 21) & 0x0f);
-            day = (int) ((dtime >> 16) & 0x1f);
+
+        if (month > 0 && month < 13 && day > 0 && hour < 24 && minute < 60 && second < 60) {
+            try {
+                LocalDateTime ldt = LocalDateTime.of(year, month, day, hour, minute, second);
+                return TimeUnit.MILLISECONDS.convert(ldt.toEpochSecond(
+                        ZoneId.systemDefault().getRules().getOffset(ldt)), TimeUnit.SECONDS);
+            } catch (DateTimeException dte) {
+                // ignore
+            }
         }
-        LocalDateTime ldt = LocalDateTime.of(year, month, day, hour, minute, second);
-        return TimeUnit.MILLISECONDS.convert(ldt.toEpochSecond(
-                ZoneId.systemDefault().getRules().getOffset(ldt)), TimeUnit.SECONDS);
+        return overflowDosToJavaTime(year, month, day, hour, minute, second);
     }
 
+    /*
+     * Deal with corner cases where an arguably mal-formed DOS time is used
+     */
+    @SuppressWarnings("deprecation") // Use of Date constructor
+    private static long overflowDosToJavaTime(int year, int month, int day,
+                                              int hour, int minute, int second) {
+        return new Date(year - 1900, month - 1, day, hour, minute, second).getTime();
+    }
+
+
     /**
      * Converts extended DOS time to Java time, where up to 1999 milliseconds
      * might be encoded into the upper half of the returned long.
--- a/src/java.base/share/classes/sun/nio/ch/FileChannelImpl.java	Thu Oct 05 22:05:22 2017 +0200
+++ b/src/java.base/share/classes/sun/nio/ch/FileChannelImpl.java	Thu Oct 12 22:05:47 2017 +0200
@@ -27,6 +27,7 @@
 
 import java.io.FileDescriptor;
 import java.io.IOException;
+import java.lang.ref.Cleaner.Cleanable;
 import java.nio.ByteBuffer;
 import java.nio.MappedByteBuffer;
 import java.nio.channels.ClosedByInterruptException;
@@ -47,6 +48,7 @@
 import jdk.internal.misc.JavaNioAccess;
 import jdk.internal.misc.SharedSecrets;
 import jdk.internal.ref.Cleaner;
+import jdk.internal.ref.CleanerFactory;
 import sun.security.action.GetPropertyAction;
 
 public class FileChannelImpl
@@ -55,7 +57,7 @@
     // Memory allocation size for mapping buffers
     private static final long allocationGranularity;
 
-    // Access to FileDispatcher internals
+    // Access to FileDescriptor internals
     private static final JavaIOFileDescriptorAccess fdAccess =
         SharedSecrets.getJavaIOFileDescriptorAccess();
 
@@ -85,6 +87,21 @@
     // Positional-read is not interruptible
     private volatile boolean uninterruptible;
 
+    // Cleanable with an action which closes this channel's file descriptor
+    private final Cleanable closer;
+
+    private static class Closer implements Runnable {
+        private final FileDescriptor fd;
+
+        Closer(FileDescriptor fd) {
+            this.fd = fd;
+        }
+
+        public void run() {
+            fdAccess.close(fd);
+        }
+    }
+
     private FileChannelImpl(FileDescriptor fd, String path, boolean readable,
                             boolean writable, Object parent)
     {
@@ -94,6 +111,12 @@
         this.parent = parent;
         this.path = path;
         this.nd = new FileDispatcherImpl();
+        // Register a cleaning action if and only if there is no parent
+        // as the parent will take care of closing the file descriptor.
+        // FileChannel is used by the LambdaMetaFactory so a lambda cannot
+        // be used here hence we use a nested class instead.
+        this.closer = parent != null ? null :
+            CleanerFactory.cleaner().register(this, new Closer(fd));
     }
 
     // Used by FileInputStream.getChannel(), FileOutputStream.getChannel
@@ -143,6 +166,10 @@
             // that method will prevent this method from being reinvoked.
             //
             ((java.io.Closeable)parent).close();
+        } else if (closer != null) {
+            // Perform the cleaning action so it is not redone when
+            // this channel becomes phantom reachable.
+            closer.clean();
         } else {
             fdAccess.close(fd);
         }
@@ -1237,5 +1264,4 @@
         IOUtil.load();
         allocationGranularity = initIDs();
     }
-
 }
--- a/src/java.base/windows/native/libnet/NetworkInterface_winXP.c	Thu Oct 05 22:05:22 2017 +0200
+++ b/src/java.base/windows/native/libnet/NetworkInterface_winXP.c	Thu Oct 12 22:05:47 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -79,6 +79,7 @@
             strlen("IP Helper Library GetAdaptersAddresses function failed"
                    " with error == ") + 10;
     int _ret = 0;
+    int try;
 
 
     adapterInfo = (IP_ADAPTER_ADDRESSES *) malloc(BUFF_SIZE);
@@ -94,7 +95,7 @@
     flags |= GAA_FLAG_INCLUDE_PREFIX;
     ret = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, adapterInfo, &len);
 
-    for (int try = 0; ret == ERROR_BUFFER_OVERFLOW && try < MAX_TRIES; ++try) {
+    for (try = 0; ret == ERROR_BUFFER_OVERFLOW && try < MAX_TRIES; ++try) {
         IP_ADAPTER_ADDRESSES * newAdapterInfo = NULL;
         if (len < (ULONG_MAX - BUFF_SIZE)) {
             len += BUFF_SIZE;
@@ -160,6 +161,7 @@
     size_t error_msg_buf_size =
         strlen("IP Helper Library GetAdaptersAddresses function failed with error == ") + 10;
     int _ret = 0;
+    int try;
     adapterInfo = (IP_ADAPTER_ADDRESSES *) malloc(BUFF_SIZE);
     if (adapterInfo == NULL) {
         JNU_ThrowByName(env, "java/lang/OutOfMemoryError",
@@ -171,7 +173,7 @@
     flags |= GAA_FLAG_SKIP_MULTICAST;
     flags |= GAA_FLAG_INCLUDE_PREFIX;
     val = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, adapterInfo, &len);
-    for (int try = 0; val == ERROR_BUFFER_OVERFLOW && try < MAX_TRIES; ++try) {
+    for (try = 0; val == ERROR_BUFFER_OVERFLOW && try < MAX_TRIES; ++try) {
         IP_ADAPTER_ADDRESSES * newAdapterInfo = NULL;
         if (len < (ULONG_MAX - BUFF_SIZE)) {
             len += BUFF_SIZE;
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java	Thu Oct 05 22:05:22 2017 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java	Thu Oct 12 22:05:47 2017 +0200
@@ -1180,6 +1180,9 @@
                         v.type = chk.checkLocalVarType(tree, tree.init.type.baseType(), tree.name);
                     }
                 }
+                if (tree.isImplicitlyTyped()) {
+                    setSyntheticVariableType(tree, v.type);
+                }
             }
             result = tree.type = v.type;
             if (tree.name == names.underscore) {
@@ -1360,11 +1363,7 @@
             }
             if (tree.var.isImplicitlyTyped()) {
                 Type inferredType = chk.checkLocalVarType(tree.var, elemtype, tree.var.name);
-                if (inferredType.isErroneous()) {
-                    tree.var.vartype = make.at(tree.var.vartype).Erroneous();
-                } else {
-                    tree.var.vartype = make.at(tree.var.vartype).Type(inferredType);
-                }
+                setSyntheticVariableType(tree.var, inferredType);
             }
             attribStat(tree.var, loopEnv);
             chk.checkType(tree.expr.pos(), elemtype, tree.var.sym.type);
@@ -2571,7 +2570,7 @@
                     Type argType = arityMismatch ?
                             syms.errType :
                             actuals.head;
-                    params.head.vartype = make.at(params.head).Type(argType);
+                    setSyntheticVariableType(params.head, argType);
                     params.head.sym = null;
                     actuals = actuals.isEmpty() ?
                             actuals :
@@ -4854,6 +4853,14 @@
         return types.capture(type);
     }
 
+    private void setSyntheticVariableType(JCVariableDecl tree, Type type) {
+        if (type.isErroneous()) {
+            tree.vartype = make.at(Position.NOPOS).Erroneous();
+        } else {
+            tree.vartype = make.at(Position.NOPOS).Type(type);
+        }
+    }
+
     public void validateTypeAnnotations(JCTree tree, boolean sigOnly) {
         tree.accept(new TypeAnnotationsValidator(sigOnly));
     }
@@ -5175,7 +5182,7 @@
                 that.sym.adr = 0;
             }
             if (that.vartype == null) {
-                that.vartype = make.Erroneous();
+                that.vartype = make.at(Position.NOPOS).Erroneous();
             }
             super.visitVarDef(that);
         }
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java	Thu Oct 05 22:05:22 2017 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java	Thu Oct 12 22:05:47 2017 +0200
@@ -308,8 +308,8 @@
         void visitSymbol(Symbol _sym) {
             Symbol sym = _sym;
             if (sym.kind == VAR || sym.kind == MTH) {
-                while (sym != null && sym.owner != owner)
-                    sym = proxies.findFirst(proxyName(sym.name));
+                if (sym != null && sym.owner != owner)
+                    sym = proxies.get(sym);
                 if (sym != null && sym.owner == owner) {
                     VarSymbol v = (VarSymbol)sym;
                     if (v.getConstValue() == null) {
@@ -1084,7 +1084,7 @@
                 return makeLit(sym.type, cv);
             }
             // Otherwise replace the variable by its proxy.
-            sym = proxies.findFirst(proxyName(sym.name));
+            sym = proxies.get(sym);
             Assert.check(sym != null && (sym.flags_field & FINAL) != 0);
             tree = make.at(tree.pos).Ident(sym);
         }
@@ -1359,14 +1359,12 @@
  * Free variables proxies and this$n
  *************************************************************************/
 
-    /** A scope containing all free variable proxies for currently translated
-     *  class, as well as its this$n symbol (if needed).
-     *  Proxy scopes are nested in the same way classes are.
-     *  Inside a constructor, proxies and any this$n symbol are duplicated
-     *  in an additional innermost scope, where they represent the constructor
-     *  parameters.
+    /** A map which allows to retrieve the translated proxy variable for any given symbol of an
+     *  enclosing scope that is accessed (the accessed symbol could be the synthetic 'this$n' symbol).
+     *  Inside a constructor, the map temporarily overrides entries corresponding to proxies and any
+     *  'this$n' symbols, where they represent the constructor parameters.
      */
-    WriteableScope proxies;
+    Map<Symbol, Symbol> proxies;
 
     /** A scope containing all unnamed resource variables/saved
      *  exception variables for translated TWR blocks
@@ -1383,8 +1381,12 @@
 
     /** The name of a free variable proxy.
      */
-    Name proxyName(Name name) {
-        return names.fromString("val" + target.syntheticNameChar() + name);
+    Name proxyName(Name name, int index) {
+        Name proxyName = names.fromString("val" + target.syntheticNameChar() + name);
+        if (index > 0) {
+            proxyName = proxyName.append(names.fromString("" + target.syntheticNameChar() + index));
+        }
+        return proxyName;
     }
 
     /** Proxy definitions for all free variables in given list, in reverse order.
@@ -1400,11 +1402,17 @@
             long additionalFlags) {
         long flags = FINAL | SYNTHETIC | additionalFlags;
         List<JCVariableDecl> defs = List.nil();
+        Set<Name> proxyNames = new HashSet<>();
         for (List<VarSymbol> l = freevars; l.nonEmpty(); l = l.tail) {
             VarSymbol v = l.head;
+            int index = 0;
+            Name proxyName;
+            do {
+                proxyName = proxyName(v.name, index++);
+            } while (!proxyNames.add(proxyName));
             VarSymbol proxy = new VarSymbol(
-                flags, proxyName(v.name), v.erasure(types), owner);
-            proxies.enter(proxy);
+                flags, proxyName, v.erasure(types), owner);
+            proxies.put(v, proxy);
             JCVariableDecl vd = make.at(pos).VarDef(proxy, null);
             vd.vartype = access(vd.vartype);
             defs = defs.prepend(vd);
@@ -1843,11 +1851,8 @@
     /** Return tree simulating the assignment {@code this.name = name}, where
      *  name is the name of a free variable.
      */
-    JCStatement initField(int pos, Name name) {
-        Iterator<Symbol> it = proxies.getSymbolsByName(name).iterator();
-        Symbol rhs = it.next();
+    JCStatement initField(int pos, Symbol rhs, Symbol lhs) {
         Assert.check(rhs.owner.kind == MTH);
-        Symbol lhs = it.next();
         Assert.check(rhs.owner.owner == lhs.owner);
         make.at(pos);
         return
@@ -2207,7 +2212,8 @@
 
         classdefs.put(currentClass, tree);
 
-        proxies = proxies.dup(currentClass);
+        Map<Symbol, Symbol> prevProxies = proxies;
+        proxies = new HashMap<>(proxies);
         List<VarSymbol> prevOuterThisStack = outerThisStack;
 
         // If this is an enum definition
@@ -2270,7 +2276,7 @@
             enterSynthetic(tree.pos(), otdef.sym, currentClass.members());
         }
 
-        proxies = proxies.leave();
+        proxies = prevProxies;
         outerThisStack = prevOuterThisStack;
 
         // Append translated tree to `translated' queue.
@@ -2488,7 +2494,8 @@
 
             // Push a new proxy scope for constructor parameters.
             // and create definitions for any this$n and proxy parameters.
-            proxies = proxies.dup(m);
+            Map<Symbol, Symbol> prevProxies = proxies;
+            proxies = new HashMap<>(proxies);
             List<VarSymbol> prevOuterThisStack = outerThisStack;
             List<VarSymbol> fvs = freevars(currentClass);
             JCVariableDecl otdef = null;
@@ -2523,13 +2530,12 @@
             if (fvs.nonEmpty()) {
                 List<Type> addedargtypes = List.nil();
                 for (List<VarSymbol> l = fvs; l.nonEmpty(); l = l.tail) {
-                    final Name pName = proxyName(l.head.name);
                     m.capturedLocals =
                         m.capturedLocals.prepend((VarSymbol)
-                                                (proxies.findFirst(pName)));
+                                                (proxies.get(l.head)));
                     if (TreeInfo.isInitialConstructor(tree)) {
                         added = added.prepend(
-                          initField(tree.body.pos, pName));
+                          initField(tree.body.pos, proxies.get(l.head), prevProxies.get(l.head)));
                     }
                     addedargtypes = addedargtypes.prepend(l.head.erasure(types));
                 }
@@ -2547,7 +2553,7 @@
             }
 
             // pop local variables from proxy stack
-            proxies = proxies.leave();
+            proxies = prevProxies;
 
             // recursively translate following local statements and
             // combine with this- or super-call
@@ -3714,7 +3720,7 @@
             classdefs = new HashMap<>();
             actualSymbols = new HashMap<>();
             freevarCache = new HashMap<>();
-            proxies = WriteableScope.create(syms.noSymbol);
+            proxies = new HashMap<>();
             twrVars = WriteableScope.create(syms.noSymbol);
             outerThisStack = List.nil();
             accessNums = new HashMap<>();
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java	Thu Oct 05 22:05:22 2017 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java	Thu Oct 12 22:05:47 2017 +0200
@@ -3082,6 +3082,7 @@
         }
         else if (reqInit) syntaxError(token.pos, "expected", EQ);
         JCTree elemType = TreeInfo.innermostType(type, true);
+        int startPos = Position.NOPOS;
         if (allowLocalVariableTypeInference && elemType.hasTag(IDENT)) {
             Name typeName = ((JCIdent)elemType).name;
             if (isRestrictedLocalVarTypeName(typeName)) {
@@ -3089,6 +3090,9 @@
                     //error - 'var' and arrays
                     reportSyntaxError(pos, "var.not.allowed.array");
                 } else {
+                    startPos = TreeInfo.getStartPos(mods);
+                    if (startPos == Position.NOPOS)
+                        startPos = TreeInfo.getStartPos(type);
                     //implicit type
                     type = null;
                 }
@@ -3097,6 +3101,7 @@
         JCVariableDecl result =
             toP(F.at(pos).VarDef(mods, name, type, init));
         attach(result, dc);
+        result.startPos = startPos;
         return result;
     }
 
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/JCTree.java	Thu Oct 05 22:05:22 2017 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/JCTree.java	Thu Oct 12 22:05:47 2017 +0200
@@ -920,6 +920,8 @@
         public JCExpression init;
         /** symbol */
         public VarSymbol sym;
+        /** explicit start pos */
+        public int startPos = Position.NOPOS;
 
         protected JCVariableDecl(JCModifiers mods,
                          Name name,
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java	Thu Oct 05 22:05:22 2017 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java	Thu Oct 12 22:05:47 2017 +0200
@@ -457,9 +457,11 @@
             }
             case VARDEF: {
                 JCVariableDecl node = (JCVariableDecl)tree;
-                if (node.mods.pos != Position.NOPOS) {
+                if (node.startPos != Position.NOPOS) {
+                    return node.startPos;
+                } else if (node.mods.pos != Position.NOPOS) {
                     return node.mods.pos;
-                } else if (node.vartype == null) {
+                } else if (node.vartype == null || node.vartype.pos == Position.NOPOS) {
                     //if there's no type (partially typed lambda parameter)
                     //simply return node position
                     return node.pos;
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractExecutableMemberWriter.java	Thu Oct 05 22:05:22 2017 +0200
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractExecutableMemberWriter.java	Thu Oct 12 22:05:47 2017 +0200
@@ -313,7 +313,8 @@
      * @return the 1.4.x style anchor for the executable element.
      */
     protected String getErasureAnchor(ExecutableElement executableElement) {
-        final StringBuilder buf = new StringBuilder(name(executableElement) + "(");
+        final StringBuilder buf = new StringBuilder(writer.anchorName(executableElement));
+        buf.append("(");
         List<? extends VariableElement> parameters = executableElement.getParameters();
         boolean foundTypeVariable = false;
         for (int i = 0; i < parameters.size(); i++) {
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/FrameOutputWriter.java	Thu Oct 05 22:05:22 2017 +0200
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/FrameOutputWriter.java	Thu Oct 12 22:05:47 2017 +0200
@@ -25,11 +25,15 @@
 
 package jdk.javadoc.internal.doclets.formats.html;
 
+import jdk.javadoc.internal.doclets.formats.html.markup.Comment;
+import jdk.javadoc.internal.doclets.formats.html.markup.DocType;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlAttr;
+import jdk.javadoc.internal.doclets.formats.html.markup.HtmlDocument;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
 import jdk.javadoc.internal.doclets.formats.html.markup.RawHtml;
+import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
 import jdk.javadoc.internal.doclets.toolkit.Content;
 import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException;
 import jdk.javadoc.internal.doclets.toolkit.util.DocPath;
@@ -110,15 +114,41 @@
             body.addContent(frame);
         }
         if (configuration.windowtitle.length() > 0) {
-            printFramesDocument(configuration.windowtitle, configuration,
-                    body);
+            printFramesDocument(configuration.windowtitle, body);
         } else {
-            printFramesDocument(configuration.getText("doclet.Generated_Docs_Untitled"),
-                    configuration, body);
+            printFramesDocument(configuration.getText("doclet.Generated_Docs_Untitled"), body);
         }
     }
 
     /**
+     * Print the frames version of the Html file header.
+     * Called only when generating an HTML frames file.
+     *
+     * @param title Title of this HTML document
+     * @param body the body content tree to be added to the HTML document
+     * @throws DocFileIOException if there is an error writing the frames document
+     */
+    private void printFramesDocument(String title, HtmlTree body) throws DocFileIOException {
+        Content htmlDocType = configuration.isOutputHtml5()
+                ? DocType.HTML5
+                : DocType.TRANSITIONAL;
+        Content htmlComment = new Comment(configuration.getText("doclet.New_Page"));
+        Content head = new HtmlTree(HtmlTag.HEAD);
+        head.addContent(getGeneratedBy(!configuration.notimestamp));
+        Content windowTitle = HtmlTree.TITLE(new StringContent(title));
+        head.addContent(windowTitle);
+        Content meta = HtmlTree.META("Content-Type", CONTENT_TYPE, configuration.charset);
+        head.addContent(meta);
+        head.addContent(getStyleSheetProperties(configuration));
+        head.addContent(getFramesJavaScript());
+        Content htmlTree = HtmlTree.HTML(configuration.getLocale().getLanguage(),
+                head, body);
+        Content htmlDocument = new HtmlDocument(htmlDocType,
+                htmlComment, htmlTree);
+        write(htmlDocument);
+    }
+
+    /**
      * Get the frame sizes and their contents.
      *
      * @return a content tree for the frame details
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java	Thu Oct 05 22:05:22 2017 +0200
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java	Thu Oct 12 22:05:47 2017 +0200
@@ -33,6 +33,7 @@
 import javax.lang.model.element.AnnotationMirror;
 import javax.lang.model.element.AnnotationValue;
 import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementKind;
 import javax.lang.model.element.ExecutableElement;
 import javax.lang.model.element.ModuleElement;
 import javax.lang.model.element.Name;
@@ -74,6 +75,7 @@
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
+import jdk.javadoc.internal.doclets.formats.html.markup.HtmlVersion;
 import jdk.javadoc.internal.doclets.formats.html.markup.RawHtml;
 import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
 import jdk.javadoc.internal.doclets.toolkit.AnnotationTypeWriter;
@@ -1468,20 +1470,18 @@
         if (isProperty) {
             return executableElement.getSimpleName().toString();
         }
-        String signature = utils.signature(executableElement);
-        StringBuilder signatureParsed = new StringBuilder();
-        int counter = 0;
-        for (int i = 0; i < signature.length(); i++) {
-            char c = signature.charAt(i);
-            if (c == '<') {
-                counter++;
-            } else if (c == '>') {
-                counter--;
-            } else if (counter == 0) {
-                signatureParsed.append(c);
-            }
+        String member = anchorName(executableElement);
+        String erasedSignature = utils.makeSignature(executableElement, true, true);
+        return member + erasedSignature;
+    }
+
+    public String anchorName(Element member) {
+        if (member.getKind() == ElementKind.CONSTRUCTOR
+                && configuration.isOutputHtml5()) {
+            return "<init>";
+        } else {
+            return utils.getSimpleName(member);
         }
-        return utils.getSimpleName(executableElement) + signatureParsed.toString();
     }
 
     public Content seeTagToContent(Element element, DocTree see) {
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlDocWriter.java	Thu Oct 05 22:05:22 2017 +0200
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlDocWriter.java	Thu Oct 12 22:05:47 2017 +0200
@@ -37,7 +37,6 @@
 import jdk.javadoc.internal.doclets.toolkit.Content;
 import jdk.javadoc.internal.doclets.toolkit.Messages;
 import jdk.javadoc.internal.doclets.toolkit.util.DocFile;
-import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException;
 import jdk.javadoc.internal.doclets.toolkit.util.DocLink;
 import jdk.javadoc.internal.doclets.toolkit.util.DocPath;
 import jdk.javadoc.internal.doclets.toolkit.util.DocPaths;
@@ -60,7 +59,8 @@
 
     public static final String CONTENT_TYPE = "text/html";
 
-    DocPath pathToRoot;
+    private final HtmlConfiguration configuration;
+    private final DocPath pathToRoot;
 
     /**
      * Constructor. Initializes the destination file name through the super
@@ -69,8 +69,9 @@
      * @param configuration the configuration for this doclet
      * @param filename String file name.
      */
-    public HtmlDocWriter(BaseConfiguration configuration, DocPath filename) {
+    public HtmlDocWriter(HtmlConfiguration configuration, DocPath filename) {
         super(configuration, filename);
+        this.configuration = configuration;
         this.pathToRoot = filename.parent().invert();
         Messages messages = configuration.getMessages();
         messages.notice("doclet.Generating_0",
@@ -81,7 +82,9 @@
      * Accessor for configuration.
      * @return the configuration for this doclet
      */
-    public abstract BaseConfiguration configuration();
+    public BaseConfiguration configuration() {
+        return configuration;
+    }
 
     public Content getHyperLink(DocPath link, String label) {
         return getHyperLink(link, new StringContent(label), false, "", "", "");
@@ -167,8 +170,6 @@
      * @return a valid HTML name string.
      */
     public String getName(String name) {
-        StringBuilder sb = new StringBuilder();
-        char ch;
         /* The HTML 4 spec at http://www.w3.org/TR/html4/types.html#h-6.2 mentions
          * that the name/id should begin with a letter followed by other valid characters.
          * The HTML 5 spec (draft) is more permissive on names/ids where the only restriction
@@ -179,8 +180,14 @@
          * substitute it accordingly, "_" and "$" can appear at the beginning of a member name.
          * The method substitutes "$" with "Z:Z:D" and will prefix "_" with "Z:Z".
          */
+
+        if (configuration.isOutputHtml5()) {
+            return name.replaceAll(" +", "");
+        }
+
+        StringBuilder sb = new StringBuilder();
         for (int i = 0; i < name.length(); i++) {
-            ch = name.charAt(i);
+            char ch = name.charAt(i);
             switch (ch) {
                 case '(':
                 case ')':
@@ -310,36 +317,6 @@
     }
 
     /**
-     * Print the frames version of the Html file header.
-     * Called only when generating an HTML frames file.
-     *
-     * @param title Title of this HTML document
-     * @param configuration the configuration object
-     * @param body the body content tree to be added to the HTML document
-     * @throws DocFileIOException if there is an error writing the frames document
-     */
-    public void printFramesDocument(String title, HtmlConfiguration configuration,
-            HtmlTree body) throws DocFileIOException {
-        Content htmlDocType = configuration.isOutputHtml5()
-                ? DocType.HTML5
-                : DocType.TRANSITIONAL;
-        Content htmlComment = new Comment(configuration.getText("doclet.New_Page"));
-        Content head = new HtmlTree(HtmlTag.HEAD);
-        head.addContent(getGeneratedBy(!configuration.notimestamp));
-        Content windowTitle = HtmlTree.TITLE(new StringContent(title));
-        head.addContent(windowTitle);
-        Content meta = HtmlTree.META("Content-Type", CONTENT_TYPE, configuration.charset);
-        head.addContent(meta);
-        head.addContent(getStyleSheetProperties(configuration));
-        head.addContent(getFramesJavaScript());
-        Content htmlTree = HtmlTree.HTML(configuration.getLocale().getLanguage(),
-                head, body);
-        Content htmlDocument = new HtmlDocument(htmlDocType,
-                htmlComment, htmlTree);
-        write(htmlDocument);
-    }
-
-    /**
      * Returns a link to the stylesheet file.
      *
      * @param configuration the configuration for this doclet
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlTree.java	Thu Oct 05 22:05:22 2017 +0200
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlTree.java	Thu Oct 12 22:05:47 2017 +0200
@@ -181,36 +181,63 @@
         return s;
     }
 
-    /**
-     * A set of ASCII URI characters to be left unencoded.
+    /*
+     * The sets of ASCII URI characters to be left unencoded.
+     * See "Uniform Resource Identifier (URI): Generic Syntax"
+     * IETF RFC 3986. https://tools.ietf.org/html/rfc3986
      */
-    public static final BitSet NONENCODING_CHARS = new BitSet(256);
+    public static final BitSet MAIN_CHARS;
+    public static final BitSet QUERY_FRAGMENT_CHARS;
 
     static {
-        // alphabetic characters
-        for (int i = 'a'; i <= 'z'; i++) {
-            NONENCODING_CHARS.set(i);
-        }
-        for (int i = 'A'; i <= 'Z'; i++) {
-            NONENCODING_CHARS.set(i);
-        }
-        // numeric characters
-        for (int i = '0'; i <= '9'; i++) {
-            NONENCODING_CHARS.set(i);
-        }
-        // Reserved characters as per RFC 3986. These are set of delimiting characters.
-        String noEnc = ":/?#[]@!$&'()*+,;=";
-        // Unreserved characters as per RFC 3986 which should not be percent encoded.
-        noEnc += "-._~";
-        for (int i = 0; i < noEnc.length(); i++) {
-            NONENCODING_CHARS.set(noEnc.charAt(i));
-        }
+        BitSet alphaDigit = bitSet(bitSet('A', 'Z'), bitSet('a', 'z'), bitSet('0', '9'));
+        BitSet unreserved = bitSet(alphaDigit, bitSet("-._~"));
+        BitSet genDelims = bitSet(":/?#[]@");
+        BitSet subDelims = bitSet("!$&'()*+,;=");
+        MAIN_CHARS = bitSet(unreserved, genDelims, subDelims);
+        BitSet pchar = bitSet(unreserved, subDelims, bitSet(":@"));
+        QUERY_FRAGMENT_CHARS = bitSet(pchar, bitSet("/?"));
     }
 
+    private static BitSet bitSet(String s) {
+        BitSet result = new BitSet();
+        for (int i = 0; i < s.length(); i++) {
+           result.set(s.charAt(i));
+        }
+        return result;
+    }
+
+    private static BitSet bitSet(char from, char to) {
+        BitSet result = new BitSet();
+        result.set(from, to + 1);
+        return result;
+    }
+
+    private static BitSet bitSet(BitSet... sets) {
+        BitSet result = new BitSet();
+        for (BitSet set : sets) {
+            result.or(set);
+        }
+        return result;
+    }
+
+    /**
+     * Apply percent-encoding to a URL.
+     * This is similar to {@link java.net.URLEncoder} but
+     * is less aggressive about encoding some characters,
+     * like '(', ')', ',' which are used in the anchor
+     * names for Java methods in HTML5 mode.
+     */
     private static String encodeURL(String url) {
+        BitSet nonEncodingChars = MAIN_CHARS;
         StringBuilder sb = new StringBuilder();
         for (byte c : url.getBytes(Charset.forName("UTF-8"))) {
-            if (NONENCODING_CHARS.get(c & 0xFF)) {
+            if (c == '?' || c == '#') {
+                sb.append((char) c);
+                // switch to the more restrictive set inside
+                // the query and/or fragment
+                nonEncodingChars = QUERY_FRAGMENT_CHARS;
+            } else if (nonEncodingChars.get(c & 0xFF)) {
                 sb.append((char) c);
             } else {
                 sb.append(String.format("%%%02X", c & 0xFF));
--- a/src/jdk.jshell/share/classes/jdk/jshell/Eval.java	Thu Oct 05 22:05:22 2017 +0200
+++ b/src/jdk.jshell/share/classes/jdk/jshell/Eval.java	Thu Oct 12 22:05:47 2017 +0200
@@ -295,6 +295,10 @@
                 Range rtype = dis.treeToRange(baseType);
                 typeWrap = Wrap.rangeWrap(compileSource, rtype);
             } else {
+                AnalyzeTask at = trialCompile(Wrap.methodWrap(compileSource));
+                if (at.hasErrors()) {
+                    return compileFailResult(at, userSource, kindOfTree(unitTree));
+                }
                 Tree init = vt.getInitializer();
                 if (init != null) {
                     Range rinit = dis.treeToRange(init);
--- a/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipUtils.java	Thu Oct 05 22:05:22 2017 +0200
+++ b/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipUtils.java	Thu Oct 12 22:05:47 2017 +0200
@@ -27,10 +27,12 @@
 
 import java.io.IOException;
 import java.io.OutputStream;
+import java.time.DateTimeException;
 import java.time.Instant;
 import java.time.LocalDateTime;
 import java.time.ZoneId;
 import java.util.Arrays;
+import java.util.Date;
 import java.util.regex.PatternSyntaxException;
 import java.util.concurrent.TimeUnit;
 
@@ -106,26 +108,32 @@
      * Converts DOS time to Java time (number of milliseconds since epoch).
      */
     public static long dosToJavaTime(long dtime) {
-        int year;
-        int month;
-        int day;
+        int year = (int) (((dtime >> 25) & 0x7f) + 1980);
+        int month = (int) ((dtime >> 21) & 0x0f);
+        int day = (int) ((dtime >> 16) & 0x1f);
         int hour = (int) ((dtime >> 11) & 0x1f);
         int minute = (int) ((dtime >> 5) & 0x3f);
         int second = (int) ((dtime << 1) & 0x3e);
-        if ((dtime >> 16) == 0) {
-            // Interpret the 0 DOS date as 1979-11-30 for compatibility with
-            // other implementations.
-            year = 1979;
-            month = 11;
-            day = 30;
-        } else {
-            year = (int) (((dtime >> 25) & 0x7f) + 1980);
-            month = (int) ((dtime >> 21) & 0x0f);
-            day = (int) ((dtime >> 16) & 0x1f);
+
+        if (month > 0 && month < 13 && day > 0 && hour < 24 && minute < 60 && second < 60) {
+            try {
+                LocalDateTime ldt = LocalDateTime.of(year, month, day, hour, minute, second);
+                return TimeUnit.MILLISECONDS.convert(ldt.toEpochSecond(
+                        ZoneId.systemDefault().getRules().getOffset(ldt)), TimeUnit.SECONDS);
+            } catch (DateTimeException dte) {
+                // ignore
+            }
         }
-        LocalDateTime ldt = LocalDateTime.of(year, month, day, hour, minute, second);
-        return TimeUnit.MILLISECONDS.convert(ldt.toEpochSecond(
-                ZoneId.systemDefault().getRules().getOffset(ldt)), TimeUnit.SECONDS);
+        return overflowDosToJavaTime(year, month, day, hour, minute, second);
+    }
+
+    /*
+     * Deal with corner cases where an arguably mal-formed DOS time is used
+     */
+    @SuppressWarnings("deprecation") // Use of Date constructor
+    private static long overflowDosToJavaTime(int year, int month, int day,
+                                              int hour, int minute, int second) {
+        return new Date(year - 1900, month - 1, day, hour, minute, second).getTime();
     }
 
     /*
--- a/test/TestCommon.gmk	Thu Oct 05 22:05:22 2017 +0200
+++ b/test/TestCommon.gmk	Thu Oct 12 22:05:47 2017 +0200
@@ -360,6 +360,9 @@
   JTREG_TESTVM_MEMORY_OPTION = -vmoption:-Xmx512m
   JTREG_TEST_OPTIONS += $(JTREG_TESTVM_MEMORY_OPTION)
 endif
+# Make it possible to specify the JIB_DATA_DIR for tests using the
+# JIB Artifact resolver
+JTREG_BASIC_OPTIONS += -e:JIB_DATA_DIR
 # Give tests access to JT_JAVA, see JDK-8141609
 JTREG_BASIC_OPTIONS += -e:JDK8_HOME=${JT_JAVA}
 # Give aot tests access to Visual Studio installation
--- a/test/jdk/java/net/HttpURLConnection/SetAuthenticator/HTTPSetAuthenticatorTest.java	Thu Oct 05 22:05:22 2017 +0200
+++ b/test/jdk/java/net/HttpURLConnection/SetAuthenticator/HTTPSetAuthenticatorTest.java	Thu Oct 12 22:05:47 2017 +0200
@@ -147,11 +147,6 @@
             throw new AssertionError("Authenticator #2 called " + count(count)
                 + " expected it to be called " + expected(expectedIncrement));
         }
-        count = authTwo.count.get();
-        if (count != expectedIncrement) {
-            throw new AssertionError("Authenticator #2 called " + count(count)
-                + " expected it to be called " + expected(expectedIncrement));
-        }
 
         // Connect to the server with a GET request, then with a
         // POST that contains "Hello World!"
--- a/test/jdk/java/net/HttpURLConnection/SetAuthenticator/HTTPTestServer.java	Thu Oct 05 22:05:22 2017 +0200
+++ b/test/jdk/java/net/HttpURLConnection/SetAuthenticator/HTTPTestServer.java	Thu Oct 12 22:05:47 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -46,6 +46,7 @@
 import java.net.MalformedURLException;
 import java.net.ServerSocket;
 import java.net.Socket;
+import java.net.SocketAddress;
 import java.net.URL;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
@@ -148,62 +149,139 @@
     }
 
     /**
-     * The HttpServerFactory ensures that the local port used by an HttpServer
-     * previously created by the current test/VM will not get reused by
-     * a subsequent test in the same VM. This is to avoid having the
-     * AuthCache reuse credentials from previous tests - which would
-     * invalidate the assumptions made by the current test on when
-     * the default authenticator should be called.
+     * The SocketBindableFactory ensures that the local port used by an HttpServer
+     * or a proxy ServerSocket previously created by the current test/VM will not
+     * get reused by a subsequent test in the same VM. This is to avoid having the
+     * AuthCache reuse credentials from previous tests - which would invalidate the
+     * assumptions made by the current test on when the default authenticator should
+     * be called.
      */
-    private static final class HttpServerFactory {
+    private static abstract class SocketBindableFactory<B> {
         private static final int MAX = 10;
         private static final CopyOnWriteArrayList<String> addresses =
             new CopyOnWriteArrayList<>();
-        private static HttpServer newHttpServer(HttpProtocolType protocol)
-                throws IOException {
-            switch (protocol) {
-               case HTTP:  return HttpServer.create();
-               case HTTPS: return HttpsServer.create();
-               default: throw new InternalError("Unsupported protocol " + protocol);
-            }
-        }
-        static <T extends HttpServer> T create(HttpProtocolType protocol)
-                throws IOException {
+        protected B createInternal() throws IOException {
             final int max = addresses.size() + MAX;
-            final List<HttpServer> toClose = new ArrayList<>();
+            final List<B> toClose = new ArrayList<>();
             try {
                 for (int i = 1; i <= max; i++) {
-                    HttpServer server = newHttpServer(protocol);
-                    server.bind(new InetSocketAddress("127.0.0.1", 0), 0);
-                    InetSocketAddress address = server.getAddress();
+                    B bindable = createBindable();
+                    SocketAddress address = getAddress(bindable);
                     String key = address.toString();
                     if (addresses.addIfAbsent(key)) {
-                       System.out.println("Server bound to: " + key
+                       System.out.println("Socket bound to: " + key
                                           + " after " + i + " attempt(s)");
-                       return (T) server;
+                       return bindable;
                     }
                     System.out.println("warning: address " + key
                                        + " already used. Retrying bind.");
                     // keep the port bound until we get a port that we haven't
                     // used already
-                    toClose.add(server);
+                    toClose.add(bindable);
                 }
             } finally {
-                // if we had to retry, then close the servers we're not
+                // if we had to retry, then close the socket we're not
                 // going to use.
-                for (HttpServer s : toClose) {
-                  try { s.stop(1); } catch (Exception x) { /* ignore */ }
+                for (B b : toClose) {
+                  try { close(b); } catch (Exception x) { /* ignore */ }
                 }
             }
-            throw new IOException("Couldn't bind servers after " + max + " attempts: "
+            throw new IOException("Couldn't bind socket after " + max + " attempts: "
                                   + "addresses used before: " + addresses);
         }
+
+        protected abstract B createBindable() throws IOException;
+
+        protected abstract SocketAddress getAddress(B bindable);
+
+        protected abstract void close(B bindable) throws IOException;
+    }
+
+    /*
+     * Used to create ServerSocket for a proxy.
+     */
+    private static final class ServerSocketFactory
+            extends SocketBindableFactory<ServerSocket> {
+        private static final ServerSocketFactory instance = new ServerSocketFactory();
+
+        static ServerSocket create() throws IOException {
+            return instance.createInternal();
+        }
+
+        @Override
+        protected ServerSocket createBindable() throws IOException {
+            return new ServerSocket(0, 0, InetAddress.getByName("127.0.0.1"));
+        }
+
+        @Override
+        protected SocketAddress getAddress(ServerSocket socket) {
+            return socket.getLocalSocketAddress();
+        }
+
+        @Override
+        protected void close(ServerSocket socket) throws IOException {
+            socket.close();
+        }
+    }
+
+    /*
+     * Used to create HttpServer for a NTLMTestServer.
+     */
+    private static abstract class WebServerFactory<S extends HttpServer>
+            extends SocketBindableFactory<S> {
+        @Override
+        protected S createBindable() throws IOException {
+            S server = newHttpServer();
+            server.bind(new InetSocketAddress("127.0.0.1", 0), 0);
+            return server;
+        }
+
+        @Override
+        protected SocketAddress getAddress(S server) {
+            return server.getAddress();
+        }
+
+        @Override
+        protected void close(S server) throws IOException {
+            server.stop(1);
+        }
+
+        /*
+         * Returns a HttpServer or a HttpsServer in different subclasses.
+         */
+        protected abstract S newHttpServer() throws IOException;
+    }
+
+    private static final class HttpServerFactory extends WebServerFactory<HttpServer> {
+        private static final HttpServerFactory instance = new HttpServerFactory();
+
+        static HttpServer create() throws IOException {
+            return instance.createInternal();
+        }
+
+        @Override
+        protected HttpServer newHttpServer() throws IOException {
+            return HttpServer.create();
+        }
+    }
+
+    private static final class HttpsServerFactory extends WebServerFactory<HttpsServer> {
+        private static final HttpsServerFactory instance = new HttpsServerFactory();
+
+        static HttpsServer create() throws IOException {
+            return instance.createInternal();
+        }
+
+        @Override
+        protected HttpsServer newHttpServer() throws IOException {
+            return HttpsServer.create();
+        }
     }
 
     static HttpServer createHttpServer(HttpProtocolType protocol) throws IOException {
         switch (protocol) {
-            case HTTP:  return HttpServerFactory.create(protocol);
-            case HTTPS: return configure(HttpServerFactory.create(protocol));
+            case HTTP:  return HttpServerFactory.create();
+            case HTTPS: return configure(HttpsServerFactory.create());
             default: throw new InternalError("Unsupported protocol " + protocol);
         }
     }
@@ -894,7 +972,7 @@
             super(server, target, delegate);
             System.out.flush();
             System.err.println("WARNING: HttpsProxyTunnel is an experimental test class");
-            ss = new ServerSocket(0, 0, InetAddress.getByName("127.0.0.1"));
+            ss = ServerSocketFactory.create();
             start();
         }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/nio/channels/FileChannel/CleanerTest.java	Thu Oct 12 22:05:47 2017 +0200
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 8147615
+ * @summary Test whether an unreferenced FileChannel is actually cleaned
+ * @requires (os.family == "linux") | (os.family == "mac") | (os.family == "solaris") | (os.family == "aix")
+ * @modules java.management
+ * @run main/othervm CleanerTest
+ */
+
+import com.sun.management.UnixOperatingSystemMXBean;
+import java.lang.management.ManagementFactory;
+import java.lang.management.OperatingSystemMXBean;
+import java.lang.ref.PhantomReference;
+import java.lang.ref.Reference;
+import java.lang.ref.ReferenceQueue;
+import java.nio.channels.FileChannel;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardOpenOption;
+
+public class CleanerTest {
+    public static void main(String[] args) throws Throwable {
+        OperatingSystemMXBean mxBean =
+            ManagementFactory.getOperatingSystemMXBean();
+        UnixOperatingSystemMXBean unixMxBean = null;
+        if (mxBean instanceof UnixOperatingSystemMXBean) {
+            unixMxBean = (UnixOperatingSystemMXBean)mxBean;
+        } else {
+            System.out.println("Non-Unix system: skipping test.");
+            return;
+        }
+
+        Path path = Paths.get(System.getProperty("test.dir", "."), "junk");
+        try {
+            FileChannel fc = FileChannel.open(path, StandardOpenOption.CREATE,
+                StandardOpenOption.READ, StandardOpenOption.WRITE);
+
+            ReferenceQueue refQueue = new ReferenceQueue();
+            Reference fcRef = new PhantomReference(fc, refQueue);
+
+            long fdCount0 = unixMxBean.getOpenFileDescriptorCount();
+            fc = null;
+
+            // Perform repeated GCs until the reference has been enqueued.
+            do {
+                Thread.sleep(1);
+                System.gc();
+            } while (refQueue.poll() == null);
+
+            // Loop until the open file descriptor count has been decremented.
+            while (unixMxBean.getOpenFileDescriptorCount() > fdCount0 - 1) {
+                Thread.sleep(1);
+            }
+
+            long fdCount = unixMxBean.getOpenFileDescriptorCount();
+            if (fdCount != fdCount0 - 1) {
+                throw new RuntimeException("FD count expected " +
+                    (fdCount0 - 1) + "; actual " + fdCount);
+            }
+        } finally {
+            Files.delete(path);
+        }
+    }
+}
--- a/test/jdk/java/util/zip/ZipFile/ZeroDate.java	Thu Oct 05 22:05:22 2017 +0200
+++ b/test/jdk/java/util/zip/ZipFile/ZeroDate.java	Thu Oct 12 22:05:47 2017 +0200
@@ -34,14 +34,16 @@
 import java.nio.file.Path;
 import java.time.Instant;
 import java.time.LocalDate;
+import java.time.LocalDateTime;
 import java.time.ZoneId;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipFile;
 import java.util.zip.ZipOutputStream;
 
 /* @test
- * @bug 8184940
+ * @bug 8184940 8188869
  * @summary JDK 9 rejects zip files where the modified day or month is 0
+ *          or otherwise represent an invalid date, such as 1980-02-30 24:60:60
  * @author Liam Miller-Cushon
  */
 public class ZeroDate {
@@ -63,12 +65,19 @@
         Files.delete(path);
 
         // year, month, day are zero
-        testDate(data.clone(), 0, LocalDate.of(1979, 11, 30));
+        testDate(data.clone(), 0, LocalDate.of(1979, 11, 30).atStartOfDay());
         // only year is zero
-        testDate(data.clone(), 0 << 25 | 4 << 21 | 5 << 16, LocalDate.of(1980, 4, 5));
+        testDate(data.clone(), 0 << 25 | 4 << 21 | 5 << 16, LocalDate.of(1980, 4, 5).atStartOfDay());
+        // month is greater than 12
+        testDate(data.clone(), 0 << 25 | 13 << 21 | 1 << 16, LocalDate.of(1981, 1, 1).atStartOfDay());
+        // 30th of February
+        testDate(data.clone(), 0 << 25 | 2 << 21 | 30 << 16, LocalDate.of(1980, 3, 1).atStartOfDay());
+        // 30th of February, 24:60:60
+        testDate(data.clone(), 0 << 25 | 2 << 21 | 30 << 16 | 24 << 11 | 60 << 5 | 60 >> 1,
+                LocalDateTime.of(1980, 3, 2, 1, 1, 0));
     }
 
-    private static void testDate(byte[] data, int date, LocalDate expected) throws IOException {
+    private static void testDate(byte[] data, int date, LocalDateTime expected) throws IOException {
         // set the datetime
         int endpos = data.length - ENDHDR;
         int cenpos = u16(data, endpos + ENDOFF);
@@ -84,8 +93,7 @@
         try (ZipFile zf = new ZipFile(path.toFile())) {
             ZipEntry ze = zf.entries().nextElement();
             Instant actualInstant = ze.getLastModifiedTime().toInstant();
-            Instant expectedInstant =
-                    expected.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant();
+            Instant expectedInstant = expected.atZone(ZoneId.systemDefault()).toInstant();
             if (!actualInstant.equals(expectedInstant)) {
                 throw new AssertionError(
                         String.format("actual: %s, expected: %s", actualInstant, expectedInstant));
--- a/test/jdk/jdk/nio/zipfs/ZeroDate.java	Thu Oct 05 22:05:22 2017 +0200
+++ b/test/jdk/jdk/nio/zipfs/ZeroDate.java	Thu Oct 12 22:05:47 2017 +0200
@@ -38,14 +38,16 @@
 import java.nio.file.attribute.BasicFileAttributes;
 import java.time.Instant;
 import java.time.LocalDate;
+import java.time.LocalDateTime;
 import java.time.ZoneId;
 import java.util.Collections;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipOutputStream;
 
 /* @test
- * @bug 8184940 8186227
+ * @bug 8184940 8186227 8188869
  * @summary JDK 9 rejects zip files where the modified day or month is 0
+ *          or otherwise represent an invalid date, such as 1980-02-30 24:60:60
  * @author Liam Miller-Cushon
  */
 public class ZeroDate {
@@ -67,12 +69,19 @@
         Files.delete(path);
 
         // year, month, day are zero
-        testDate(data.clone(), 0, LocalDate.of(1979, 11, 30));
+        testDate(data.clone(), 0, LocalDate.of(1979, 11, 30).atStartOfDay());
         // only year is zero
-        testDate(data.clone(), 0 << 25 | 4 << 21 | 5 << 16, LocalDate.of(1980, 4, 5));
+        testDate(data.clone(), 0 << 25 | 4 << 21 | 5 << 16, LocalDate.of(1980, 4, 5).atStartOfDay());
+        // month is greater than 12
+        testDate(data.clone(), 0 << 25 | 13 << 21 | 1 << 16, LocalDate.of(1981, 1, 1).atStartOfDay());
+        // 30th of February
+        testDate(data.clone(), 0 << 25 | 2 << 21 | 30 << 16, LocalDate.of(1980, 3, 1).atStartOfDay());
+        // 30th of February, 24:60:60
+        testDate(data.clone(), 0 << 25 | 2 << 21 | 30 << 16 | 24 << 11 | 60 << 5 | 60 >> 1,
+                LocalDateTime.of(1980, 3, 2, 1, 1, 0));
     }
 
-    private static void testDate(byte[] data, int date, LocalDate expected) throws IOException {
+    private static void testDate(byte[] data, int date, LocalDateTime expected) throws IOException {
         // set the datetime
         int endpos = data.length - ENDHDR;
         int cenpos = u16(data, endpos + ENDOFF);
@@ -93,7 +102,7 @@
                             .lastModifiedTime()
                             .toInstant();
             Instant expectedInstant =
-                    expected.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant();
+                    expected.atZone(ZoneId.systemDefault()).toInstant();
             if (!actualInstant.equals(expectedInstant)) {
                 throw new AssertionError(
                         String.format("actual: %s, expected: %s", actualInstant, expectedInstant));
--- a/test/langtools/jdk/javadoc/doclet/lib/JavadocTester.java	Thu Oct 05 22:05:22 2017 +0200
+++ b/test/langtools/jdk/javadoc/doclet/lib/JavadocTester.java	Thu Oct 12 22:05:47 2017 +0200
@@ -37,6 +37,8 @@
 import java.lang.ref.SoftReference;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
+import java.nio.charset.Charset;
+import java.nio.charset.UnsupportedCharsetException;
 import java.nio.file.Files;
 import java.util.Arrays;
 import java.util.ArrayList;
@@ -46,6 +48,7 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.function.Function;
 
 
@@ -150,6 +153,9 @@
     /** The output directory used in the most recent call of javadoc. */
     protected File outputDir;
 
+    /** The output charset used in the most recent call of javadoc. */
+    protected Charset charset = Charset.defaultCharset();
+
     /** The exit code of the most recent call of javadoc. */
     private int exitCode;
 
@@ -158,6 +164,8 @@
 
     /** A cache of file content, to avoid reading files unnecessarily. */
     private final Map<File,SoftReference<String>> fileContentCache = new HashMap<>();
+    /** The charset used for files in the fileContentCache. */
+    private Charset fileContentCacheCharset = null;
 
     /** Stream used for logging messages. */
     protected final PrintStream out = System.out;
@@ -293,13 +301,46 @@
             out.println("Running javadoc (run "
                                     + javadocRunNum + ")...");
         }
+
         outputDir = new File(".");
+        String charsetArg = null;
+        String docencodingArg = null;
+        String encodingArg = null;
         for (int i = 0; i < args.length - 2; i++) {
-            if (args[i].equals("-d")) {
-                outputDir = new File(args[++i]);
-                break;
+            switch (args[i]) {
+                case "-d":
+                    outputDir = new File(args[++i]);
+                    break;
+                case "-charset":
+                    charsetArg = args[++i];
+                    break;
+                case "-docencoding":
+                    docencodingArg = args[++i];
+                    break;
+                case "-encoding":
+                    encodingArg = args[++i];
+                    break;
             }
         }
+
+        // The following replicates HtmlConfiguration.finishOptionSettings0
+        // and sets up the charset used to read files.
+        String cs;
+        if (docencodingArg == null) {
+            if (charsetArg == null) {
+                cs = (encodingArg == null) ? "UTF-8" : encodingArg;
+            } else {
+                cs = charsetArg;
+            }
+        } else {
+           cs = docencodingArg;
+        }
+        try {
+            charset = Charset.forName(cs);
+        } catch (UnsupportedCharsetException e) {
+            charset = Charset.defaultCharset();
+        }
+
         out.println("args: " + Arrays.toString(args));
 //        log.setOutDir(outputDir);
 
@@ -637,6 +678,10 @@
      * @return          the file in string format
      */
     private String readFile(File baseDir, String fileName) throws Error {
+        if (!Objects.equals(fileContentCacheCharset, charset)) {
+            fileContentCache.clear();
+            fileContentCacheCharset = charset;
+        }
         try {
             File file = new File(baseDir, fileName);
             SoftReference<String> ref = fileContentCache.get(file);
@@ -644,7 +689,8 @@
             if (content != null)
                 return content;
 
-            content = new String(Files.readAllBytes(file.toPath()));
+            // charset defaults to a value inferred from latest javadoc run
+            content = new String(Files.readAllBytes(file.toPath()), charset);
             fileContentCache.put(file, new SoftReference<>(content));
             return content;
         } catch (FileNotFoundException e) {
--- a/test/langtools/jdk/javadoc/doclet/testAnchorNames/TestAnchorNames.java	Thu Oct 05 22:05:22 2017 +0200
+++ b/test/langtools/jdk/javadoc/doclet/testAnchorNames/TestAnchorNames.java	Thu Oct 12 22:05:47 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,29 +23,37 @@
 
 /*
  * @test
- * @bug 8025633 8025524 8081854
+ * @bug 8025633 8025524 8081854 8187521
  * @summary Test for valid name attribute in HTML anchors.
  * @author Bhavesh Patel
- * @library ../lib
+ * @library /tools/lib ../lib
  * @modules jdk.javadoc/jdk.javadoc.internal.tool
- * @build JavadocTester
+ * @build toolbox.ToolBox JavadocTester
  * @run main TestAnchorNames
  */
 
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import toolbox.*;
+
 public class TestAnchorNames extends JavadocTester {
 
-    private static final String[] ARGS = new String[] {
+    public final ToolBox tb;
+    public static void main(String... args) throws Exception {
+        TestAnchorNames tester = new TestAnchorNames();
+        tester.runTests(m -> new Object[] { Paths.get(m.getName()) });
+    }
 
-    };
-
-    public static void main(String[] args) throws Exception {
-        TestAnchorNames tester = new TestAnchorNames();
-        tester.runTests();
+    public TestAnchorNames() {
+        tb = new ToolBox();
     }
 
     @Test
-    void test() {
-        javadoc("-d", "out",
+    void testHtml4(Path ignore) {
+        javadoc("-d", "out-html4",
                 "-sourcepath", testSrc,
                 "-source", "8", //so that '_' can be used as an identifier
                 "-use",
@@ -153,11 +161,169 @@
                 "<a href=\"#I:Z:Z_\">_");
 
         // The marker name conversion should only affect HTML anchors. It should not
-        // affect the lables.
+        // affect the labels.
         checkOutput("pkg1/RegClass.html", false,
                 " Z:Z_",
                 " Z:Z:Dfield",
                 " Z:Z_field_In_Class",
                 " S_:D:D:D:D:DINT");
     }
+
+    @Test
+    void testHtml5(Path ignore) {
+        javadoc("-d", "out-html5",
+                "-sourcepath", testSrc,
+                "-source", "8", //so that '_' can be used as an identifier
+                "-use",
+                "-html5",
+                "pkg1");
+        checkExit(Exit.OK);
+
+        // Test some section markers and links to these markers
+        checkOutput("pkg1/RegClass.html", true,
+                "<a id=\"skip.navbar.top\">",
+                "<a href=\"#skip.navbar.top\" title=\"Skip navigation links\">",
+                "<a id=\"nested.class.summary\">",
+                "<a href=\"#nested.class.summary\">",
+                "<a id=\"method.summary\">",
+                "<a href=\"#method.summary\">",
+                "<a id=\"field.detail\">",
+                "<a href=\"#field.detail\">",
+                "<a id=\"constructor.detail\">",
+                "<a href=\"#constructor.detail\">");
+
+        // Test some members and link to these members
+        checkOutput("pkg1/RegClass.html", true,
+                //The marker for this appears in the serialized-form.html which we will
+                //test below
+                "<a href=\"../serialized-form.html#pkg1.RegClass\">");
+
+        // Test some fields
+        checkOutput("pkg1/RegClass.html", true,
+                "<a id=\"_\">",
+                "<a href=\"../pkg1/RegClass.html#_\">",
+                "<a id=\"_$\">",
+                "<a href=\"../pkg1/RegClass.html#_$\">",
+                "<a id=\"$_\">",
+                "<a href=\"../pkg1/RegClass.html#$_\">",
+                "<a id=\"$field\">",
+                "<a href=\"../pkg1/RegClass.html#$field\">",
+                "<a id=\"fieldInCla$$\">",
+                "<a href=\"../pkg1/RegClass.html#fieldInCla$$\">",
+                "<a id=\"S_$$$$$INT\">",
+                "<a href=\"../pkg1/RegClass.html#S_$$$$$INT\">",
+                "<a id=\"method$$\">",
+                "<a href=\"../pkg1/RegClass.html#method$$\">");
+
+        checkOutput("pkg1/DeprMemClass.html", true,
+                "<a id=\"_field_In_Class\">",
+                "<a href=\"../pkg1/DeprMemClass.html#_field_In_Class\">");
+
+        // Test constructor
+        checkOutput("pkg1/RegClass.html", true,
+                "<a id=\"&lt;init&gt;(java.lang.String,int)\">",
+                "<a href=\"../pkg1/RegClass.html#%3Cinit%3E(java.lang.String,int)\">");
+
+        // Test some methods
+        checkOutput("pkg1/RegClass.html", true,
+                "<a id=\"_methodInClass(java.lang.String)\">",
+                "<a href=\"../pkg1/RegClass.html#_methodInClass(java.lang.String)\">",
+                "<a id=\"method()\">",
+                "<a href=\"../pkg1/RegClass.html#method()\">",
+                "<a id=\"foo(java.util.Map)\">",
+                "<a href=\"../pkg1/RegClass.html#foo(java.util.Map)\">",
+                "<a id=\"methodInCla$s(java.lang.String[])\">",
+                "<a href=\"../pkg1/RegClass.html#methodInCla$s(java.lang.String%5B%5D)\">",
+                "<a id=\"_methodInClas$(java.lang.String,int)\">",
+                "<a href=\"../pkg1/RegClass.html#_methodInClas$(java.lang.String,int)\">",
+                "<a id=\"methodD(pkg1.RegClass.$A)\">",
+                "<a href=\"../pkg1/RegClass.html#methodD(pkg1.RegClass.$A)\">",
+                "<a id=\"methodD(pkg1.RegClass.D[])\">",
+                "<a href=\"../pkg1/RegClass.html#methodD(pkg1.RegClass.D%5B%5D)\">");
+
+        checkOutput("pkg1/DeprMemClass.html", true,
+                "<a id=\"$method_In_Class()\">",
+                "<a href=\"../pkg1/DeprMemClass.html#$method_In_Class()\">");
+
+        // Test enum
+        checkOutput("pkg1/RegClass.Te$t_Enum.html", true,
+                "<a id=\"$FLD2\">",
+                "<a href=\"../pkg1/RegClass.Te$t_Enum.html#$FLD2\">");
+
+        // Test nested class
+        checkOutput("pkg1/RegClass._NestedClas$.html", true,
+                "<a id=\"&lt;init&gt;()\">",
+                "<a href=\"../pkg1/RegClass._NestedClas$.html#%3Cinit%3E()\">");
+
+        // Test class use page
+        checkOutput("pkg1/class-use/DeprMemClass.html", true,
+                "<a href=\"../../pkg1/RegClass.html#d____mc\">");
+
+        // Test deprecated list page
+        checkOutput("deprecated-list.html", true,
+                "<a href=\"pkg1/DeprMemClass.html#_field_In_Class\">",
+                "<a href=\"pkg1/DeprMemClass.html#$method_In_Class()\">");
+
+        // Test constant values page
+        checkOutput("constant-values.html", true,
+                "<a href=\"pkg1/RegClass.html#S_$$$$$INT\">");
+
+        // Test serialized form page
+        checkOutput("serialized-form.html", true,
+                //This is the marker for the link that appears in the pkg1.RegClass.html page
+                "<a id=\"pkg1.RegClass\">");
+
+        // Test member name index page
+        checkOutput("index-all.html", true,
+                "<a id=\"I:$\">",
+                "<a href=\"#I:$\">$",
+                "<a href=\"#I:_\">_");
+    }
+
+    /**
+     * The following test is somewhat simplistic, but it is useful
+     * in conjunction with the W3C Validation Service at https://validator.w3.org/nu/#file
+     * @param base A working directory for this method, in which some UTF-8 source files
+     *      will be generated
+     * @throws IOException if there is a problem generating the source files
+     */
+    @Test
+    void testNonAscii(Path base) throws IOException {
+        Path src = base.resolve("src");
+        tb.writeJavaFiles(src,
+                "package p; public class Def {\n"
+                + "    public int \u00e0\u00e9;\n"              // a`e'
+                + "    public void \u00c0\u00c9() { }\n"        // A`E'
+                + "    public int \u03b1\u03b2\u03b3;\n"        // alpha beta gamma
+                + "    public void \u0391\u0392\u0393() { }\n"  // ALPHA BETA GAMMA
+                + "}",
+                "package p; \n"
+                + "/**\n"
+                + " * {@link Def#\u00e0\u00e9 &agrave;&eacute;}<br>\n"
+                + " * {@link Def#\u00c0\u00c9() &Agrave;&Eacute;}<br>\n"
+                + " * {@link Def#\u03b1\u03b2\u03b3 &alpha;&beta;&gamma;}<br>\n"
+                + " * {@link Def#\u0391\u0392\u0393() &Alpha;&Beta;&Gamma;}<br>\n"
+                + " */\n"
+                + "public class Ref { }");
+
+        javadoc("-d", "out-nonAscii",
+                "-sourcepath", src.toString(),
+                "-html5",
+                "-encoding", "utf-8",
+                "p");
+        checkExit(Exit.OK);
+
+        checkOutput("p/Def.html", true,
+                "<a id=\"\u00e0\u00e9\">",
+                "<a id=\"\u00c0\u00c9()\">",
+                "<a id=\"\u03b1\u03b2\u03b3\">",
+                "<a id=\"\u0391\u0392\u0393()\">");
+
+        checkOutput("p/Ref.html", true,
+                "<a href=\"../p/Def.html#%C3%A0%C3%A9\"><code>&agrave;&eacute;</code></a>",
+                "<a href=\"../p/Def.html#%C3%80%C3%89()\"><code>&Agrave;&Eacute;</code></a>",
+                "<a href=\"../p/Def.html#%CE%B1%CE%B2%CE%B3\"><code>&alpha;&beta;&gamma;</code></a>",
+                "<a href=\"../p/Def.html#%CE%91%CE%92%CE%93()\"><code>&Alpha;&Beta;&Gamma;</code></a>");
+
+    }
 }
--- a/test/langtools/jdk/javadoc/doclet/testDocEncoding/TestDocEncoding.java	Thu Oct 05 22:05:22 2017 +0200
+++ b/test/langtools/jdk/javadoc/doclet/testDocEncoding/TestDocEncoding.java	Thu Oct 12 22:05:47 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -37,6 +37,8 @@
  * @run main TestDocEncoding
  */
 
+import java.nio.charset.Charset;
+
 public class TestDocEncoding extends JavadocTester {
 
     public static void main(String... args) throws Exception {
@@ -53,6 +55,13 @@
                 "pkg");
         checkExit(Exit.OK);
 
+        checkOutput("stylesheet.css", true,
+                "body {\n"
+                + "    background-color:#ffffff;");
+
+        // reset the charset, for a negative test, that the -docencoding
+        // was effective and that the output is not in UTF-8.
+        charset = Charset.forName("UTF-8");
         checkOutput("stylesheet.css", false,
                 "body {\n"
                 + "    background-color:#ffffff;");
--- a/test/langtools/jdk/javadoc/doclet/testSearch/TestSearch.java	Thu Oct 05 22:05:22 2017 +0200
+++ b/test/langtools/jdk/javadoc/doclet/testSearch/TestSearch.java	Thu Oct 12 22:05:47 2017 +0200
@@ -23,7 +23,8 @@
 
 /*
  * @test
- * @bug 8141492 8071982 8141636 8147890 8166175 8168965 8176794 8175218 8147881 8181622 8182263 8074407
+ * @bug 8141492 8071982 8141636 8147890 8166175 8168965 8176794 8175218 8147881
+ *      8181622 8182263 8074407 8187521
  * @summary Test the search feature of javadoc.
  * @author bpatel
  * @library ../lib
@@ -64,7 +65,7 @@
         checkExit(Exit.OK);
         checkInvalidUsageIndexTag();
         checkSearchOutput(true);
-        checkSingleIndex(true);
+        checkSingleIndex(true, false);
         checkSingleIndexSearchTagDuplication();
         checkJqueryAndImageFiles(true);
         checkSearchJS();
@@ -86,7 +87,7 @@
         checkExit(Exit.ERROR);
         checkDocLintErrors();
         checkSearchOutput(true);
-        checkSingleIndex(true);
+        checkSingleIndex(true, false);
         checkSingleIndexSearchTagDuplication();
         checkJqueryAndImageFiles(true);
         checkSearchJS();
@@ -128,7 +129,7 @@
                 "-use", "pkg", "pkg1", "pkg2", "pkg3");
         checkExit(Exit.OK);
         checkSearchOutput(true);
-        checkSingleIndex(true);
+        checkSingleIndex(true, true);
         checkSingleIndexSearchTagDuplication();
         checkJqueryAndImageFiles(true);
         checkSearchJS();
@@ -280,7 +281,9 @@
                 "<div class=\"fixedNav\">");
     }
 
-    void checkSingleIndex(boolean expectedOutput) {
+    void checkSingleIndex(boolean expectedOutput, boolean html5) {
+        String html_span_see_span = html5 ? "html%3Cspan%3Esee%3C/span%3E" : "html-span-see-/span-";
+
         // Test for search tags markup in index file.
         checkOutput("index-all.html", expectedOutput,
                 "<dt><span class=\"searchTagLink\"><a href=\"pkg/package-summary.html#phrasewithspaces\">"
@@ -313,7 +316,7 @@
                 + "#nested%7B@indexnested_tag_test%7D\">nested {@index nested_tag_test}</a></span> - "
                 + "Search tag in pkg.AnotherClass.ModalExclusionType.NO_EXCLUDE</dt>",
                 "<dt><span class=\"searchTagLink\"><a href=\"pkg/AnotherClass.ModalExclusionType.html"
-                + "#html-span-see-/span-\">html &lt;span&gt; see &lt;/span&gt;</a></span> - Search "
+                + "#" + html_span_see_span + "\">html &lt;span&gt; see &lt;/span&gt;</a></span> - Search "
                 + "tag in pkg.AnotherClass.ModalExclusionType.APPLICATION_EXCLUDE</dt>",
                 "<dt><span class=\"searchTagLink\"><a href=\"pkg/AnotherClass.html#quoted\">quoted</a>"
                 + "</span> - Search tag in pkg.AnotherClass.CONSTANT1</dt>",
--- a/test/langtools/jdk/jshell/ErrorTranslationTest.java	Thu Oct 05 22:05:22 2017 +0200
+++ b/test/langtools/jdk/jshell/ErrorTranslationTest.java	Thu Oct 12 22:05:47 2017 +0200
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @bug 8188225
  * @summary Tests for shell error translation
  * @modules jdk.compiler/com.sun.tools.javac.api
  *          jdk.compiler/com.sun.tools.javac.main
@@ -59,6 +60,13 @@
         );
     }
 
+    public void testlvtiErrors() {
+        test(
+                a -> assertDiagnostic(a, "var broken = () -> {};", newExpectedDiagnostic(0, 22, 0, -1, -1, Diagnostic.Kind.ERROR)),
+                a -> assertDiagnostic(a, "void t () { var broken = () -> {}; }", newExpectedDiagnostic(12, 34, 0, -1, -1, Diagnostic.Kind.ERROR))
+        );
+    }
+
     public void testWarnings() {
         List<ReplTest> list = new ArrayList<>();
         ExpectedDiagnostic[] diagnostics = new ExpectedDiagnostic[]{
@@ -117,19 +125,16 @@
             }
             String kind = getKind(expectedDiagnostic.getKind());
             assertEquals(lines[0], kind);
-            String source;
-            String markingLine;
-            switch (expectedDiagnostic.getKind()) {
-                case ERROR:
-                case WARNING:
-                    source = lines[2];
-                    markingLine = lines[3];
-                    break;
-                default:
-                    throw new AssertionError("Unsupported diagnostic kind: " + expectedDiagnostic.getKind());
+            boolean found = false;
+            for (int i = 0; i < lines.length; i++) {
+                if (lines[i].endsWith(expectedSource)) {
+                    assertEquals(lines[i + 1], expectedMarkingLine, "Input: " + expectedSource + ", marking line: ");
+                    found = true;
+                }
             }
-            assertTrue(source.endsWith(expectedSource), "Expected: " + expectedSource + ", found: " + source);
-            assertEquals(markingLine, expectedMarkingLine, "Input: " + expectedSource + ", marking line: ");
+            if (!found) {
+                throw new AssertionError("Did not find: " + expectedSource + " in: " + s);
+            }
         };
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/8169345/T8169345a.java	Thu Oct 12 22:05:47 2017 +0200
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8169345
+ * @summary javac crash when local from enclosing context is captured multiple times
+ */
+
+public class T8169345a {
+    void test() {
+        Object o = new Object();
+        class Local1 {
+            Object test1() {
+                return o;
+            }
+        }
+        class Local2 {
+            void test2() {
+                Object o = new Object();
+                class Local3 extends Local1 {
+                    Object test3() {
+                        return o;
+                    }
+                }
+            }
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        Class.forName("T8169345a$1Local1");
+        Class.forName("T8169345a$1Local2$1Local3");
+        Class.forName("T8169345a$1Local2");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/8169345/T8169345b.java	Thu Oct 12 22:05:47 2017 +0200
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @bug 8169345
+ * @summary javac crash when local from enclosing context is captured multiple times
+ */
+
+public class T8169345b {
+    void test() {
+        Object o = new Object();
+        class Local1 {
+            Object test1() {
+                return o;
+            }
+        }
+        class Local2 {
+            void test2() {
+                Object o = new Object();
+                class Local3 {
+                    Object test3() {
+                        return o;
+                    }
+                }
+            }
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        Class.forName("T8169345b$1Local1");
+        Class.forName("T8169345b$1Local2$1Local3");
+        Class.forName("T8169345b$1Local2");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/8169345/T8169345c.java	Thu Oct 12 22:05:47 2017 +0200
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @bug 8169345
+ * @summary javac crash when local from enclosing context is captured multiple times
+ * @compile T8169345c.java
+ */
+
+class T8169345c {
+    void test() {
+        final int b;
+        b = 10;
+        class Local1 {
+            public String toString() {
+                return "" + b;
+            }
+        }
+        class Local2 {
+            void test() {
+                final int b;
+                b = 20;
+                class DeepLocal extends Local1 {
+                    public String toString() {
+                        return "" + b;
+                    }
+                }
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/tree/VarTree.java	Thu Oct 12 22:05:47 2017 +0200
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8188225
+ * @summary Check that variables of type var have a consistent model
+ * @modules jdk.compiler/com.sun.tools.javac.api
+ */
+
+import com.sun.source.tree.CompilationUnitTree;
+import com.sun.tools.javac.api.JavacTaskImpl;
+
+import java.io.IOException;
+import java.net.URI;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileObject;
+import javax.tools.SimpleJavaFileObject;
+import javax.tools.ToolProvider;
+
+import com.sun.source.tree.VariableTree;
+import com.sun.source.util.TreeScanner;
+import com.sun.source.util.Trees;
+
+public class VarTree {
+    private final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
+
+    public static void main(String... args) throws Exception {
+        VarTree test = new VarTree();
+        test.run("|var testVar = 0;| ",
+                 "int testVar = 0");
+        test.run("|var testVar = 0;| undef undef;",
+                 "int testVar = 0");
+        test.run("|final var testVar = 0;| ",
+                 "final int testVar = 0");
+        test.run("for (|var testVar| : java.util.Arrays.asList(0, 1)) {}",
+                 "java.lang.Integer testVar");
+        test.run("for (|final var testVar| : java.util.Arrays.asList(0, 1)) {}",
+                 "final java.lang.Integer testVar");
+        test.run("java.util.function.Consumer<String> c = |testVar| -> {};",
+                 "java.lang.String testVar");
+        test.run("java.util.function.Consumer<String> c = (|testVar|) -> {};",
+                 "java.lang.String testVar");
+    }
+
+    void run(String code, String expected) throws IOException {
+        String[] parts = code.split("\\|");
+
+        if (parts.length != 3) {
+            throw new IllegalStateException("Incorrect number of markers.");
+        }
+
+        String prefix = "public class Test { void test() { ";
+        String src = prefix + parts[0] + parts[1] + parts[2] + " } }";
+
+        JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, d -> {},
+                                                        List.of("--should-stop:at=FLOW"),
+                                                        null, Arrays.asList(new MyFileObject(src)));
+
+        Iterable<? extends CompilationUnitTree> units = ct.parse();
+        ct.analyze();
+
+        Trees trees = Trees.instance(ct);
+
+        for (CompilationUnitTree cut : units) {
+            new TreeScanner<Void, Void>() {
+                @Override
+                public Void visitVariable(VariableTree node, Void p) {
+                    if (node.getName().contentEquals("testVar")) {
+                        if (!expected.equals(node.toString())) {
+                            throw new AssertionError("Unexpected tree: " + node.toString());
+                        }
+
+                        int start = (int) trees.getSourcePositions().getStartPosition(cut, node);
+                        int end   = (int) trees.getSourcePositions().getEndPosition(cut, node);
+
+                        String snip = src.substring(start, end);
+
+                        if (start != prefix.length() + parts[0].length() || end != prefix.length() + parts[0].length() + parts[1].length()) {
+                            throw new AssertionError("Unexpected span: " + snip);
+                        }
+
+                        int typeStart = (int) trees.getSourcePositions().getStartPosition(cut, node.getType());
+                        int typeEnd   = (int) trees.getSourcePositions().getEndPosition(cut, node.getType());
+
+                        if (typeStart != (-1) && typeEnd != (-1)) {
+                            throw new AssertionError("Unexpected type position: " + typeStart + ", " + typeEnd);
+                        }
+                    }
+                    return super.visitVariable(node, p);
+                }
+
+            }.scan(cut, null);
+        }
+    }
+    class MyFileObject extends SimpleJavaFileObject {
+
+        private String text;
+
+        public MyFileObject(String text) {
+            super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
+            this.text = text;
+        }
+
+        @Override
+        public CharSequence getCharContent(boolean ignoreEncodingErrors) {
+            return text;
+        }
+    }
+}