Merge
authorprr
Tue, 17 Oct 2017 14:33:32 -0700
changeset 47390 1a818b395dba
parent 47389 18c850407be9 (current diff)
parent 47357 74700c8e39e9 (diff)
child 47391 a29594840024
Merge
make/corba/Makefile
make/hotspot/copy/Copy-java.base.gmk
test/langtools/tools/javac/lib/combo/ReusableContext.java
--- a/.hgtags	Mon Oct 16 08:47:59 2017 -0700
+++ b/.hgtags	Tue Oct 17 14:33:32 2017 -0700
@@ -451,3 +451,4 @@
 3b201865d5c1f244f555cad58da599c9261286d8 jdk-10+24
 8eb5e3ccee560c28ac9b1df2670adac2b3d36fad jdk-10+25
 1129253d3bc728a2963ba411ab9dd1adf358fb6b jdk-10+26
+b87d7b5d5dedc1185e5929470f945b7378cdb3ad jdk-10+27
--- a/bin/jib.sh	Mon Oct 16 08:47:59 2017 -0700
+++ b/bin/jib.sh	Tue Oct 17 14:33:32 2017 -0700
@@ -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/Bundles.gmk	Mon Oct 16 08:47:59 2017 -0700
+++ b/make/Bundles.gmk	Tue Oct 17 14:33:32 2017 -0700
@@ -70,9 +70,14 @@
   $$(call SetIfEmpty, $1_UNZIP_DEBUGINFO, false)
 
   $(BUNDLES_OUTPUTDIR)/$$($1_BUNDLE_NAME): $$($1_FILES)
+        # If any of the files contain a space in the file name, CacheFind
+        # will have replaced it with ?. Tar does not accept that so need to
+        # switch it back.
 	$$(foreach d, $$($1_BASE_DIRS), \
 	  $$(eval $$(call ListPathsSafely, \
 	      $1_$$d_RELATIVE_FILES, $$($1_$$d_LIST_FILE))) \
+	  $$(CAT) $$($1_$$d_LIST_FILE) | $$(TR) '?' ' ' > $$($1_$$d_LIST_FILE).tmp \
+	      && $(MV) $$($1_$$d_LIST_FILE).tmp $$($1_$$d_LIST_FILE) $$(NEWLINE) \
 	)
 	$$(call MakeDir, $$(@D))
         ifneq ($$($1_SPECIAL_INCLUDES), )
--- a/make/CompileDemos.gmk	Mon Oct 16 08:47:59 2017 -0700
+++ b/make/CompileDemos.gmk	Tue Oct 17 14:33:32 2017 -0700
@@ -37,9 +37,13 @@
 include TextFileProcessing.gmk
 include ZipArchive.gmk
 
+# Hook to include the corresponding custom file, if present.
+$(eval $(call IncludeCustomExtension, CompileDemos-pre.gmk))
+
 # Prepare the find cache.
-$(eval $(call FillCacheFind, $(wildcard $(TOPDIR)/src/demo \
-    $(TOPDIR)/src/*/demo)))
+DEMO_SRC_DIRS += $(TOPDIR)/src/demo
+
+$(eval $(call FillCacheFind, $(wildcard $(DEMO_SRC_DIRS))))
 
 # Append demo goals to this variable.
 TARGETS =
@@ -295,7 +299,7 @@
   $(eval $(call SetupCopyFiles, COPY_TO_TEST_IMAGE, \
       SRC := $(SUPPORT_OUTPUTDIR)/demos/image, \
       DEST := $(TEST_IMAGE_DIR)/jdk/demos, \
-      FILES := $(call DoubleDollar, $(call CacheFind, $(SUPPORT_OUTPUTDIR)/demos/image)), \
+      FILES := $(call CacheFind, $(SUPPORT_OUTPUTDIR)/demos/image), \
   ))
 
   IMAGES_TARGETS := $(COPY_TO_TEST_IMAGE)
@@ -303,7 +307,7 @@
 
 ################################################################################
 # Hook to include the corresponding custom file, if present.
-$(eval $(call IncludeCustomExtension, CompileDemos.gmk))
+$(eval $(call IncludeCustomExtension, CompileDemos-post.gmk))
 
 all: $(TARGETS)
 images: $(IMAGES_TARGETS)
--- a/make/Images.gmk	Mon Oct 16 08:47:59 2017 -0700
+++ b/make/Images.gmk	Tue Oct 17 14:33:32 2017 -0700
@@ -324,9 +324,8 @@
 
   DEMO_FILES := \
       $(if $(wildcard $(SUPPORT_OUTPUTDIR)/demos/image), \
-        $(call DoubleDollar, \
         $(shell $(FIND) $(SUPPORT_OUTPUTDIR)/demos/image \
-            -type f -a ! \( -name "_the*" -o -name "javac_state" \) )) \
+            -type f -a ! \( -name "_the*" -o -name "javac_state" \) ) \
       )
 
   ifeq ($(ZIP_EXTERNAL_DEBUG_SYMBOLS), true)
--- a/make/Init.gmk	Mon Oct 16 08:47:59 2017 -0700
+++ b/make/Init.gmk	Tue Oct 17 14:33:32 2017 -0700
@@ -267,8 +267,9 @@
 	  $(ECHO) "Re-running configure using default settings"
         endif
 	( cd $(OUTPUTDIR) && PATH="$(ORIGINAL_PATH)" \
+	    CUSTOM_ROOT="$(CUSTOM_ROOT)" \
 	    CUSTOM_CONFIG_DIR="$(CUSTOM_CONFIG_DIR)" \
-	    $(BASH) $(CONFIGURE_CMD) $(CONFIGURE_COMMAND_LINE) )
+	    $(BASH) $(TOPDIR)/configure $(CONFIGURE_COMMAND_LINE) )
 
   ##############################################################################
   # The main target, for delegating into Main.gmk
--- a/make/InitSupport.gmk	Mon Oct 16 08:47:59 2017 -0700
+++ b/make/InitSupport.gmk	Tue Oct 17 14:33:32 2017 -0700
@@ -70,10 +70,10 @@
       $(subst \ ,\#,$(MAKEOVERRIDES))))
 
   # Setup information about available configurations, if any.
-  ifeq ($(CUSTOM_BUILD_DIR), )
+  ifneq ($(CUSTOM_ROOT), )
+    build_dir=$(CUSTOM_ROOT)/build
+  else
     build_dir=$(topdir)/build
-  else
-    build_dir=$(CUSTOM_BUILD_DIR)
   endif
   all_spec_files=$(wildcard $(build_dir)/*/spec.gmk)
   # Extract the configuration names from the path
@@ -227,7 +227,11 @@
     else
       # Use spec.gmk files in the build output directory
       ifeq ($$(all_spec_files),)
-        $$(info Error: No configurations found for $$(topdir).)
+        ifneq ($(CUSTOM_ROOT), )
+          $$(info Error: No configurations found for $$(CUSTOM_ROOT).)
+        else
+          $$(info Error: No configurations found for $$(topdir).)
+        endif
         $$(info Please run 'bash configure' to create a configuration.)
         $$(info )
         $$(error Cannot continue)
--- a/make/MacBundles.gmk	Mon Oct 16 08:47:59 2017 -0700
+++ b/make/MacBundles.gmk	Tue Oct 17 14:33:32 2017 -0700
@@ -49,22 +49,17 @@
     BUNDLE_VENDOR := $(COMPANY_NAME)
   endif
 
-  JDK_FILE_LIST := $(shell $(FIND) $(JDK_IMAGE_DIR))
-  JRE_FILE_LIST := $(shell $(FIND) $(JRE_IMAGE_DIR))
-
-  JDK_TARGET_LIST := $(subst $(JDK_IMAGE_DIR)/,$(JDK_MACOSX_CONTENTS_DIR)/Home/,$(JDK_FILE_LIST))
-  JRE_TARGET_LIST := $(subst $(JRE_IMAGE_DIR)/,$(JRE_MACOSX_CONTENTS_DIR)/Home/,$(JRE_FILE_LIST))
+  $(eval $(call SetupCopyFiles, COPY_JDK_IMAGE, \
+      SRC := $(JDK_IMAGE_DIR), \
+      DEST := $(JDK_MACOSX_CONTENTS_DIR)/Home, \
+      FILES := $(call CacheFind, $(JDK_IMAGE_DIR)), \
+  ))
 
-  # Copy empty directories (jre/lib/applet).
-  $(JDK_MACOSX_CONTENTS_DIR)/Home/%: $(JDK_IMAGE_DIR)/%
-	$(call LogInfo, Copying $(patsubst $(OUTPUTDIR)/%,%,$@))
-	$(MKDIR) -p $(@D)
-	if [ -d "$<" ]; then $(MKDIR) -p $@; else $(CP) -f -R -P '$<' '$@'; fi
-
-  $(JRE_MACOSX_CONTENTS_DIR)/Home/%: $(JRE_IMAGE_DIR)/%
-	$(call LogInfo, Copying $(patsubst $(OUTPUTDIR)/%,%,$@))
-	$(MKDIR) -p $(@D)
-	if [ -d "$<" ]; then $(MKDIR) -p $@; else $(CP) -f -R -P '$<' '$@'; fi
+  $(eval $(call SetupCopyFiles, COPY_JRE_IMAGE, \
+      SRC := $(JRE_IMAGE_DIR), \
+      DEST := $(JRE_MACOSX_CONTENTS_DIR)/Home, \
+      FILES := $(call CacheFind, $(JRE_IMAGE_DIR)), \
+  ))
 
   $(JDK_MACOSX_CONTENTS_DIR)/MacOS/libjli.dylib:
 	$(call LogInfo, Creating link $(patsubst $(OUTPUTDIR)/%,%,$@))
@@ -102,11 +97,11 @@
           @@VENDOR@@ => $(BUNDLE_VENDOR) , \
   ))
 
-  jdk-bundle: $(JDK_TARGET_LIST) $(JDK_MACOSX_CONTENTS_DIR)/MacOS/libjli.dylib \
+  jdk-bundle: $(COPY_JDK_IMAGE) $(JDK_MACOSX_CONTENTS_DIR)/MacOS/libjli.dylib \
       $(BUILD_JDK_PLIST)
 	$(SETFILE) -a B $(dir $(JDK_MACOSX_CONTENTS_DIR))
 
-  jre-bundle: $(JRE_TARGET_LIST) $(JRE_MACOSX_CONTENTS_DIR)/MacOS/libjli.dylib \
+  jre-bundle: $(COPY_JRE_IMAGE) $(JRE_MACOSX_CONTENTS_DIR)/MacOS/libjli.dylib \
       $(BUILD_JRE_PLIST)
 	$(SETFILE) -a B $(dir $(JRE_MACOSX_CONTENTS_DIR))
 
--- a/make/RunTests.gmk	Mon Oct 16 08:47:59 2017 -0700
+++ b/make/RunTests.gmk	Tue Oct 17 14:33:32 2017 -0700
@@ -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/basics.m4	Mon Oct 16 08:47:59 2017 -0700
+++ b/make/autoconf/basics.m4	Tue Oct 17 14:33:32 2017 -0700
@@ -766,13 +766,10 @@
   AC_ARG_WITH(conf-name, [AS_HELP_STRING([--with-conf-name],
       [use this as the name of the configuration @<:@generated from important configuration options@:>@])],
       [ CONF_NAME=${with_conf_name} ])
-  AC_ARG_WITH(output-base-dir, [AS_HELP_STRING([--with-output-base-dir],
-      [override the default output base directory @<:@./build@:>@])],
-      [ OUTPUT_BASE=${with_output_base_dir} ], [ OUTPUT_BASE="$TOPDIR/build" ] )
 
   # Test from where we are running configure, in or outside of src root.
   AC_MSG_CHECKING([where to store configuration])
-  if test "x$CURDIR" = "x$TOPDIR" || test "x$CURDIR" = "x$TOPDIR/common" \
+  if test "x$CURDIR" = "x$TOPDIR" || test "x$CURDIR" = "x$CUSTOM_ROOT" \
       || test "x$CURDIR" = "x$TOPDIR/make/autoconf" \
       || test "x$CURDIR" = "x$TOPDIR/make" ; then
     # We are running configure from the src root.
@@ -783,7 +780,12 @@
     else
       AC_MSG_RESULT([in build directory with custom name])
     fi
-    OUTPUTDIR="${OUTPUT_BASE}/${CONF_NAME}"
+
+    if test "x$CUSTOM_ROOT" != x; then
+      OUTPUTDIR="${CUSTOM_ROOT}/build/${CONF_NAME}"
+    else
+      OUTPUTDIR="${TOPDIR}/build/${CONF_NAME}"
+    fi
     $MKDIR -p "$OUTPUTDIR"
     if test ! -d "$OUTPUTDIR"; then
       AC_MSG_ERROR([Could not create build directory $OUTPUTDIR])
--- a/make/autoconf/boot-jdk.m4	Mon Oct 16 08:47:59 2017 -0700
+++ b/make/autoconf/boot-jdk.m4	Tue Oct 17 14:33:32 2017 -0700
@@ -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/configure	Mon Oct 16 08:47:59 2017 -0700
+++ b/make/autoconf/configure	Tue Oct 17 14:33:32 2017 -0700
@@ -23,19 +23,18 @@
 #
 
 if test "x$1" != xCHECKME; then
-  echo "WARNING: Calling the wrapper script directly is deprecated and unsupported."
-  echo "Not all features of configure will be available."
+  echo "ERROR: Calling this wrapper script directly is not supported."
   echo "Use the 'configure' script in the top-level directory instead."
-  TOPDIR=$(cd $(dirname $0)/../.. > /dev/null && pwd)
-else
-  # Now the next argument is the absolute top-level directory path.
-  # The TOPDIR variable is passed on to configure.ac.
-  TOPDIR="$2"
-  # Remove these two arguments to get to the user supplied arguments
-  shift
-  shift
+  exit 1
 fi
 
+# The next argument is the absolute top-level directory path.
+# The TOPDIR variable is passed on to configure.ac.
+TOPDIR="$2"
+# Remove these two arguments to get to the user supplied arguments
+shift
+shift
+
 if test "x$BASH" = x; then
   echo "Error: This script must be run using bash." 1>&2
   exit 1
--- a/make/autoconf/generated-configure.sh	Mon Oct 16 08:47:59 2017 -0700
+++ b/make/autoconf/generated-configure.sh	Tue Oct 17 14:33:32 2017 -0700
@@ -1134,7 +1134,6 @@
 with_extra_path
 with_sdk_name
 with_conf_name
-with_output_base_dir
 with_output_sync
 with_default_make_target
 enable_headless_only
@@ -2043,7 +2042,6 @@
   --with-sdk-name         use the platform SDK of the given name. [macosx]
   --with-conf-name        use this as the name of the configuration [generated
                           from important configuration options]
-  --with-output-base-dir  override the default output base directory [./build]
   --with-output-sync      set make output sync type if supported by make.
                           [recurse]
   --with-default-make-target
@@ -5117,7 +5115,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=1508136203
 
 ###############################################################################
 #
@@ -17554,18 +17552,10 @@
 fi
 
 
-# Check whether --with-output-base-dir was given.
-if test "${with_output_base_dir+set}" = set; then :
-  withval=$with_output_base_dir;  OUTPUT_BASE=${with_output_base_dir}
-else
-   OUTPUT_BASE="$TOPDIR/build"
-fi
-
-
   # Test from where we are running configure, in or outside of src root.
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking where to store configuration" >&5
 $as_echo_n "checking where to store configuration... " >&6; }
-  if test "x$CURDIR" = "x$TOPDIR" || test "x$CURDIR" = "x$TOPDIR/common" \
+  if test "x$CURDIR" = "x$TOPDIR" || test "x$CURDIR" = "x$CUSTOM_ROOT" \
       || test "x$CURDIR" = "x$TOPDIR/make/autoconf" \
       || test "x$CURDIR" = "x$TOPDIR/make" ; then
     # We are running configure from the src root.
@@ -17578,7 +17568,12 @@
       { $as_echo "$as_me:${as_lineno-$LINENO}: result: in build directory with custom name" >&5
 $as_echo "in build directory with custom name" >&6; }
     fi
-    OUTPUTDIR="${OUTPUT_BASE}/${CONF_NAME}"
+
+    if test "x$CUSTOM_ROOT" != x; then
+      OUTPUTDIR="${CUSTOM_ROOT}/build/${CONF_NAME}"
+    else
+      OUTPUTDIR="${TOPDIR}/build/${CONF_NAME}"
+    fi
     $MKDIR -p "$OUTPUTDIR"
     if test ! -d "$OUTPUTDIR"; then
       as_fn_error $? "Could not create build directory $OUTPUTDIR" "$LINENO" 5
@@ -31483,6 +31478,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 +66266,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 +66326,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/autoconf/spec.gmk.in	Mon Oct 16 08:47:59 2017 -0700
+++ b/make/autoconf/spec.gmk.in	Tue Oct 17 14:33:32 2017 -0700
@@ -842,8 +842,6 @@
 TEST_BUNDLE :=  $(BUNDLES_OUTPUTDIR)/$(TEST_BUNDLE_NAME)
 DOCS_BUNDLE :=  $(BUNDLES_OUTPUTDIR)/$(DOCS_BUNDLE_NAME)
 
-CONFIGURE_CMD := $(TOPDIR)/configure
-
 # This macro is called to allow inclusion of closed source counterparts.
 # Unless overridden in closed sources, it expands to nothing.
 # Usage: This function is called in an open makefile, with the following
--- a/make/common/MakeBase.gmk	Mon Oct 16 08:47:59 2017 -0700
+++ b/make/common/MakeBase.gmk	Tue Oct 17 14:33:32 2017 -0700
@@ -463,11 +463,22 @@
 endef
 
 ################################################################################
+# Replace question marks with space in string. This macro needs to be called on
+# files from CacheFind in case any of them contains space in their file name,
+# since CacheFind replaces space with ?.
+# Param 1 - String to replace in
+DecodeSpace = \
+    $(subst ?,$(SPACE),$(strip $1))
+EncodeSpace = \
+    $(subst $(SPACE),?,$(strip $1))
+
+################################################################################
 # Make directory without forking mkdir if not needed
 # 1: List of directories to create
 MakeDir = \
     $(strip \
-        $(eval MakeDir_dirs_to_make := $(strip $(foreach d, $1, $(if $(wildcard $d), , $d)))) \
+        $(eval MakeDir_dirs_to_make := $(strip $(foreach d, $1, $(if $(wildcard $d), , \
+            "$(call DecodeSpace, $d)")))) \
         $(if $(MakeDir_dirs_to_make), $(shell $(MKDIR) -p $(MakeDir_dirs_to_make))) \
     )
 
@@ -479,6 +490,7 @@
     $(if $($(strip $1)),,$(eval $(strip $1) := $2))
 
 ################################################################################
+# All install-file and related macros automatically call DecodeSpace when needed.
 
 ifeq ($(OPENJDK_TARGET_OS),solaris)
   # On Solaris, if the target is a symlink and exists, cp won't overwrite.
@@ -487,19 +499,21 @@
   # If the source and target parent directories are the same, recursive copy doesn't work
   # so we fall back on regular copy, which isn't preserving symlinks.
   define install-file
-	$(MKDIR) -p '$(@D)'
-	$(RM) '$@'
-	if [ "$(@D)" != "$(<D)" ]; then \
-	  $(CP) -f -r -P '$<' '$(@D)'; \
-	  if [ "$(@F)" != "$(<F)" ]; then \
-	    $(MV) '$(@D)/$(<F)' '$@'; \
+	$(call MakeDir, $(@D))
+	$(RM) '$(call DecodeSpace, $@)'
+	if [ '$(call DecodeSpace, $(dir $@))' != \
+	    '$(call DecodeSpace, $(dir $(call EncodeSpace, $<)))' ]; then \
+	  $(CP) -f -r -P '$(call DecodeSpace, $<)' '$(call DecodeSpace, $(@D))'; \
+	  if [ '$(call DecodeSpace, $(@F))' != \
+	      '$(call DecodeSpace, $(notdir $(call EncodeSpace, $(<))))' ]; then \
+	    $(MV) '$(call DecodeSpace, $(@D)/$(<F))' '$(call DecodeSpace, $@)'; \
 	  fi; \
 	else \
-	  if [ -L '$<' ]; then \
+	  if [ -L '$(call DecodeSpace, $<)' ]; then \
 	    $(ECHO) "Source file is a symlink and target is in the same directory: $< $@" ; \
 	    exit 1; \
 	  fi; \
-	  $(CP) -f '$<' '$@'; \
+	  $(CP) -f '$(call DecodeSpace, $<)' '$(call DecodeSpace, $@)'; \
 	fi
   endef
 else ifeq ($(OPENJDK_TARGET_OS),macosx)
@@ -512,22 +526,22 @@
   # If copying a soft link to a directory, need to delete the target first to avoid
   # weird errors.
   define install-file
-	$(MKDIR) -p '$(@D)'
-	$(RM) '$@'
-	$(CP) -fRP '$<' '$@'
-	if [ -n "`$(XATTR) -l '$@'`" ]; then $(XATTR) -c '$@'; fi
+	$(call MakeDir, $(@D))
+	$(RM) '$(call DecodeSpace, $@)'
+	$(CP) -fRP '$(call DecodeSpace, $<)' '$(call DecodeSpace, $@)'
+	if [ -n "`$(XATTR) -l '$(call DecodeSpace, $@)'`" ]; then $(XATTR) -c '$(call DecodeSpace, $@)'; fi
   endef
 else
   define install-file
 	$(call MakeDir, $(@D))
-	$(CP) -fP '$<' '$@'
+	$(CP) -fP '$(call DecodeSpace, $<)' '$(call DecodeSpace, $@)'
   endef
 endif
 
 # Variant of install file that does not preserve symlinks
 define install-file-nolink
 	$(call MakeDir, $(@D))
-	$(CP) -f '$<' '$@'
+	$(CP) -f '$(call DecodeSpace, $<)' '$(call DecodeSpace, $@)'
 endef
 
 ################################################################################
@@ -577,14 +591,14 @@
 # the unix emulation environment.
 define link-file-relative
 	$(call MakeDir, $(@D))
-	$(RM) $@
-	$(LN) -s $(call RelativePath, $<, $(@D)) $@
+	$(RM) '$(call DecodeSpace, $@)'
+	$(LN) -s '$(call DecodeSpace, $(call RelativePath, $<, $(@D)))' '$(call DecodeSpace, $@)'
 endef
 
 define link-file-absolute
 	$(call MakeDir, $(@D))
-	$(RM) $@
-	$(LN) -s $< $@
+	$(RM) '$(call DecodeSpace, $@)'
+	$(LN) -s '$(call DecodeSpace, $<)' '$(call DecodeSpace, $@)'
 endef
 
 ################################################################################
@@ -651,6 +665,13 @@
   # This macro can be called multiple times to add to the cache. Only finds files
   # with no filters.
   #
+  # Files containing space will get spaces replaced with ? because GNU Make
+  # cannot handle lists of files with space in them. By using ?, make will match
+  # the wildcard to space in many situations so we don't need to replace back
+  # to space on every use. While not a complete solution it does allow some uses
+  # of CacheFind to function with spaces in file names, including for
+  # SetupCopyFiles.
+  #
   # Needs to be called with $(eval )
   #
   # Even if the performance benifit is negligible on other platforms, keep the
@@ -668,7 +689,8 @@
     ifneq ($$(FIND_CACHE_NEW_DIRS), )
       # Remove any trailing slash from dirs in the cache dir list
       FIND_CACHE_DIRS += $$(patsubst %/,%, $$(FIND_CACHE_NEW_DIRS))
-      FIND_CACHE := $$(sort $$(FIND_CACHE) $$(shell $(FIND) $$(FIND_CACHE_NEW_DIRS) \( -type f -o -type l \) $2))
+      FIND_CACHE := $$(sort $$(FIND_CACHE) $$(shell $(FIND) $$(FIND_CACHE_NEW_DIRS) \
+          \( -type f -o -type l \) $2 | $(TR) ' ' '?'))
     endif
   endef
 
@@ -684,7 +706,8 @@
   # Param 2 - (optional) specialization. Normally "-a \( ... \)" expression.
   define CacheFind
     $(if $(filter-out $(addsuffix /%,- $(FIND_CACHE_DIRS)) $(FIND_CACHE_DIRS),$1), \
-      $(if $(wildcard $1), $(shell $(FIND) $1 \( -type f -o -type l \) $2)), \
+      $(if $(wildcard $1), $(shell $(FIND) $1 \( -type f -o -type l \) $2 \
+          | $(TR) ' ' '?')), \
       $(filter $(addsuffix /%,$(patsubst %/,%,$1)) $1,$(FIND_CACHE)))
   endef
 
@@ -693,7 +716,7 @@
   # Param 1 - Dirs to find in
   # Param 2 - (optional) specialization. Normally "-a \( ... \)" expression.
   define CacheFind
-    $(shell $(FIND) $1 \( -type f -o -type l \) $2)
+    $(shell $(FIND) $1 \( -type f -o -type l \) $2 | $(TR) ' ' '?')
   endef
 endif
 
@@ -707,7 +730,7 @@
   # 4 : Macro to call for copy operation
   # 5 : Action text to log
   $2: $1
-	$$(call LogInfo, $(strip $5) $$(patsubst $(OUTPUTDIR)/%,%,$$@))
+	$$(call LogInfo, $(strip $5) $$(patsubst $(OUTPUTDIR)/%,%,$$(call DecodeSpace, $$@)))
 	$$($$(strip $4))
 
   $3 += $2
@@ -758,10 +781,19 @@
   $1_SRC := $$(patsubst %/,%,$$($1_SRC))
   $1_DEST := $$(patsubst %/,%,$$($1_DEST))
 
+  # Need to wrap arguments in DoubleDollar because of the eval nested inside an
+  # eval macro body.
   $$(foreach f, $$(patsubst $$($1_SRC)/%,%,$$($1_FILES)), \
-      $$(eval $$(call AddFileToCopy, $$($1_SRC)/$$f, \
-      $$($1_DEST)/$$(call $$(strip $$($1_NAME_MACRO)),$$(if $$($1_FLATTEN),$$(notdir $$f),$$f)), \
-      $1, $$($1_MACRO), $$($1_LOG_ACTION))))
+    $$(eval $$(call AddFileToCopy, \
+        $$(call DoubleDollar, $$($1_SRC)/$$f), \
+        $$(call DoubleDollar, \
+            $$($1_DEST)/$$(call $$(strip $$($1_NAME_MACRO)),$$(if $$($1_FLATTEN),$$(notdir $$f),$$f)) \
+        ), \
+        $1, \
+        $$($1_MACRO), \
+        $$($1_LOG_ACTION) \
+    )) \
+  )
 
 endef
 
--- a/make/copy/Copy-java.base.gmk	Mon Oct 16 08:47:59 2017 -0700
+++ b/make/copy/Copy-java.base.gmk	Tue Oct 17 14:33:32 2017 -0700
@@ -247,3 +247,19 @@
 ))
 
 TARGETS += $(COPY_JDK_NOTICES)
+
+################################################################################
+# Optionally copy libffi.so.? into the the image
+
+ifeq ($(ENABLE_LIBFFI_BUNDLING), true)
+  $(eval $(call SetupCopyFiles, COPY_LIBFFI, \
+      FILES := $(LIBFFI_LIB_FILE), \
+      DEST := $(call FindLibDirForModule, $(MODULE)), \
+      FLATTEN := true, \
+      MACRO := install-file-nolink, \
+  ))
+
+  TARGETS += $(COPY_LIBFFI)
+endif
+
+################################################################################
--- a/make/corba/Makefile	Mon Oct 16 08:47:59 2017 -0700
+++ /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/hotspot/copy/Copy-java.base.gmk	Mon Oct 16 08:47:59 2017 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,81 +0,0 @@
-#
-# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.  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.
-#
-
-# These include files are currently being copied from the jdk repository for
-# historical reasons. Disable copying from here until this has been cleaned up.
-# The files in hotspot differ slightly from the corresponding files in jdk.
-# See JDK-8167078.
-
-INCLUDE_DST_DIR := $(SUPPORT_OUTPUTDIR)/modules_include/$(MODULE)
-
-################################################################################
-# Copy platform-independent .h files
-$(eval $(call SetupCopyFiles, COPY_INCLUDE_FILES, \
-    SRC := $(TOPDIR)/src/hotspot/share, \
-    DEST := $(INCLUDE_DST_DIR), \
-    FLATTEN := true, \
-    FILES := prims/jni.h code/jvmticmlr.h \
-))
-
-#TARGETS += $(COPY_INCLUDE_FILES)
-
-################################################################################
-# Copy jni_md.h
-
-# This might have been defined in a custom extension
-JNI_MD_H_SRC ?= $(TOPDIR)/src/hotspot/cpu/$(HOTSPOT_TARGET_CPU_ARCH)/jni_$(HOTSPOT_TARGET_CPU_ARCH).h
-
-ifeq ($(OPENJDK_TARGET_OS), macosx)
-  # NOTE: This should most likely be darwin, but the old hotspot build uses bsd
-  JNI_MD_SUBDIR := bsd
-else ifeq ($(OPENJDK_TARGET_OS), windows)
-  JNI_MD_SUBDIR := win32
-else
-  JNI_MD_SUBDIR := $(OPENJDK_TARGET_OS)
-endif
-
-# SetupCopyFiles is not used here since it's non-trivial to copy a single
-# file with a different target name.
-$(INCLUDE_DST_DIR)/$(JNI_MD_SUBDIR)/jni_md.h: $(JNI_MD_H_SRC)
-	$(call LogInfo, Copying hotspot/dist/include/$(JNI_MD_SUBDIR)/jni_md.h)
-	$(install-file)
-
-#TARGETS += $(INCLUDE_DST_DIR)/$(JNI_MD_SUBDIR)/jni_md.h
-
-################################################################################
-# Optionally copy libffi.so.? into the the image
-
-ifeq ($(ENABLE_LIBFFI_BUNDLING), true)
-  $(eval $(call SetupCopyFiles, COPY_LIBFFI, \
-      FILES := $(LIBFFI_LIB_FILE), \
-      DEST := $(call FindLibDirForModule, $(MODULE)), \
-      FLATTEN := true, \
-      MACRO := install-file-nolink, \
-  ))
-
-  TARGETS += $(COPY_LIBFFI)
-endif
-
-################################################################################
--- a/make/lib/Lib-java.base.gmk	Mon Oct 16 08:47:59 2017 -0700
+++ b/make/lib/Lib-java.base.gmk	Tue Oct 17 14:33:32 2017 -0700
@@ -25,9 +25,13 @@
 
 include LibCommon.gmk
 
+# Hook to include the corresponding custom file, if present.
+$(eval $(call IncludeCustomExtension, lib/Lib-java.base.gmk))
+
 # Prepare the find cache.
-$(eval $(call FillCacheFind, $(wildcard $(TOPDIR)/src/java.base/*/native \
-    $(TOPDIR)/src/*/java.base/*/native)))
+LIB_java.base_SRC_DIRS += $(TOPDIR)/src/java.base/*/native
+
+$(eval $(call FillCacheFind, $(wildcard $(LIB_java.base_SRC_DIRS))))
 
 include CoreLibraries.gmk
 include NetworkingLibraries.gmk
--- a/make/lib/Lib-java.desktop.gmk	Mon Oct 16 08:47:59 2017 -0700
+++ b/make/lib/Lib-java.desktop.gmk	Tue Oct 17 14:33:32 2017 -0700
@@ -25,9 +25,13 @@
 
 include LibCommon.gmk
 
+# Hook to include the corresponding custom file, if present.
+$(eval $(call IncludeCustomExtension, lib/Lib-java.desktop.gmk))
+
 # Prepare the find cache.
-$(eval $(call FillCacheFind, $(wildcard $(TOPDIR)/src/java.desktop/*/native \
-    $(TOPDIR)/src/*/java.desktop/*/native)))
+LIB_java.desktop_SRC_DIRS += $(TOPDIR)/src/java.desktop/*/native
+
+$(eval $(call FillCacheFind, $(wildcard $(LIB_java.desktop_SRC_DIRS))))
 
 include LibosxLibraries.gmk
 include PlatformLibraries.gmk
--- a/make/test/JtregNativeHotspot.gmk	Mon Oct 16 08:47:59 2017 -0700
+++ b/make/test/JtregNativeHotspot.gmk	Tue Oct 17 14:33:32 2017 -0700
@@ -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	Mon Oct 16 08:47:59 2017 -0700
+++ b/make/test/JtregNativeJdk.gmk	Tue Oct 17 14:33:32 2017 -0700
@@ -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/macosx/native/libjava/java_props_macosx.c	Mon Oct 16 08:47:59 2017 -0700
+++ b/src/java.base/macosx/native/libjava/java_props_macosx.c	Tue Oct 17 14:33:32 2017 -0700
@@ -113,6 +113,12 @@
     }
 
     if (retVal != NULL) {
+        // convertToPOSIXLocale() does not expect any variant codes, so ignore
+        // '@' and anything following, if present.
+        char* rmAt = strchr(retVal, '@');
+        if (rmAt != NULL) {
+            *rmAt = '\0';
+        }
         return strdup(convertToPOSIXLocale(retVal));
     }
 
--- a/src/java.base/share/classes/java/lang/Object.java	Mon Oct 16 08:47:59 2017 -0700
+++ b/src/java.base/share/classes/java/lang/Object.java	Tue Oct 17 14:33:32 2017 -0700
@@ -307,18 +307,67 @@
     public final native void notifyAll();
 
     /**
-     * Causes the current thread to wait until either another thread invokes the
-     * {@link java.lang.Object#notify()} method or the
-     * {@link java.lang.Object#notifyAll()} method for this object, or a
-     * specified amount of time has elapsed.
+     * Causes the current thread to wait until it is awakened, typically
+     * by being <em>notified</em> or <em>interrupted</em>.
+     * <p>
+     * In all respects, this method behaves as if {@code wait(0L, 0)}
+     * had been called. See the specification of the {@link #wait(long, int)} method
+     * for details.
+     *
+     * @throws IllegalMonitorStateException if the current thread is not
+     *         the owner of the object's monitor
+     * @throws InterruptedException if any thread interrupted the current thread before or
+     *         while the current thread was waiting. The <em>interrupted status</em> of the
+     *         current thread is cleared when this exception is thrown.
+     * @see    #notify()
+     * @see    #notifyAll()
+     * @see    #wait(long)
+     * @see    #wait(long, int)
+     */
+    public final void wait() throws InterruptedException {
+        wait(0L);
+    }
+
+    /**
+     * Causes the current thread to wait until it is awakened, typically
+     * by being <em>notified</em> or <em>interrupted</em>, or until a
+     * certain amount of real time has elapsed.
      * <p>
-     * The current thread must own this object's monitor.
+     * In all respects, this method behaves as if {@code wait(timeout, 0)}
+     * had been called. See the specification of the {@link #wait(long, int)} method
+     * for details.
+     *
+     * @param  timeout the maximum time to wait, in milliseconds
+     * @throws IllegalArgumentException if the value of {@code timeout} is negative
+     * @throws IllegalMonitorStateException if the current thread is not
+     *         the owner of the object's monitor
+     * @throws InterruptedException if any thread interrupted the current thread before or
+     *         while the current thread was waiting. The <em>interrupted status</em> of the
+     *         current thread is cleared when this exception is thrown.
+     * @see    #notify()
+     * @see    #notifyAll()
+     * @see    #wait()
+     * @see    #wait(long, int)
+     */
+    public final native void wait(long timeout) throws InterruptedException;
+
+    /**
+     * Causes the current thread to wait until it is awakened, typically
+     * by being <em>notified</em> or <em>interrupted</em>, or until a
+     * certain amount of real time has elapsed.
      * <p>
-     * This method causes the current thread (call it <var>T</var>) to
-     * place itself in the wait set for this object and then to relinquish
-     * any and all synchronization claims on this object. Thread <var>T</var>
-     * becomes disabled for thread scheduling purposes and lies dormant
-     * until one of four things happens:
+     * The current thread must own this object's monitor lock. See the
+     * {@link #notify notify} method for a description of the ways in which
+     * a thread can become the owner of a monitor lock.
+     * <p>
+     * This method causes the current thread (referred to here as <var>T</var>) to
+     * place itself in the wait set for this object and then to relinquish any
+     * and all synchronization claims on this object. Note that only the locks
+     * on this object are relinquished; any other objects on which the current
+     * thread may be synchronized remain locked while the thread waits.
+     * <p>
+     * Thread <var>T</var> then becomes disabled for thread scheduling purposes
+     * and lies dormant until one of the following occurs:
      * <ul>
      * <li>Some other thread invokes the {@code notify} method for this
      * object and thread <var>T</var> happens to be arbitrarily chosen as
@@ -327,14 +376,18 @@
      * object.
      * <li>Some other thread {@linkplain Thread#interrupt() interrupts}
      * thread <var>T</var>.
-     * <li>The specified amount of real time has elapsed, more or less.  If
-     * {@code timeout} is zero, however, then real time is not taken into
-     * consideration and the thread simply waits until notified.
+     * <li>The specified amount of real time has elapsed, more or less.
+     * The amount of real time, in nanoseconds, is given by the expression
+     * {@code 1000000 * timeout + nanos}. If {@code timeout} and {@code nanos}
+     * are both zero, then real time is not taken into consideration and the
+     * thread waits until awakened by one of the other causes.
+     * <li>Thread <var>T</var> is awakened spuriously. (See below.)
      * </ul>
+     * <p>
      * The thread <var>T</var> is then removed from the wait set for this
-     * object and re-enabled for thread scheduling. It then competes in the
+     * object and re-enabled for thread scheduling. It competes in the
      * usual manner with other threads for the right to synchronize on the
-     * object; once it has gained control of the object, all its
+     * object; once it has regained control of the object, all its
      * synchronization claims on the object are restored to the status quo
      * ante - that is, to the situation as of the time that the {@code wait}
      * method was invoked. Thread <var>T</var> then returns from the
@@ -343,119 +396,54 @@
      * thread {@code T} is exactly as it was when the {@code wait} method
      * was invoked.
      * <p>
-     * A thread can also wake up without being notified, interrupted, or
-     * timing out, a so-called <i>spurious wakeup</i>.  While this will rarely
-     * occur in practice, applications must guard against it by testing for
-     * the condition that should have caused the thread to be awakened, and
-     * continuing to wait if the condition is not satisfied.  In other words,
-     * waits should always occur in loops, like this one:
-     * <pre>
-     *     synchronized (obj) {
-     *         while (&lt;condition does not hold&gt;)
-     *             obj.wait(timeout);
-     *         ... // Perform action appropriate to condition
-     *     }
-     * </pre>
+     * A thread can wake up without being notified, interrupted, or timing out, a
+     * so-called <em>spurious wakeup</em>.  While this will rarely occur in practice,
+     * applications must guard against it by testing for the condition that should
+     * have caused the thread to be awakened, and continuing to wait if the condition
+     * is not satisfied. See the example below.
+     * <p>
+     * For more information on this topic, see section 14.2,
+     * "Condition Queues," in Brian Goetz and others' <em>Java Concurrency
+     * in Practice</em> (Addison-Wesley, 2006) or Item 69 in Joshua
+     * Bloch's <em>Effective Java, Second Edition</em> (Addison-Wesley,
+     * 2008).
+     * <p>
+     * If the current thread is {@linkplain java.lang.Thread#interrupt() interrupted}
+     * by any thread before or while it is waiting, then an {@code InterruptedException}
+     * is thrown.  The <em>interrupted status</em> of the current thread is cleared when
+     * this exception is thrown. This exception is not thrown until the lock status of
+     * this object has been restored as described above.
      *
-     * (For more information on this topic, see section 14.2,
-     * Condition Queues, in Brian Goetz and others' "Java Concurrency
-     * in Practice" (Addison-Wesley, 2006) or Item 69 in Joshua
-     * Bloch's "Effective Java (Second Edition)" (Addison-Wesley,
-     * 2008).
-     *
-     * <p>If the current thread is {@linkplain java.lang.Thread#interrupt()
-     * interrupted} by any thread before or while it is waiting, then an
-     * {@code InterruptedException} is thrown.  This exception is not
-     * thrown until the lock status of this object has been restored as
-     * described above.
-     *
-     * <p>
-     * Note that the {@code wait} method, as it places the current thread
-     * into the wait set for this object, unlocks only this object; any
-     * other objects on which the current thread may be synchronized remain
-     * locked while the thread waits.
-     * <p>
-     * This method should only be called by a thread that is the owner
-     * of this object's monitor. See the {@code notify} method for a
-     * description of the ways in which a thread can become the owner of
-     * a monitor.
+     * @apiNote
+     * The recommended approach to waiting is to check the condition being awaited in
+     * a {@code while} loop around the call to {@code wait}, as shown in the example
+     * below. Among other things, this approach avoids problems that can be caused
+     * by spurious wakeups.
      *
-     * @param      timeout   the maximum time to wait in milliseconds.
-     * @throws  IllegalArgumentException      if the value of timeout is
-     *               negative.
-     * @throws  IllegalMonitorStateException  if the current thread is not
-     *               the owner of the object's monitor.
-     * @throws  InterruptedException if any thread interrupted the
-     *             current thread before or while the current thread
-     *             was waiting for a notification.  The <i>interrupted
-     *             status</i> of the current thread is cleared when
-     *             this exception is thrown.
-     * @see        java.lang.Object#notify()
-     * @see        java.lang.Object#notifyAll()
-     */
-    public final native void wait(long timeout) throws InterruptedException;
-
-    /**
-     * Causes the current thread to wait until another thread invokes the
-     * {@link java.lang.Object#notify()} method or the
-     * {@link java.lang.Object#notifyAll()} method for this object, or
-     * some other thread interrupts the current thread, or a certain
-     * amount of real time has elapsed.
-     * <p>
-     * This method is similar to the {@code wait} method of one
-     * argument, but it allows finer control over the amount of time to
-     * wait for a notification before giving up. The amount of real time,
-     * measured in nanoseconds, is given by:
-     * <blockquote>
-     * <pre>
-     * 1000000*timeout+nanos</pre></blockquote>
-     * <p>
-     * In all other respects, this method does the same thing as the
-     * method {@link #wait(long)} of one argument. In particular,
-     * {@code wait(0, 0)} means the same thing as {@code wait(0)}.
-     * <p>
-     * The current thread must own this object's monitor. The thread
-     * releases ownership of this monitor and waits until either of the
-     * following two conditions has occurred:
-     * <ul>
-     * <li>Another thread notifies threads waiting on this object's monitor
-     *     to wake up either through a call to the {@code notify} method
-     *     or the {@code notifyAll} method.
-     * <li>The timeout period, specified by {@code timeout}
-     *     milliseconds plus {@code nanos} nanoseconds arguments, has
-     *     elapsed.
-     * </ul>
-     * <p>
-     * The thread then waits until it can re-obtain ownership of the
-     * monitor and resumes execution.
-     * <p>
-     * As in the one argument version, interrupts and spurious wakeups are
-     * possible, and this method should always be used in a loop:
-     * <pre>
+     * <pre>{@code
      *     synchronized (obj) {
-     *         while (&lt;condition does not hold&gt;)
+     *         while (<condition does not hold> and <timeout not exceeded>) {
+     *             long timeout = ... ; // recompute timeout values
+     *             int nanos = ... ;
      *             obj.wait(timeout, nanos);
-     *         ... // Perform action appropriate to condition
+     *         }
+     *         ... // Perform action appropriate to condition or timeout
      *     }
-     * </pre>
-     * This method should only be called by a thread that is the owner
-     * of this object's monitor. See the {@code notify} method for a
-     * description of the ways in which a thread can become the owner of
-     * a monitor.
+     * }</pre>
      *
-     * @param      timeout   the maximum time to wait in milliseconds.
-     * @param      nanos      additional time, in nanoseconds range
-     *                       0-999999.
-     * @throws  IllegalArgumentException      if the value of timeout is
-     *                      negative or the value of nanos is
-     *                      not in the range 0-999999.
-     * @throws  IllegalMonitorStateException  if the current thread is not
-     *               the owner of this object's monitor.
-     * @throws  InterruptedException if any thread interrupted the
-     *             current thread before or while the current thread
-     *             was waiting for a notification.  The <i>interrupted
-     *             status</i> of the current thread is cleared when
-     *             this exception is thrown.
+     * @param  timeout the maximum time to wait, in milliseconds
+     * @param  nanos   additional time, in nanoseconds, in the range range 0-999999 inclusive
+     * @throws IllegalArgumentException if the value of {@code timeout} is negative,
+     *         or if the value of {@code nanos} is out of range
+     * @throws IllegalMonitorStateException if the current thread is not
+     *         the owner of the object's monitor
+     * @throws InterruptedException if any thread interrupted the current thread before or
+     *         while the current thread was waiting. The <em>interrupted status</em> of the
+     *         current thread is cleared when this exception is thrown.
+     * @see    #notify()
+     * @see    #notifyAll()
+     * @see    #wait()
+     * @see    #wait(long)
      */
     public final void wait(long timeout, int nanos) throws InterruptedException {
         if (timeout < 0) {
@@ -475,48 +463,6 @@
     }
 
     /**
-     * Causes the current thread to wait until another thread invokes the
-     * {@link java.lang.Object#notify()} method or the
-     * {@link java.lang.Object#notifyAll()} method for this object.
-     * In other words, this method behaves exactly as if it simply
-     * performs the call {@code wait(0)}.
-     * <p>
-     * The current thread must own this object's monitor. The thread
-     * releases ownership of this monitor and waits until another thread
-     * notifies threads waiting on this object's monitor to wake up
-     * either through a call to the {@code notify} method or the
-     * {@code notifyAll} method. The thread then waits until it can
-     * re-obtain ownership of the monitor and resumes execution.
-     * <p>
-     * As in the one argument version, interrupts and spurious wakeups are
-     * possible, and this method should always be used in a loop:
-     * <pre>
-     *     synchronized (obj) {
-     *         while (&lt;condition does not hold&gt;)
-     *             obj.wait();
-     *         ... // Perform action appropriate to condition
-     *     }
-     * </pre>
-     * This method should only be called by a thread that is the owner
-     * of this object's monitor. See the {@code notify} method for a
-     * description of the ways in which a thread can become the owner of
-     * a monitor.
-     *
-     * @throws  IllegalMonitorStateException  if the current thread is not
-     *               the owner of the object's monitor.
-     * @throws  InterruptedException if any thread interrupted the
-     *             current thread before or while the current thread
-     *             was waiting for a notification.  The <i>interrupted
-     *             status</i> of the current thread is cleared when
-     *             this exception is thrown.
-     * @see        java.lang.Object#notify()
-     * @see        java.lang.Object#notifyAll()
-     */
-    public final void wait() throws InterruptedException {
-        wait(0);
-    }
-
-    /**
      * Called by the garbage collector on an object when garbage collection
      * determines that there are no more references to the object.
      * A subclass overrides the {@code finalize} method to dispose of
--- a/src/java.base/share/classes/java/util/ServiceLoader.java	Mon Oct 16 08:47:59 2017 -0700
+++ b/src/java.base/share/classes/java/util/ServiceLoader.java	Tue Oct 17 14:33:32 2017 -0700
@@ -747,8 +747,10 @@
                 // invoke factory method with permissions restricted by acc
                 try {
                     result = AccessController.doPrivileged(pa, acc);
-                } catch (PrivilegedActionException pae) {
-                    exc = pae.getCause();
+                } catch (Throwable x) {
+                    if (x instanceof PrivilegedActionException)
+                        x = x.getCause();
+                    exc = x;
                 }
             }
             if (exc != null) {
@@ -788,8 +790,10 @@
                 // invoke constructor with permissions restricted by acc
                 try {
                     p = AccessController.doPrivileged(pa, acc);
-                } catch (PrivilegedActionException pae) {
-                    exc = pae.getCause();
+                } catch (Throwable x) {
+                    if (x instanceof PrivilegedActionException)
+                        x = x.getCause();
+                    exc = x;
                 }
             }
             if (exc != null) {
@@ -852,8 +856,9 @@
             PrivilegedExceptionAction<Class<?>> pa = () -> Class.forName(module, cn);
             try {
                 clazz = AccessController.doPrivileged(pa);
-            } catch (PrivilegedActionException pae) {
-                Throwable x = pae.getCause();
+            } catch (Throwable x) {
+                if (x instanceof PrivilegedActionException)
+                    x = x.getCause();
                 fail(service, "Unable to load " + cn, x);
                 return null;
             }
@@ -1477,6 +1482,8 @@
                 next = (Provider<T>) loadedProviders.get(index++);
             } else if (iterator.hasNext()) {
                 next = iterator.next();
+                loadedProviders.add((Provider<S>)next);
+                index++;
             } else {
                 loadedAllProviders = true;
             }
--- a/src/java.base/share/classes/java/util/SplittableRandom.java	Mon Oct 16 08:47:59 2017 -0700
+++ b/src/java.base/share/classes/java/util/SplittableRandom.java	Tue Oct 17 14:33:32 2017 -0700
@@ -399,6 +399,26 @@
     }
 
     /**
+     * Fills a user-supplied byte array with generated pseudorandom bytes.
+     *
+     * @param  bytes the byte array to fill with pseudorandom bytes
+     * @throws NullPointerException if bytes is null
+     * @since  10
+     */
+    public void nextBytes(byte[] bytes) {
+        int i = 0;
+        int len = bytes.length;
+        for (int words = len >> 3; words--> 0; ) {
+            long rnd = nextLong();
+            for (int n = 8; n--> 0; rnd >>>= Byte.SIZE)
+                bytes[i++] = (byte)rnd;
+        }
+        if (i < len)
+            for (long rnd = nextLong(); i < len; rnd >>>= Byte.SIZE)
+                bytes[i++] = (byte)rnd;
+    }
+
+    /**
      * Returns a pseudorandom {@code int} value.
      *
      * @return a pseudorandom {@code int} value
--- a/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java	Mon Oct 16 08:47:59 2017 -0700
+++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java	Tue Oct 17 14:33:32 2017 -0700
@@ -231,15 +231,16 @@
      *
      * The implementation is completely directionally symmetrical,
      * except that most public methods that iterate through the list
-     * follow next pointers ("forward" direction).
+     * follow next pointers, in the "forward" direction.
      *
-     * We believe (without full proof) that all single-element deque
-     * operations (e.g., addFirst, peekLast, pollLast) are linearizable
-     * (see Herlihy and Shavit's book).  However, some combinations of
+     * We believe (without full proof) that all single-element Deque
+     * operations that operate directly at the two ends of the Deque
+     * (e.g., addFirst, peekLast, pollLast) are linearizable (see
+     * Herlihy and Shavit's book).  However, some combinations of
      * operations are known not to be linearizable.  In particular,
-     * when an addFirst(A) is racing with pollFirst() removing B, it is
-     * possible for an observer iterating over the elements to observe
-     * A B C and subsequently observe A C, even though no interior
+     * when an addFirst(A) is racing with pollFirst() removing B, it
+     * is possible for an observer iterating over the elements to
+     * observe first [A B C] and then [A C], even though no interior
      * removes are ever performed.  Nevertheless, iterators behave
      * reasonably, providing the "weakly consistent" guarantees.
      *
@@ -865,21 +866,33 @@
     }
 
     public E peekFirst() {
-        for (Node<E> p = first(); p != null; p = succ(p)) {
-            final E item;
-            if ((item = p.item) != null)
-                return item;
+        restart: for (;;) {
+            for (Node<E> first = first(), p = first;;) {
+                final E item;
+                if ((item = p.item) != null) {
+                    // recheck for linearizability
+                    if (first.prev != null) continue restart;
+                    return item;
+                }
+                if ((p = succ(p)) == null)
+                    return null;
+            }
         }
-        return null;
     }
 
     public E peekLast() {
-        for (Node<E> p = last(); p != null; p = pred(p)) {
-            final E item;
-            if ((item = p.item) != null)
-                return item;
+        restart: for (;;) {
+            for (Node<E> last = last(), p = last;;) {
+                final E item;
+                if ((item = p.item) != null) {
+                    // recheck for linearizability
+                    if (last.next != null) continue restart;
+                    return item;
+                }
+                if ((p = pred(p)) == null)
+                    return null;
+            }
         }
-        return null;
     }
 
     /**
@@ -897,27 +910,39 @@
     }
 
     public E pollFirst() {
-        for (Node<E> p = first(); p != null; p = succ(p)) {
-            final E item;
-            if ((item = p.item) != null
-                && ITEM.compareAndSet(p, item, null)) {
-                unlink(p);
-                return item;
+        restart: for (;;) {
+            for (Node<E> first = first(), p = first;;) {
+                final E item;
+                if ((item = p.item) != null) {
+                    // recheck for linearizability
+                    if (first.prev != null) continue restart;
+                    if (ITEM.compareAndSet(p, item, null)) {
+                        unlink(p);
+                        return item;
+                    }
+                }
+                if ((p = succ(p)) == null)
+                    return null;
             }
         }
-        return null;
     }
 
     public E pollLast() {
-        for (Node<E> p = last(); p != null; p = pred(p)) {
-            final E item;
-            if ((item = p.item) != null
-                && ITEM.compareAndSet(p, item, null)) {
-                unlink(p);
-                return item;
+        restart: for (;;) {
+            for (Node<E> last = last(), p = last;;) {
+                final E item;
+                if ((item = p.item) != null) {
+                    // recheck for linearizability
+                    if (last.next != null) continue restart;
+                    if (ITEM.compareAndSet(p, item, null)) {
+                        unlink(p);
+                        return item;
+                    }
+                }
+                if ((p = pred(p)) == null)
+                    return null;
             }
         }
-        return null;
     }
 
     /**
@@ -1079,14 +1104,14 @@
      * @return the number of elements in this deque
      */
     public int size() {
-        restartFromHead: for (;;) {
+        restart: for (;;) {
             int count = 0;
             for (Node<E> p = first(); p != null;) {
                 if (p.item != null)
                     if (++count == Integer.MAX_VALUE)
                         break;  // @see Collection.size()
                 if (p == (p = p.next))
-                    continue restartFromHead;
+                    continue restart;
             }
             return count;
         }
@@ -1183,7 +1208,7 @@
 
     public String toString() {
         String[] a = null;
-        restartFromHead: for (;;) {
+        restart: for (;;) {
             int charLength = 0;
             int size = 0;
             for (Node<E> p = first(); p != null;) {
@@ -1198,7 +1223,7 @@
                     charLength += s.length();
                 }
                 if (p == (p = p.next))
-                    continue restartFromHead;
+                    continue restart;
             }
 
             if (size == 0)
@@ -1210,7 +1235,7 @@
 
     private Object[] toArrayInternal(Object[] a) {
         Object[] x = a;
-        restartFromHead: for (;;) {
+        restart: for (;;) {
             int size = 0;
             for (Node<E> p = first(); p != null;) {
                 final E item;
@@ -1222,7 +1247,7 @@
                     x[size++] = item;
                 }
                 if (p == (p = p.next))
-                    continue restartFromHead;
+                    continue restart;
             }
             if (x == null)
                 return new Object[0];
--- a/src/java.base/share/classes/java/util/concurrent/ThreadLocalRandom.java	Mon Oct 16 08:47:59 2017 -0700
+++ b/src/java.base/share/classes/java/util/concurrent/ThreadLocalRandom.java	Tue Oct 17 14:33:32 2017 -0700
@@ -1039,7 +1039,10 @@
      */
     private static final long SEEDER_INCREMENT = 0xbb67ae8584caa73bL;
 
-    // Constants from SplittableRandom
+    /**
+     * The least non-zero value returned by nextDouble(). This value
+     * is scaled by a random value of 53 bits to produce a result.
+     */
     private static final double DOUBLE_UNIT = 0x1.0p-53;  // 1.0  / (1L << 53)
     private static final float  FLOAT_UNIT  = 0x1.0p-24f; // 1.0f / (1 << 24)
 
--- a/src/java.base/share/classes/java/util/concurrent/locks/StampedLock.java	Mon Oct 16 08:47:59 2017 -0700
+++ b/src/java.base/share/classes/java/util/concurrent/locks/StampedLock.java	Tue Oct 17 14:33:32 2017 -0700
@@ -140,7 +140,8 @@
  *   private double x, y;
  *   private final StampedLock sl = new StampedLock();
  *
- *   void move(double deltaX, double deltaY) { // an exclusively locked method
+ *   // an exclusively locked method
+ *   void move(double deltaX, double deltaY) {
  *     long stamp = sl.writeLock();
  *     try {
  *       x += deltaX;
@@ -150,25 +151,57 @@
  *     }
  *   }
  *
- *   double distanceFromOrigin() { // A read-only method
- *     double currentX, currentY;
+ *   // a read-only method
+ *   // upgrade from optimistic read to read lock
+ *   double distanceFromOrigin() {
  *     long stamp = sl.tryOptimisticRead();
- *     do {
- *       if (stamp == 0L)
- *         stamp = sl.readLock();
- *       try {
+ *     try {
+ *       retryHoldingLock: for (;; stamp = sl.readLock()) {
+ *         if (stamp == 0L)
+ *           continue retryHoldingLock;
  *         // possibly racy reads
- *         currentX = x;
- *         currentY = y;
- *       } finally {
- *         stamp = sl.tryConvertToOptimisticRead(stamp);
+ *         double currentX = x;
+ *         double currentY = y;
+ *         if (!sl.validate(stamp))
+ *           continue retryHoldingLock;
+ *         return Math.hypot(currentX, currentY);
  *       }
- *     } while (stamp == 0);
- *     return Math.hypot(currentX, currentY);
+ *     } finally {
+ *       if (StampedLock.isReadLockStamp(stamp))
+ *         sl.unlockRead(stamp);
+ *     }
  *   }
  *
- *   void moveIfAtOrigin(double newX, double newY) { // upgrade
- *     // Could instead start with optimistic, not read mode
+ *   // upgrade from optimistic read to write lock
+ *   void moveIfAtOrigin(double newX, double newY) {
+ *     long stamp = sl.tryOptimisticRead();
+ *     try {
+ *       retryHoldingLock: for (;; stamp = sl.writeLock()) {
+ *         if (stamp == 0L)
+ *           continue retryHoldingLock;
+ *         // possibly racy reads
+ *         double currentX = x;
+ *         double currentY = y;
+ *         if (!sl.validate(stamp))
+ *           continue retryHoldingLock;
+ *         if (currentX != 0.0 || currentY != 0.0)
+ *           break;
+ *         stamp = sl.tryConvertToWriteLock(stamp);
+ *         if (stamp == 0L)
+ *           continue retryHoldingLock;
+ *         // exclusive access
+ *         x = newX;
+ *         y = newY;
+ *         return;
+ *       }
+ *     } finally {
+ *       if (StampedLock.isWriteLockStamp(stamp))
+ *         sl.unlockWrite(stamp);
+ *     }
+ *   }
+ *
+ *   // Upgrade read lock to write lock
+ *   void moveIfAtOrigin(double newX, double newY) {
  *     long stamp = sl.readLock();
  *     try {
  *       while (x == 0.0 && y == 0.0) {
@@ -882,6 +915,92 @@
     }
 
     /**
+     * Tells whether a stamp represents holding a lock exclusively.
+     * This method may be useful in conjunction with
+     * {@link #tryConvertToWriteLock}, for example: <pre> {@code
+     * long stamp = sl.tryOptimisticRead();
+     * try {
+     *   ...
+     *   stamp = sl.tryConvertToWriteLock(stamp);
+     *   ...
+     * } finally {
+     *   if (StampedLock.isWriteLockStamp(stamp))
+     *     sl.unlockWrite(stamp);
+     * }}</pre>
+     *
+     * @param stamp a stamp returned by a previous StampedLock operation
+     * @return {@code true} if the stamp was returned by a successful
+     *   write-lock operation
+     * @since 10
+     */
+    public static boolean isWriteLockStamp(long stamp) {
+        return (stamp & ABITS) == WBIT;
+    }
+
+    /**
+     * Tells whether a stamp represents holding a lock non-exclusively.
+     * This method may be useful in conjunction with
+     * {@link #tryConvertToReadLock}, for example: <pre> {@code
+     * long stamp = sl.tryOptimisticRead();
+     * try {
+     *   ...
+     *   stamp = sl.tryConvertToReadLock(stamp);
+     *   ...
+     * } finally {
+     *   if (StampedLock.isReadLockStamp(stamp))
+     *     sl.unlockRead(stamp);
+     * }}</pre>
+     *
+     * @param stamp a stamp returned by a previous StampedLock operation
+     * @return {@code true} if the stamp was returned by a successful
+     *   read-lock operation
+     * @since 10
+     */
+    public static boolean isReadLockStamp(long stamp) {
+        return (stamp & RBITS) != 0L;
+    }
+
+    /**
+     * Tells whether a stamp represents holding a lock.
+     * This method may be useful in conjunction with
+     * {@link #tryConvertToReadLock} and {@link #tryConvertToWriteLock},
+     * for example: <pre> {@code
+     * long stamp = sl.tryOptimisticRead();
+     * try {
+     *   ...
+     *   stamp = sl.tryConvertToReadLock(stamp);
+     *   ...
+     *   stamp = sl.tryConvertToWriteLock(stamp);
+     *   ...
+     * } finally {
+     *   if (StampedLock.isLockStamp(stamp))
+     *     sl.unlock(stamp);
+     * }}</pre>
+     *
+     * @param stamp a stamp returned by a previous StampedLock operation
+     * @return {@code true} if the stamp was returned by a successful
+     *   read-lock or write-lock operation
+     * @since 10
+     */
+    public static boolean isLockStamp(long stamp) {
+        return (stamp & ABITS) != 0L;
+    }
+
+    /**
+     * Tells whether a stamp represents a successful optimistic read.
+     *
+     * @param stamp a stamp returned by a previous StampedLock operation
+     * @return {@code true} if the stamp was returned by a successful
+     *   optimistic read operation, that is, a non-zero return from
+     *   {@link #tryOptimisticRead()} or
+     *   {@link #tryConvertToOptimisticRead(long)}
+     * @since 10
+     */
+    public static boolean isOptimisticReadStamp(long stamp) {
+        return (stamp & ABITS) == 0L && stamp != 0L;
+    }
+
+    /**
      * Queries the number of read locks held for this lock. This
      * method is designed for use in monitoring system state, not for
      * synchronization control.
--- a/src/java.base/share/classes/java/util/zip/ZipUtils.java	Mon Oct 16 08:47:59 2017 -0700
+++ b/src/java.base/share/classes/java/util/zip/ZipUtils.java	Tue Oct 17 14:33:32 2017 -0700
@@ -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	Mon Oct 16 08:47:59 2017 -0700
+++ b/src/java.base/share/classes/sun/nio/ch/FileChannelImpl.java	Tue Oct 17 14:33:32 2017 -0700
@@ -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/share/classes/sun/util/cldr/CLDRLocaleProviderAdapter.java	Mon Oct 16 08:47:59 2017 -0700
+++ b/src/java.base/share/classes/sun/util/cldr/CLDRLocaleProviderAdapter.java	Tue Oct 17 14:33:32 2017 -0700
@@ -26,6 +26,7 @@
 package sun.util.cldr;
 
 import java.security.AccessController;
+import java.security.AccessControlException;
 import java.security.PrivilegedExceptionAction;
 import java.text.spi.BreakIteratorProvider;
 import java.text.spi.CollatorProvider;
@@ -37,6 +38,7 @@
 import java.util.Map;
 import java.util.Objects;
 import java.util.ServiceLoader;
+import java.util.ServiceConfigurationError;
 import java.util.Set;
 import java.util.StringTokenizer;
 import java.util.concurrent.ConcurrentHashMap;
@@ -81,8 +83,11 @@
                     return null;
                 }
             });
-        }  catch (Exception e) {
+        } catch (Exception e) {
             // Catch any exception, and continue as if only CLDR's base locales exist.
+        } catch (ServiceConfigurationError sce) {
+            Throwable cause = sce.getCause();
+            if (!(cause instanceof AccessControlException)) throw sce;
         }
 
         nonBaseMetaInfo = nbmi;
--- a/src/java.base/share/classes/sun/util/locale/provider/JRELocaleProviderAdapter.java	Mon Oct 16 08:47:59 2017 -0700
+++ b/src/java.base/share/classes/sun/util/locale/provider/JRELocaleProviderAdapter.java	Tue Oct 17 14:33:32 2017 -0700
@@ -26,6 +26,7 @@
 package sun.util.locale.provider;
 
 import java.security.AccessController;
+import java.security.AccessControlException;
 import java.security.PrivilegedAction;
 import java.security.PrivilegedExceptionAction;
 import java.text.spi.BreakIteratorProvider;
@@ -40,6 +41,7 @@
 import java.util.Locale;
 import java.util.ResourceBundle;
 import java.util.ServiceLoader;
+import java.util.ServiceConfigurationError;
 import java.util.Set;
 import java.util.StringTokenizer;
 import java.util.concurrent.ConcurrentHashMap;
@@ -476,8 +478,11 @@
             if (nonBaseTags != null) {
                 supportedLocaleString += " " + nonBaseTags;
             }
-        }  catch (Exception e) {
+        } catch (Exception e) {
             // catch any exception, and ignore them as if non-EN locales do not exist.
+        } catch (ServiceConfigurationError sce) {
+            Throwable cause = sce.getCause();
+            if (!(cause instanceof AccessControlException)) throw sce;
         }
 
         return supportedLocaleString;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTaskPool.java	Tue Oct 17 14:33:32 2017 -0700
@@ -0,0 +1,390 @@
+/*
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.javac.api;
+
+import java.io.PrintStream;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+
+import com.sun.source.tree.ClassTree;
+import com.sun.source.tree.CompilationUnitTree;
+import com.sun.source.util.JavacTask;
+import com.sun.source.util.TaskEvent;
+import com.sun.source.util.TaskEvent.Kind;
+import com.sun.source.util.TaskListener;
+import com.sun.source.util.TreeScanner;
+import com.sun.tools.javac.code.Kinds;
+import com.sun.tools.javac.code.Symbol;
+import com.sun.tools.javac.code.Symtab;
+import com.sun.tools.javac.code.Type;
+import com.sun.tools.javac.code.Type.ClassType;
+import com.sun.tools.javac.code.TypeTag;
+import com.sun.tools.javac.code.Types;
+import com.sun.tools.javac.comp.Annotate;
+import com.sun.tools.javac.comp.Check;
+import com.sun.tools.javac.comp.CompileStates;
+import com.sun.tools.javac.comp.Enter;
+import com.sun.tools.javac.comp.Modules;
+import com.sun.tools.javac.main.Arguments;
+import com.sun.tools.javac.main.JavaCompiler;
+import com.sun.tools.javac.tree.JCTree.JCClassDecl;
+
+import javax.tools.Diagnostic;
+import javax.tools.DiagnosticListener;
+import javax.tools.JavaFileManager;
+import javax.tools.JavaFileObject;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.StreamSupport;
+
+import com.sun.tools.javac.model.JavacElements;
+import com.sun.tools.javac.util.Context;
+import com.sun.tools.javac.util.DefinedBy;
+import com.sun.tools.javac.util.DefinedBy.Api;
+import com.sun.tools.javac.util.Log;
+
+/**
+ * A pool of reusable JavacTasks. When a task is no valid anymore, it is returned to the pool,
+ * and its Context may be reused for future processing in some cases. The reuse is achieved
+ * by replacing some components (most notably JavaCompiler and Log) with reusable counterparts,
+ * and by cleaning up leftovers from previous compilation.
+ * <p>
+ * For each combination of options, a separate task/context is created and kept, as most option
+ * values are cached inside components themselves.
+ * <p>
+ * When the compilation redefines sensitive classes (e.g. classes in the the java.* packages), the
+ * task/context is not reused.
+ * <p>
+ * When the task is reused, then packages that were already listed won't be listed again.
+ * <p>
+ * Care must be taken to only return tasks that won't be used by the original caller.
+ * <p>
+ * Care must also be taken when custom components are installed, as those are not cleaned when the
+ * task/context is reused, and subsequent getTask may return a task based on a context with these
+ * custom components.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
+ */
+public class JavacTaskPool {
+
+    private static final JavacTool systemProvider = JavacTool.create();
+
+    private final int maxPoolSize;
+    private final Map<List<String>, List<ReusableContext>> options2Contexts = new HashMap<>();
+    private int id;
+
+    private int statReused = 0;
+    private int statNew = 0;
+    private int statPolluted = 0;
+    private int statRemoved = 0;
+
+    /**Creates the pool.
+     *
+     * @param maxPoolSize maximum number of tasks/context that will be kept in the pool.
+     */
+    public JavacTaskPool(int maxPoolSize) {
+        this.maxPoolSize = maxPoolSize;
+    }
+
+    /**Creates a new task as if by {@link javax.tools.JavaCompiler#getTask} and runs the provided
+     * worker with it. The task is only valid while the worker is running. The internal structures
+     * may be reused from some previous compilation.
+     *
+     * @param out a Writer for additional output from the compiler;
+     * use {@code System.err} if {@code null}
+     * @param fileManager a file manager; if {@code null} use the
+     * compiler's standard filemanager
+     * @param diagnosticListener a diagnostic listener; if {@code
+     * null} use the compiler's default method for reporting
+     * diagnostics
+     * @param options compiler options, {@code null} means no options
+     * @param classes names of classes to be processed by annotation
+     * processing, {@code null} means no class names
+     * @param compilationUnits the compilation units to compile, {@code
+     * null} means no compilation units
+     * @param worker that should be run with the task
+     * @return an object representing the compilation
+     * @throws RuntimeException if an unrecoverable error
+     * occurred in a user supplied component.  The
+     * {@linkplain Throwable#getCause() cause} will be the error in
+     * user code.
+     * @throws IllegalArgumentException if any of the options are invalid,
+     * or if any of the given compilation units are of other kind than
+     * {@linkplain JavaFileObject.Kind#SOURCE source}
+     */
+    public <Z> Z getTask(Writer out,
+                         JavaFileManager fileManager,
+                         DiagnosticListener<? super JavaFileObject> diagnosticListener,
+                         Iterable<String> options,
+                         Iterable<String> classes,
+                         Iterable<? extends JavaFileObject> compilationUnits,
+                         Worker<Z> worker) {
+        List<String> opts =
+                StreamSupport.stream(options.spliterator(), false)
+                             .collect(Collectors.toCollection(ArrayList::new));
+
+        ReusableContext ctx;
+
+        synchronized (this) {
+            List<ReusableContext> cached =
+                    options2Contexts.getOrDefault(opts, Collections.emptyList());
+
+            if (cached.isEmpty()) {
+                ctx = new ReusableContext(opts);
+                statNew++;
+            } else {
+                ctx = cached.remove(0);
+                statReused++;
+            }
+        }
+
+        ctx.useCount++;
+
+        JavacTaskImpl task =
+                (JavacTaskImpl) systemProvider.getTask(out, fileManager, diagnosticListener,
+                                                       opts, classes, compilationUnits, ctx);
+
+        task.addTaskListener(ctx);
+
+        Z result = worker.withTask(task);
+
+        //not returning the context to the pool if task crashes with an exception
+        //the task/context may be in a broken state
+        ctx.clear();
+        if (ctx.polluted) {
+            statPolluted++;
+        } else {
+            task.cleanup();
+            synchronized (this) {
+                while (cacheSize() + 1 > maxPoolSize) {
+                    ReusableContext toRemove =
+                            options2Contexts.values()
+                                            .stream()
+                                            .flatMap(Collection::stream)
+                                            .sorted((c1, c2) -> c1.timeStamp < c2.timeStamp ? -1 : 1)
+                                            .findFirst()
+                                            .get();
+                    options2Contexts.get(toRemove.arguments).remove(toRemove);
+                    statRemoved++;
+                }
+                options2Contexts.computeIfAbsent(ctx.arguments, x -> new ArrayList<>()).add(ctx);
+                ctx.timeStamp = id++;
+            }
+        }
+
+        return result;
+    }
+    //where:
+        private long cacheSize() {
+            return options2Contexts.values().stream().flatMap(Collection::stream).count();
+        }
+
+    public void printStatistics(PrintStream out) {
+        out.println(statReused + " reused Contexts");
+        out.println(statNew + " newly created Contexts");
+        out.println(statPolluted + " polluted Contexts");
+        out.println(statRemoved + " removed Contexts");
+    }
+
+    public interface Worker<Z> {
+        public Z withTask(JavacTask task);
+    }
+
+    static class ReusableContext extends Context implements TaskListener {
+
+        Set<CompilationUnitTree> roots = new HashSet<>();
+
+        List<String> arguments;
+        boolean polluted = false;
+
+        int useCount;
+        long timeStamp;
+
+        ReusableContext(List<String> arguments) {
+            super();
+            this.arguments = arguments;
+            put(Log.logKey, ReusableLog.factory);
+            put(JavaCompiler.compilerKey, ReusableJavaCompiler.factory);
+        }
+
+        void clear() {
+            drop(Arguments.argsKey);
+            drop(DiagnosticListener.class);
+            drop(Log.outKey);
+            drop(Log.errKey);
+            drop(JavaFileManager.class);
+            drop(JavacTask.class);
+            drop(JavacTrees.class);
+            drop(JavacElements.class);
+
+            if (ht.get(Log.logKey) instanceof ReusableLog) {
+                //log already inited - not first round
+                ((ReusableLog)Log.instance(this)).clear();
+                Enter.instance(this).newRound();
+                ((ReusableJavaCompiler)ReusableJavaCompiler.instance(this)).clear();
+                Types.instance(this).newRound();
+                Check.instance(this).newRound();
+                Modules.instance(this).newRound();
+                Annotate.instance(this).newRound();
+                CompileStates.instance(this).clear();
+                MultiTaskListener.instance(this).clear();
+
+                //find if any of the roots have redefined java.* classes
+                Symtab syms = Symtab.instance(this);
+                pollutionScanner.scan(roots, syms);
+                roots.clear();
+            }
+        }
+
+        /**
+         * This scanner detects as to whether the shared context has been polluted. This happens
+         * whenever a compiled program redefines a core class (in 'java.*' package) or when
+         * (typically because of cyclic inheritance) the symbol kind of a core class has been touched.
+         */
+        TreeScanner<Void, Symtab> pollutionScanner = new TreeScanner<Void, Symtab>() {
+            @Override @DefinedBy(Api.COMPILER_TREE)
+            public Void visitClass(ClassTree node, Symtab syms) {
+                Symbol sym = ((JCClassDecl)node).sym;
+                if (sym != null) {
+                    syms.removeClass(sym.packge().modle, sym.flatName());
+                    Type sup = supertype(sym);
+                    if (isCoreClass(sym) ||
+                            (sup != null && isCoreClass(sup.tsym) && sup.tsym.kind != Kinds.Kind.TYP)) {
+                        polluted = true;
+                    }
+                }
+                return super.visitClass(node, syms);
+            }
+
+            private boolean isCoreClass(Symbol s) {
+                return s.flatName().toString().startsWith("java.");
+            }
+
+            private Type supertype(Symbol s) {
+                if (s.type == null ||
+                        !s.type.hasTag(TypeTag.CLASS)) {
+                    return null;
+                } else {
+                    ClassType ct = (ClassType)s.type;
+                    return ct.supertype_field;
+                }
+            }
+        };
+
+        @Override @DefinedBy(Api.COMPILER_TREE)
+        public void finished(TaskEvent e) {
+            if (e.getKind() == Kind.PARSE) {
+                roots.add(e.getCompilationUnit());
+            }
+        }
+
+        @Override @DefinedBy(Api.COMPILER_TREE)
+        public void started(TaskEvent e) {
+            //do nothing
+        }
+
+        <T> void drop(Key<T> k) {
+            ht.remove(k);
+        }
+
+        <T> void drop(Class<T> c) {
+            ht.remove(key(c));
+        }
+
+        /**
+         * Reusable JavaCompiler; exposes a method to clean up the component from leftovers associated with
+         * previous compilations.
+         */
+        static class ReusableJavaCompiler extends JavaCompiler {
+
+            final static Factory<JavaCompiler> factory = ReusableJavaCompiler::new;
+
+            ReusableJavaCompiler(Context context) {
+                super(context);
+            }
+
+            @Override
+            public void close() {
+                //do nothing
+            }
+
+            void clear() {
+                newRound();
+            }
+
+            @Override
+            protected void checkReusable() {
+                //do nothing - it's ok to reuse the compiler
+            }
+        }
+
+        /**
+         * Reusable Log; exposes a method to clean up the component from leftovers associated with
+         * previous compilations.
+         */
+        static class ReusableLog extends Log {
+
+            final static Factory<Log> factory = ReusableLog::new;
+
+            Context context;
+
+            ReusableLog(Context context) {
+                super(context);
+                this.context = context;
+            }
+
+            void clear() {
+                recorded.clear();
+                sourceMap.clear();
+                nerrors = 0;
+                nwarnings = 0;
+                //Set a fake listener that will lazily lookup the context for the 'real' listener. Since
+                //this field is never updated when a new task is created, we cannot simply reset the field
+                //or keep old value. This is a hack to workaround the limitations in the current infrastructure.
+                diagListener = new DiagnosticListener<JavaFileObject>() {
+                    DiagnosticListener<JavaFileObject> cachedListener;
+
+                    @Override  @DefinedBy(Api.COMPILER)
+                    @SuppressWarnings("unchecked")
+                    public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
+                        if (cachedListener == null) {
+                            cachedListener = context.get(DiagnosticListener.class);
+                        }
+                        cachedListener.report(diagnostic);
+                    }
+                };
+            }
+        }
+    }
+}
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Type.java	Mon Oct 16 08:47:59 2017 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Type.java	Tue Oct 17 14:33:32 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -1976,7 +1976,7 @@
             }
             for (InferenceBound bound: InferenceBound.values()) {
                 List<Type> aboundList = bounds.get(bound);
-                if (aboundList.size() > 0) {
+                if (aboundList != null && aboundList.size() > 0) {
                     result += bound + " = " + aboundList + '\n';
                 }
             }
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java	Mon Oct 16 08:47:59 2017 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java	Tue Oct 17 14:33:32 2017 -0700
@@ -56,6 +56,7 @@
 import java.util.HashSet;
 import java.util.LinkedHashMap;
 import java.util.Map;
+import java.util.Optional;
 import java.util.Set;
 import java.util.function.Consumer;
 import java.util.function.Supplier;
@@ -2096,9 +2097,12 @@
                             }
                             break;
                         case CAPTURED_OUTER_THIS:
-                            if (lambdaIdent.sym.owner.kind == TYP && m.containsKey(lambdaIdent.sym.owner)) {
+                            Optional<Symbol> proxy = m.keySet().stream()
+                                    .filter(out -> lambdaIdent.sym.isMemberOf(out.type.tsym, types))
+                                    .reduce((a, b) -> a.isEnclosedBy((ClassSymbol)b) ? a : b);
+                            if (proxy.isPresent()) {
                                 // Transform outer instance variable references anchoring them to the captured synthetic.
-                                Symbol tSym = m.get(lambdaIdent.sym.owner);
+                                Symbol tSym = m.get(proxy.get());
                                 JCExpression t = make.Ident(tSym).setType(lambdaIdent.sym.owner.type);
                                 t = make.Select(t, lambdaIdent.name);
                                 t.setType(lambdaIdent.type);
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java	Mon Oct 16 08:47:59 2017 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java	Tue Oct 17 14:33:32 2017 -0700
@@ -241,12 +241,19 @@
             boolean firstToComplete = queue.isEmpty();
 
             Phase prevTopLevelPhase = topLevelPhase;
+            boolean success = false;
 
             try {
                 topLevelPhase = this;
                 doCompleteEnvs(envs);
+                success = true;
             } finally {
                 topLevelPhase = prevTopLevelPhase;
+                if (!success && firstToComplete) {
+                    //an exception was thrown, e.g. BreakAttr:
+                    //the queue would become stale, clear it:
+                    queue.clear();
+                }
             }
 
             if (firstToComplete) {
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/file/PathFileObject.java	Mon Oct 16 08:47:59 2017 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/file/PathFileObject.java	Tue Oct 17 14:33:32 2017 -0700
@@ -316,6 +316,11 @@
             return isPathNameCompatible(userPath, simpleName, kind);
         }
 
+        @Override @DefinedBy(Api.COMPILER)
+        public URI toUri() {
+            return userPath.toUri().normalize();
+        }
+
         @Override
         PathFileObject getSibling(String baseName) {
             return new SimpleFileObject(fileManager,
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractExecutableMemberWriter.java	Mon Oct 16 08:47:59 2017 -0700
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractExecutableMemberWriter.java	Tue Oct 17 14:33:32 2017 -0700
@@ -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/HtmlDocletWriter.java	Mon Oct 16 08:47:59 2017 -0700
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java	Tue Oct 17 14:33:32 2017 -0700
@@ -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	Mon Oct 16 08:47:59 2017 -0700
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlDocWriter.java	Tue Oct 17 14:33:32 2017 -0700
@@ -59,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
@@ -68,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",
@@ -80,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, "", "", "");
@@ -166,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
@@ -178,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 ')':
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlTree.java	Mon Oct 16 08:47:59 2017 -0700
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlTree.java	Tue Oct 17 14:33:32 2017 -0700
@@ -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);
+        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));
         }
-        // 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));
-        }
+        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.jdeps/share/classes/com/sun/tools/jdeps/JdepsTask.java	Mon Oct 16 08:47:59 2017 -0700
+++ b/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/JdepsTask.java	Tue Oct 17 14:33:32 2017 -0700
@@ -38,8 +38,6 @@
 import java.nio.file.Paths;
 import java.text.MessageFormat;
 import java.util.*;
-import java.util.function.Function;
-import java.util.function.ToIntFunction;
 import java.util.jar.JarFile;
 import java.util.regex.Pattern;
 
@@ -157,6 +155,7 @@
         GENERATE_OPEN_MODULE("--generate-open-module"),
         LIST_DEPS("--list-deps"),
         LIST_REDUCED_DEPS("--list-reduced-deps"),
+        PRINT_MODULE_DEPS("--print-module-deps"),
         CHECK_MODULES("--check");
 
         private final String[] names;
@@ -339,7 +338,7 @@
                 if (task.command != null) {
                     throw new BadArgs("err.command.set", task.command, opt);
                 }
-                task.command = task.listModuleDeps(false);
+                task.command = task.listModuleDeps(CommandOption.LIST_DEPS);
             }
         },
         new Option(false, CommandOption.LIST_REDUCED_DEPS) {
@@ -347,7 +346,15 @@
                 if (task.command != null) {
                     throw new BadArgs("err.command.set", task.command, opt);
                 }
-                task.command = task.listModuleDeps(true);
+                task.command = task.listModuleDeps(CommandOption.LIST_REDUCED_DEPS);
+            }
+        },
+        new Option(false, CommandOption.PRINT_MODULE_DEPS) {
+            void process(JdepsTask task, String opt, String arg) throws BadArgs {
+                if (task.command != null) {
+                    throw new BadArgs("err.command.set", task.command, opt);
+                }
+                task.command = task.listModuleDeps(CommandOption.PRINT_MODULE_DEPS);
             }
         },
 
@@ -534,14 +541,15 @@
 
     boolean run() throws IOException {
         try (JdepsConfiguration config = buildConfig(command.allModules())) {
-
-            // detect split packages
-            config.splitPackages().entrySet()
-                .stream()
-                .sorted(Map.Entry.comparingByKey())
-                .forEach(e -> log.println(getMessage("split.package",
-                                                     e.getKey(),
-                                                     e.getValue().toString())));
+            if (!options.nowarning) {
+                // detect split packages
+                config.splitPackages().entrySet()
+                      .stream()
+                      .sorted(Map.Entry.comparingByKey())
+                      .forEach(e -> warning("warn.split.package",
+                                            e.getKey(),
+                                            e.getValue().stream().collect(joining(" "))));
+            }
 
             // check if any module specified in --add-modules, --require, and -m is missing
             options.addmods.stream()
@@ -606,9 +614,17 @@
         return new GenModuleInfo(dir, openModule);
     }
 
-    private ListModuleDeps listModuleDeps(boolean reduced) throws BadArgs {
-        return reduced ? new ListReducedDeps()
-                       : new ListModuleDeps();
+    private ListModuleDeps listModuleDeps(CommandOption option) throws BadArgs {
+        switch (option) {
+            case LIST_DEPS:
+                return new ListModuleDeps(option, true, false);
+            case LIST_REDUCED_DEPS:
+                return new ListModuleDeps(option, true, true);
+            case PRINT_MODULE_DEPS:
+                return new ListModuleDeps(option, false, true, ",");
+            default:
+                throw new IllegalArgumentException(option.toString());
+        }
     }
 
     private CheckModuleDeps checkModuleDeps(Set<String> mods) throws BadArgs {
@@ -964,20 +980,18 @@
         }
     }
 
-    class ListReducedDeps extends ListModuleDeps {
-        ListReducedDeps() {
-            super(CommandOption.LIST_REDUCED_DEPS, true);
+    class ListModuleDeps extends Command {
+        final boolean jdkinternals;
+        final boolean reduced;
+        final String separator;
+        ListModuleDeps(CommandOption option, boolean jdkinternals, boolean reduced) {
+            this(option, jdkinternals, reduced, System.getProperty("line.separator"));
         }
-    }
-
-    class ListModuleDeps extends Command {
-        final boolean reduced;
-        ListModuleDeps() {
-            this(CommandOption.LIST_DEPS, false);
-        }
-        ListModuleDeps(CommandOption option, boolean reduced) {
+        ListModuleDeps(CommandOption option, boolean jdkinternals, boolean reduced, String sep) {
             super(option);
+            this.jdkinternals = jdkinternals;
             this.reduced = reduced;
+            this.separator = sep;
         }
 
         @Override
@@ -1007,8 +1021,10 @@
         boolean run(JdepsConfiguration config) throws IOException {
             return new ModuleExportsAnalyzer(config,
                                              dependencyFilter(config),
+                                             jdkinternals,
                                              reduced,
-                                             log).run();
+                                             log,
+                                             separator).run();
         }
     }
 
--- a/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/ModuleExportsAnalyzer.java	Mon Oct 16 08:47:59 2017 -0700
+++ b/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/ModuleExportsAnalyzer.java	Tue Oct 17 14:33:32 2017 -0700
@@ -33,11 +33,10 @@
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
+import java.util.TreeSet;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
-import static com.sun.tools.jdeps.Analyzer.NOT_FOUND;
-
 /**
  * Analyze module dependences and any reference to JDK internal APIs.
  * It can apply transition reduction on the resulting module graph.
@@ -50,17 +49,23 @@
 public class ModuleExportsAnalyzer extends DepsAnalyzer {
     // source archive to its dependences and JDK internal APIs it references
     private final Map<Archive, Map<Archive,Set<String>>> deps = new HashMap<>();
+    private final boolean showJdkInternals;
     private final boolean reduced;
     private final PrintWriter writer;
+    private final String separator;
     public ModuleExportsAnalyzer(JdepsConfiguration config,
                                  JdepsFilter filter,
+                                 boolean showJdkInternals,
                                  boolean reduced,
-                                 PrintWriter writer) {
+                                 PrintWriter writer,
+                                 String separator) {
         super(config, filter, null,
               Analyzer.Type.PACKAGE,
               false /* all classes */);
+        this.showJdkInternals = showJdkInternals;
         this.reduced = reduced;
         this.writer = writer;
+        this.separator = separator;
     }
 
     @Override
@@ -76,7 +81,7 @@
                     .computeIfAbsent(targetArchive, _k -> new HashSet<>());
 
             Module module = targetArchive.getModule();
-            if (originArchive.getModule() != module &&
+            if (showJdkInternals && originArchive.getModule() != module &&
                     module.isJDK() && !module.isExported(target)) {
                 // use of JDK internal APIs
                 jdkInternals.add(target);
@@ -89,35 +94,19 @@
             .sorted(Comparator.comparing(Archive::getName))
             .forEach(archive -> analyzer.visitDependences(archive, visitor));
 
-
-        // print the dependences on named modules
-        printDependences();
-
-        // print the dependences on unnamed module
-        deps.values().stream()
-            .flatMap(map -> map.keySet().stream())
-            .filter(archive -> !archive.getModule().isNamed())
-            .map(archive -> archive != NOT_FOUND
-                                ? "unnamed module: " + archive.getPathName()
-                                : archive.getPathName())
-            .distinct()
-            .sorted()
-            .forEach(archive -> writer.format("   %s%n", archive));
-
+        Set<Module> modules = modules();
+        if (showJdkInternals) {
+            // print modules and JDK internal API dependences
+            printDependences(modules);
+        } else {
+            // print module dependences
+            writer.println(modules.stream().map(Module::name).sorted()
+                                  .collect(Collectors.joining(separator)));
+        }
         return rc;
     }
 
-    private void printDependences() {
-        // find use of JDK internals
-        Map<Module, Set<String>> jdkinternals = new HashMap<>();
-        dependenceStream()
-            .flatMap(map -> map.entrySet().stream())
-            .filter(e -> e.getValue().size() > 0)
-            .forEach(e -> jdkinternals.computeIfAbsent(e.getKey().getModule(),
-                                                       _k -> new HashSet<>())
-                                      .addAll(e.getValue()));
-
-
+    private Set<Module> modules() {
         // build module graph
         ModuleGraphBuilder builder = new ModuleGraphBuilder(configuration);
         Module root = new RootModule("root");
@@ -126,43 +115,38 @@
         dependenceStream()
             .flatMap(map -> map.keySet().stream())
             .filter(m -> m.getModule().isNamed()
-                            && !configuration.rootModules().contains(m))
+                && !configuration.rootModules().contains(m))
             .map(Archive::getModule)
             .forEach(m -> builder.addEdge(root, m));
 
-        // module dependences
-        Set<Module> modules = builder.build().adjacentNodes(root);
-
+        // build module dependence graph
         // if reduced is set, apply transition reduction
-        Set<Module> reducedSet;
-        if (reduced) {
-            Set<Module> nodes = builder.reduced().adjacentNodes(root);
-            if (nodes.size() == 1) {
-                // java.base only
-                reducedSet = nodes;
-            } else {
-                // java.base is mandated and can be excluded from the reduced graph
-                reducedSet = nodes.stream()
-                    .filter(m -> !"java.base".equals(m.name()) ||
-                                    jdkinternals.containsKey("java.base"))
-                    .collect(Collectors.toSet());
-            }
-        } else {
-            reducedSet = modules;
-        }
+        Graph<Module> g = reduced ? builder.reduced() : builder.build();
+        return g.adjacentNodes(root);
+    }
 
-        modules.stream()
-               .sorted(Comparator.comparing(Module::name))
-               .forEach(m -> {
-                    if (jdkinternals.containsKey(m)) {
-                        jdkinternals.get(m).stream()
-                            .sorted()
-                            .forEach(pn -> writer.format("   %s/%s%n", m, pn));
-                    } else if (reducedSet.contains(m)){
-                        // if the transition reduction is applied, show the reduced graph
-                        writer.format("   %s%n", m);
-                    }
-            });
+    private void printDependences(Set<Module> modules) {
+        // find use of JDK internals
+        Map<Module, Set<String>> jdkinternals = new HashMap<>();
+        dependenceStream()
+            .flatMap(map -> map.entrySet().stream())
+            .filter(e -> e.getValue().size() > 0)
+            .forEach(e -> jdkinternals.computeIfAbsent(e.getKey().getModule(),
+                                                       _k -> new TreeSet<>())
+                                      .addAll(e.getValue()));
+
+        // print modules and JDK internal API dependences
+        Stream.concat(modules.stream(), jdkinternals.keySet().stream())
+              .sorted(Comparator.comparing(Module::name))
+              .distinct()
+              .forEach(m -> {
+                  if (jdkinternals.containsKey(m)) {
+                      jdkinternals.get(m).stream()
+                          .forEach(pn -> writer.format("   %s/%s%s", m, pn, separator));
+                  } else {
+                      writer.format("   %s%s", m, separator);
+                  }
+              });
     }
 
     /*
--- a/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/resources/jdeps.properties	Mon Oct 16 08:47:59 2017 -0700
+++ b/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/resources/jdeps.properties	Tue Oct 17 14:33:32 2017 -0700
@@ -157,23 +157,31 @@
 \                                WARNING: JDK internal APIs are inaccessible.
 
 main.opt.list-deps=\
-\  --list-deps                   Lists the module dependences and also the\n\
-\                                package names of JDK internal APIs if referenced.
+\  --list-deps                   Lists the module dependences.  It also prints\n\
+\                                any JDK internal API packages if referenced.\n\
+\                                This option does not show dependences on the\n\
+\                                class path or not found.
 
 main.opt.list-reduced-deps=\
 \  --list-reduced-deps           Same as --list-deps with not listing\n\
-\                                the implied reads edges from the module graph\n\
+\                                the implied reads edges from the module graph.\n\
 \                                If module M1 reads M2, and M2 requires\n\
 \                                transitive on M3, then M1 reading M3 is implied\n\
 \                                and is not shown in the graph.
 
+main.opt.print-module-deps=\
+\  --print-module-deps           Same as --list-reduced-deps with printing\n\
+\                                a comma-separated list of module dependences.\n\
+\                                This output can be used by jlink --add-modules\n\
+\                                in order to create a custom image containing\n\
+\                                those modules and their transitive dependences.
+
 main.opt.depth=\
 \  -depth=<depth>                Specify the depth of the transitive\n\
 \                                dependency analysis
 
 main.opt.q=\
-\  -q       -quiet               Do not show missing dependences from \n\
-\                                --generate-module-info output.
+\  -q       -quiet               Suppress warning messages
 
 main.opt.multi-release=\
 \  --multi-release <version>     Specifies the version when processing\n\
@@ -202,7 +210,7 @@
 err.multirelease.jar.malformed=malformed multi-release jar, {0}, bad entry: {1}
 warn.invalid.arg=Path does not exist: {0}
 warn.skipped.entry={0}
-warn.split.package=package {0} defined in {1} {2}
+warn.split.package=split package: {0} {1}
 warn.replace.useJDKInternals=\
 JDK internal APIs are unsupported and private to JDK implementation that are\n\
 subject to be removed or changed incompatibly and could break your application.\n\
@@ -210,7 +218,6 @@
 For the most recent update on JDK internal API replacements, please check:\n\
 {0}
 
-split.package=split package: {0} {1}\n
 inverse.transitive.dependencies.on=Inverse transitive dependences on {0}
 inverse.transitive.dependencies.matching=Inverse transitive dependences matching {0}
 internal.api.column.header=JDK Internal API
--- a/src/jdk.jlink/share/classes/module-info.java	Mon Oct 16 08:47:59 2017 -0700
+++ b/src/jdk.jlink/share/classes/module-info.java	Tue Oct 17 14:33:32 2017 -0700
@@ -38,14 +38,13 @@
  * or the {@link java.util.ServiceLoader service loader} with the name
  * {@code "jlink"} or {@code "jmod"} as appropriate.
  *
- * <p> <em>{@extLink jimage_tool_reference jimage}</em> only exists
+ * <p> <em>jimage</em> only exists
  * as a command-line tool, and does not provide any direct API.
  *
  * <dl style="font-family:'DejaVu Sans', Arial, Helvetica, sans serif">
  * <dt class="simpleTagLabel">Tool Guides:
  * <dd>{@extLink jlink_tool_reference jlink},
- *     {@extLink jmod_tool_reference jmod},
- *     {@extLink jimage_tool_reference jimage}
+ *     {@extLink jmod_tool_reference jmod}
  * </dl>
  *
  * @provides java.util.spi.ToolProvider
--- a/src/jdk.jshell/share/classes/jdk/jshell/CompletenessAnalyzer.java	Mon Oct 16 08:47:59 2017 -0700
+++ b/src/jdk.jshell/share/classes/jdk/jshell/CompletenessAnalyzer.java	Tue Oct 17 14:33:32 2017 -0700
@@ -45,6 +45,7 @@
 import com.sun.source.tree.Tree;
 import static jdk.jshell.CompletenessAnalyzer.TK.*;
 import jdk.jshell.TaskFactory.ParseTask;
+import jdk.jshell.TaskFactory.Worker;
 import java.util.List;
 import java.util.function.Function;
 import java.util.function.Supplier;
@@ -85,7 +86,7 @@
         try {
             Parser parser = new Parser(
                     () -> new Matched(scannerFactory.newScanner(s, false)),
-                    () -> proc.taskFactory.parse(s));
+                    worker -> proc.taskFactory.parse(s, worker));
             Completeness stat = parser.parseUnit();
             int endPos = stat == Completeness.UNKNOWN
                     ? s.length()
@@ -561,12 +562,13 @@
     private static class Parser {
 
         private final Supplier<Matched> matchedFactory;
-        private final Supplier<ParseTask> parseFactory;
+        private final Function<Worker<ParseTask, Completeness>, Completeness> parseFactory;
         private Matched in;
         private CT token;
         private Completeness checkResult;
 
-        Parser(Supplier<Matched> matchedFactory, Supplier<ParseTask> parseFactory) {
+        Parser(Supplier<Matched> matchedFactory,
+               Function<Worker<ParseTask, Completeness>, Completeness> parseFactory) {
             this.matchedFactory = matchedFactory;
             this.parseFactory = parseFactory;
             resetInput();
@@ -692,30 +694,31 @@
 
         public Completeness disambiguateDeclarationVsExpression() {
             // String folding messes up position information.
-            ParseTask pt = parseFactory.get();
-            List<? extends Tree> units = pt.units();
-            if (units.isEmpty()) {
-                return error();
-            }
-            Tree unitTree = units.get(0);
-            switch (unitTree.getKind()) {
-                case EXPRESSION_STATEMENT:
-                    return parseExpressionOptionalSemi();
-                case LABELED_STATEMENT:
-                    if (shouldAbort(IDENTIFIER))  return checkResult;
-                    if (shouldAbort(COLON))  return checkResult;
-                return parseStatement();
-                case VARIABLE:
-                case IMPORT:
-                case CLASS:
-                case ENUM:
-                case ANNOTATION_TYPE:
-                case INTERFACE:
-                case METHOD:
-                    return parseDeclaration();
-                default:
+            return parseFactory.apply(pt -> {
+                List<? extends Tree> units = pt.units();
+                if (units.isEmpty()) {
                     return error();
-            }
+                }
+                Tree unitTree = units.get(0);
+                switch (unitTree.getKind()) {
+                    case EXPRESSION_STATEMENT:
+                        return parseExpressionOptionalSemi();
+                    case LABELED_STATEMENT:
+                        if (shouldAbort(IDENTIFIER))  return checkResult;
+                        if (shouldAbort(COLON))  return checkResult;
+                    return parseStatement();
+                    case VARIABLE:
+                    case IMPORT:
+                    case CLASS:
+                    case ENUM:
+                    case ANNOTATION_TYPE:
+                    case INTERFACE:
+                    case METHOD:
+                        return parseDeclaration();
+                    default:
+                        return error();
+                }
+            });
         }
 
         public Completeness parseExpressionStatement() {
--- a/src/jdk.jshell/share/classes/jdk/jshell/Eval.java	Mon Oct 16 08:47:59 2017 -0700
+++ b/src/jdk.jshell/share/classes/jdk/jshell/Eval.java	Tue Oct 17 14:33:32 2017 -0700
@@ -177,40 +177,41 @@
         if (compileSource.length() == 0) {
             return Collections.emptyList();
         }
-        ParseTask pt = state.taskFactory.parse(compileSource);
-        List<? extends Tree> units = pt.units();
-        if (units.isEmpty()) {
-            return compileFailResult(pt, userSource, Kind.ERRONEOUS);
-        }
-        Tree unitTree = units.get(0);
-        if (pt.getDiagnostics().hasOtherThanNotStatementErrors()) {
-            return compileFailResult(pt, userSource, kindOfTree(unitTree));
-        }
+        return state.taskFactory.parse(compileSource, pt -> {
+            List<? extends Tree> units = pt.units();
+            if (units.isEmpty()) {
+                return compileFailResult(pt, userSource, Kind.ERRONEOUS);
+            }
+            Tree unitTree = units.get(0);
+            if (pt.getDiagnostics().hasOtherThanNotStatementErrors()) {
+                return compileFailResult(pt, userSource, kindOfTree(unitTree));
+            }
 
-        // Erase illegal/ignored modifiers
-        compileSource = new MaskCommentsAndModifiers(compileSource, true).cleared();
+            // Erase illegal/ignored modifiers
+            String compileSourceInt = new MaskCommentsAndModifiers(compileSource, true).cleared();
 
-        state.debug(DBG_GEN, "Kind: %s -- %s\n", unitTree.getKind(), unitTree);
-        switch (unitTree.getKind()) {
-            case IMPORT:
-                return processImport(userSource, compileSource);
-            case VARIABLE:
-                return processVariables(userSource, units, compileSource, pt);
-            case EXPRESSION_STATEMENT:
-                return processExpression(userSource, compileSource);
-            case CLASS:
-                return processClass(userSource, unitTree, compileSource, SubKind.CLASS_SUBKIND, pt);
-            case ENUM:
-                return processClass(userSource, unitTree, compileSource, SubKind.ENUM_SUBKIND, pt);
-            case ANNOTATION_TYPE:
-                return processClass(userSource, unitTree, compileSource, SubKind.ANNOTATION_TYPE_SUBKIND, pt);
-            case INTERFACE:
-                return processClass(userSource, unitTree, compileSource, SubKind.INTERFACE_SUBKIND, pt);
-            case METHOD:
-                return processMethod(userSource, unitTree, compileSource, pt);
-            default:
-                return processStatement(userSource, compileSource);
-        }
+            state.debug(DBG_GEN, "Kind: %s -- %s\n", unitTree.getKind(), unitTree);
+            switch (unitTree.getKind()) {
+                case IMPORT:
+                    return processImport(userSource, compileSourceInt);
+                case VARIABLE:
+                    return processVariables(userSource, units, compileSourceInt, pt);
+                case EXPRESSION_STATEMENT:
+                    return processExpression(userSource, compileSourceInt);
+                case CLASS:
+                    return processClass(userSource, unitTree, compileSourceInt, SubKind.CLASS_SUBKIND, pt);
+                case ENUM:
+                    return processClass(userSource, unitTree, compileSourceInt, SubKind.ENUM_SUBKIND, pt);
+                case ANNOTATION_TYPE:
+                    return processClass(userSource, unitTree, compileSourceInt, SubKind.ANNOTATION_TYPE_SUBKIND, pt);
+                case INTERFACE:
+                    return processClass(userSource, unitTree, compileSourceInt, SubKind.INTERFACE_SUBKIND, pt);
+                case METHOD:
+                    return processMethod(userSource, unitTree, compileSourceInt, pt);
+                default:
+                    return processStatement(userSource, compileSourceInt);
+            }
+        });
     }
 
     private List<Snippet> processImport(String userSource, String compileSource) {
@@ -295,9 +296,9 @@
                 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));
+                DiagList dl = trialCompile(Wrap.methodWrap(compileSource));
+                if (dl.hasErrors()) {
+                    return compileFailResult(dl, userSource, kindOfTree(unitTree));
                 }
                 Tree init = vt.getInitializer();
                 if (init != null) {
@@ -459,13 +460,13 @@
             guts = Wrap.methodWrap(compileSource);
             if (ei == null) {
                 // We got no type info, check for not a statement by trying
-                AnalyzeTask at = trialCompile(guts);
-                if (at.getDiagnostics().hasNotStatement()) {
+                DiagList dl = trialCompile(guts);
+                if (dl.hasNotStatement()) {
                     guts = Wrap.methodReturnWrap(compileSource);
-                    at = trialCompile(guts);
+                    dl = trialCompile(guts);
                 }
-                if (at.hasErrors()) {
-                    return compileFailResult(at, userSource, Kind.EXPRESSION);
+                if (dl.hasErrors()) {
+                    return compileFailResult(dl, userSource, Kind.EXPRESSION);
                 }
             }
             snip = new StatementSnippet(state.keyMap.keyForStatement(), userSource, guts);
@@ -496,32 +497,32 @@
     private List<Snippet> processStatement(String userSource, String compileSource) {
         Wrap guts = Wrap.methodWrap(compileSource);
         // Check for unreachable by trying
-        AnalyzeTask at = trialCompile(guts);
-        if (at.hasErrors()) {
-            if (at.getDiagnostics().hasUnreachableError()) {
+        DiagList dl = trialCompile(guts);
+        if (dl.hasErrors()) {
+            if (dl.hasUnreachableError()) {
                 guts = Wrap.methodUnreachableSemiWrap(compileSource);
-                at = trialCompile(guts);
-                if (at.hasErrors()) {
-                    if (at.getDiagnostics().hasUnreachableError()) {
+                dl = trialCompile(guts);
+                if (dl.hasErrors()) {
+                    if (dl.hasUnreachableError()) {
                         // Without ending semicolon
                         guts = Wrap.methodUnreachableWrap(compileSource);
-                        at = trialCompile(guts);
+                        dl = trialCompile(guts);
                     }
-                    if (at.hasErrors()) {
-                        return compileFailResult(at, userSource, Kind.STATEMENT);
+                    if (dl.hasErrors()) {
+                        return compileFailResult(dl, userSource, Kind.STATEMENT);
                     }
                 }
             } else {
-                return compileFailResult(at, userSource, Kind.STATEMENT);
+                return compileFailResult(dl, userSource, Kind.STATEMENT);
             }
         }
         Snippet snip = new StatementSnippet(state.keyMap.keyForStatement(), userSource, guts);
         return singletonList(snip);
     }
 
-    private AnalyzeTask trialCompile(Wrap guts) {
+    private DiagList trialCompile(Wrap guts) {
         OuterWrap outer = state.outerMap.wrapInTrialClass(guts);
-        return state.taskFactory.new AnalyzeTask(outer);
+        return state.taskFactory.analyze(outer, AnalyzeTask::getDiagnostics);
     }
 
     private List<Snippet> processMethod(String userSource, Tree unitTree, String compileSource, ParseTask pt) {
@@ -751,19 +752,22 @@
 
             ins.stream().forEach(Unit::initialize);
             ins.stream().forEach(u -> u.setWrap(ins, ins));
-            AnalyzeTask at = state.taskFactory.new AnalyzeTask(outerWrapSet(ins));
-            ins.stream().forEach(u -> u.setDiagnostics(at));
+            state.taskFactory.analyze(outerWrapSet(ins), at -> {
+                ins.stream().forEach(u -> u.setDiagnostics(at));
 
-            // corral any Snippets that need it
-            AnalyzeTask cat;
-            if (ins.stream().anyMatch(u -> u.corralIfNeeded(ins))) {
-                // if any were corralled, re-analyze everything
-                cat = state.taskFactory.new AnalyzeTask(outerWrapSet(ins));
-                ins.stream().forEach(u -> u.setCorralledDiagnostics(cat));
-            } else {
-                cat = at;
-            }
-            ins.stream().forEach(u -> u.setStatus(cat));
+                // corral any Snippets that need it
+                if (ins.stream().anyMatch(u -> u.corralIfNeeded(ins))) {
+                    // if any were corralled, re-analyze everything
+                    state.taskFactory.analyze(outerWrapSet(ins), cat -> {
+                        ins.stream().forEach(u -> u.setCorralledDiagnostics(cat));
+                        ins.stream().forEach(u -> u.setStatus(cat));
+                        return null;
+                    });
+                } else {
+                    ins.stream().forEach(u -> u.setStatus(at));
+                }
+                return null;
+            });
             // compile and load the legit snippets
             boolean success;
             while (true) {
@@ -780,37 +784,45 @@
                     legit.stream().forEach(u -> u.setWrap(ins, legit));
 
                     // generate class files for those capable
-                    CompileTask ct = state.taskFactory.new CompileTask(outerWrapSet(legit));
-                    if (!ct.compile()) {
-                        // oy! compile failed because of recursive new unresolved
-                        if (legit.stream()
-                                .filter(u -> u.smashingErrorDiagnostics(ct))
-                                .count() > 0) {
-                            // try again, with the erroreous removed
-                            continue;
-                        } else {
-                            state.debug(DBG_GEN, "Should never happen error-less failure - %s\n",
-                                    legit);
+                    Result res = state.taskFactory.compile(outerWrapSet(legit), ct -> {
+                        if (!ct.compile()) {
+                            // oy! compile failed because of recursive new unresolved
+                            if (legit.stream()
+                                    .filter(u -> u.smashingErrorDiagnostics(ct))
+                                    .count() > 0) {
+                                // try again, with the erroreous removed
+                                return Result.CONTINUE;
+                            } else {
+                                state.debug(DBG_GEN, "Should never happen error-less failure - %s\n",
+                                        legit);
+                            }
                         }
-                    }
 
-                    // load all new classes
-                    load(legit.stream()
-                            .flatMap(u -> u.classesToLoad(ct.classList(u.snippet().outerWrap())))
-                            .collect(toSet()));
-                    // attempt to redefine the remaining classes
-                    List<Unit> toReplace = legit.stream()
-                            .filter(u -> !u.doRedefines())
-                            .collect(toList());
+                        // load all new classes
+                        load(legit.stream()
+                                .flatMap(u -> u.classesToLoad(ct.classList(u.snippet().outerWrap())))
+                                .collect(toSet()));
+                        // attempt to redefine the remaining classes
+                        List<Unit> toReplace = legit.stream()
+                                .filter(u -> !u.doRedefines())
+                                .collect(toList());
 
-                    // prevent alternating redefine/replace cyclic dependency
-                    // loop by replacing all that have been replaced
-                    if (!toReplace.isEmpty()) {
-                        replaced.addAll(toReplace);
-                        replaced.stream().forEach(Unit::markForReplacement);
+                        // prevent alternating redefine/replace cyclic dependency
+                        // loop by replacing all that have been replaced
+                        if (!toReplace.isEmpty()) {
+                            replaced.addAll(toReplace);
+                            replaced.stream().forEach(Unit::markForReplacement);
+                        }
+
+                        return toReplace.isEmpty() ? Result.SUCESS : Result.FAILURE;
+                    });
+
+                    switch (res) {
+                        case CONTINUE: continue;
+                        case SUCESS: success = true; break;
+                        default:
+                        case FAILURE: success = false; break;
                     }
-
-                    success = toReplace.isEmpty();
                 }
                 break;
             }
@@ -830,6 +842,8 @@
             }
         }
     }
+    //where:
+        enum Result {SUCESS, FAILURE, CONTINUE}
 
     /**
      * If there are classes to load, loads by calling the execution engine.
@@ -893,6 +907,8 @@
 
             final boolean fatal;
             final String message;
+            long start;
+            long end;
 
             ModifierDiagnostic(List<Modifier> list, boolean fatal) {
                 this.fatal = fatal;
@@ -910,6 +926,8 @@
                             ? "jshell.diag.modifier.single.fatal"
                             : "jshell.diag.modifier.single.ignore";
                 this.message = state.messageFormat(key, sb.toString());
+                start = dis.getStartPosition(modtree);
+                end = dis.getEndPosition(modtree);
             }
 
             @Override
@@ -919,17 +937,17 @@
 
             @Override
             public long getPosition() {
-                return dis.getStartPosition(modtree);
+                return start;
             }
 
             @Override
             public long getStartPosition() {
-                return dis.getStartPosition(modtree);
+                return start;
             }
 
             @Override
             public long getEndPosition() {
-                return dis.getEndPosition(modtree);
+                return end;
             }
 
             @Override
--- a/src/jdk.jshell/share/classes/jdk/jshell/ExpressionToTypeInfo.java	Mon Oct 16 08:47:59 2017 -0700
+++ b/src/jdk.jshell/share/classes/jdk/jshell/ExpressionToTypeInfo.java	Tue Oct 17 14:33:32 2017 -0700
@@ -163,14 +163,15 @@
         if (code == null || code.isEmpty()) {
             return null;
         }
+        OuterWrap codeWrap = state.outerMap.wrapInTrialClass(Wrap.methodReturnWrap(code));
         try {
-            OuterWrap codeWrap = state.outerMap.wrapInTrialClass(Wrap.methodReturnWrap(code));
-            AnalyzeTask at = state.taskFactory.new AnalyzeTask(codeWrap);
-            CompilationUnitTree cu = at.firstCuTree();
-            if (at.hasErrors() || cu == null) {
-                return null;
-            }
-            return new ExpressionToTypeInfo(at, cu, state).typeOfExpression();
+            return state.taskFactory.analyze(codeWrap, at -> {
+                CompilationUnitTree cu = at.firstCuTree();
+                if (at.hasErrors() || cu == null) {
+                    return null;
+                }
+                return new ExpressionToTypeInfo(at, cu, state).typeOfExpression();
+            });
         } catch (Exception ex) {
             return null;
         }
@@ -189,12 +190,13 @@
         }
         try {
             OuterWrap codeWrap = state.outerMap.wrapInTrialClass(Wrap.methodWrap("var $$$ = " + code));
-            AnalyzeTask at = state.taskFactory.new AnalyzeTask(codeWrap);
-            CompilationUnitTree cu = at.firstCuTree();
-            if (at.hasErrors() || cu == null) {
-                return null;
-            }
-            return new ExpressionToTypeInfo(at, cu, state).typeOfExpression();
+            return state.taskFactory.analyze(codeWrap, at -> {
+                CompilationUnitTree cu = at.firstCuTree();
+                if (at.hasErrors() || cu == null) {
+                    return null;
+                }
+                return new ExpressionToTypeInfo(at, cu, state).typeOfExpression();
+            });
         } catch (Exception ex) {
             return null;
         }
--- a/src/jdk.jshell/share/classes/jdk/jshell/ReplParserFactory.java	Mon Oct 16 08:47:59 2017 -0700
+++ b/src/jdk.jshell/share/classes/jdk/jshell/ReplParserFactory.java	Tue Oct 17 14:33:32 2017 -0700
@@ -40,8 +40,12 @@
     private final boolean forceExpression;
 
     public static void preRegister(Context context, boolean forceExpression) {
-        context.put(parserFactoryKey, (Context.Factory<ParserFactory>)
-                (c -> new ReplParserFactory(c, forceExpression)));
+        class Mark {}
+        if (context.get(Mark.class) == null) { //don't register the factory if Context is reused
+            context.put(parserFactoryKey, (Context.Factory<ParserFactory>)
+                    (c -> new ReplParserFactory(c, forceExpression)));
+            context.put(Mark.class, new Mark());
+        }
     }
 
     private final ScannerFactory scannerFactory;
--- a/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysisImpl.java	Mon Oct 16 08:47:59 2017 -0700
+++ b/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysisImpl.java	Tue Oct 17 14:33:32 2017 -0700
@@ -236,14 +236,15 @@
     }
 
     private Tree.Kind guessKind(String code) {
-        ParseTask pt = proc.taskFactory.parse(code);
-        List<? extends Tree> units = pt.units();
-        if (units.isEmpty()) {
-            return Tree.Kind.BLOCK;
-        }
-        Tree unitTree = units.get(0);
-        proc.debug(DBG_COMPA, "Kind: %s -- %s\n", unitTree.getKind(), unitTree);
-        return unitTree.getKind();
+        return proc.taskFactory.parse(code, pt -> {
+            List<? extends Tree> units = pt.units();
+            if (units.isEmpty()) {
+                return Tree.Kind.BLOCK;
+            }
+            Tree unitTree = units.get(0);
+            proc.debug(DBG_COMPA, "Kind: %s -- %s\n", unitTree.getKind(), unitTree);
+            return unitTree.getKind();
+        });
     }
 
     //TODO: would be better handled through a lexer:
@@ -295,182 +296,183 @@
     }
 
     private List<Suggestion> computeSuggestions(OuterWrap code, int cursor, int[] anchor) {
-        AnalyzeTask at = proc.taskFactory.new AnalyzeTask(code);
-        SourcePositions sp = at.trees().getSourcePositions();
-        CompilationUnitTree topLevel = at.firstCuTree();
-        List<Suggestion> result = new ArrayList<>();
-        TreePath tp = pathFor(topLevel, sp, code.snippetIndexToWrapIndex(cursor));
-        if (tp != null) {
-            Scope scope = at.trees().getScope(tp);
-            Predicate<Element> accessibility = createAccessibilityFilter(at, tp);
-            Predicate<Element> smartTypeFilter;
-            Predicate<Element> smartFilter;
-            Iterable<TypeMirror> targetTypes = findTargetType(at, tp);
-            if (targetTypes != null) {
-                smartTypeFilter = el -> {
-                    TypeMirror resultOf = resultTypeOf(el);
-                    return Util.stream(targetTypes)
-                            .anyMatch(targetType -> at.getTypes().isAssignable(resultOf, targetType));
-                };
-
-                smartFilter = IS_CLASS.negate()
-                                      .and(IS_INTERFACE.negate())
-                                      .and(IS_PACKAGE.negate())
-                                      .and(smartTypeFilter);
-            } else {
-                smartFilter = TRUE;
-                smartTypeFilter = TRUE;
-            }
-            switch (tp.getLeaf().getKind()) {
-                case MEMBER_SELECT: {
-                    MemberSelectTree mst = (MemberSelectTree)tp.getLeaf();
-                    if (mst.getIdentifier().contentEquals("*"))
-                        break;
-                    TreePath exprPath = new TreePath(tp, mst.getExpression());
-                    TypeMirror site = at.trees().getTypeMirror(exprPath);
-                    boolean staticOnly = isStaticContext(at, exprPath);
-                    ImportTree it = findImport(tp);
-                    boolean isImport = it != null;
-
-                    List<? extends Element> members = membersOf(at, site, staticOnly && !isImport);
-                    Predicate<Element> filter = accessibility;
-                    Function<Boolean, String> paren = DEFAULT_PAREN;
+        return proc.taskFactory.analyze(code, at -> {
+            SourcePositions sp = at.trees().getSourcePositions();
+            CompilationUnitTree topLevel = at.firstCuTree();
+            List<Suggestion> result = new ArrayList<>();
+            TreePath tp = pathFor(topLevel, sp, code.snippetIndexToWrapIndex(cursor));
+            if (tp != null) {
+                Scope scope = at.trees().getScope(tp);
+                Predicate<Element> accessibility = createAccessibilityFilter(at, tp);
+                Predicate<Element> smartTypeFilter;
+                Predicate<Element> smartFilter;
+                Iterable<TypeMirror> targetTypes = findTargetType(at, tp);
+                if (targetTypes != null) {
+                    smartTypeFilter = el -> {
+                        TypeMirror resultOf = resultTypeOf(el);
+                        return Util.stream(targetTypes)
+                                .anyMatch(targetType -> at.getTypes().isAssignable(resultOf, targetType));
+                    };
 
-                    if (isNewClass(tp)) { // new xxx.|
-                        Predicate<Element> constructorFilter = accessibility.and(IS_CONSTRUCTOR)
-                            .and(el -> {
-                                if (el.getEnclosingElement().getEnclosingElement().getKind() == ElementKind.CLASS) {
-                                    return el.getEnclosingElement().getModifiers().contains(Modifier.STATIC);
-                                }
-                                return true;
-                            });
-                        addElements(membersOf(at, members), constructorFilter, smartFilter, result);
+                    smartFilter = IS_CLASS.negate()
+                                          .and(IS_INTERFACE.negate())
+                                          .and(IS_PACKAGE.negate())
+                                          .and(smartTypeFilter);
+                } else {
+                    smartFilter = TRUE;
+                    smartTypeFilter = TRUE;
+                }
+                switch (tp.getLeaf().getKind()) {
+                    case MEMBER_SELECT: {
+                        MemberSelectTree mst = (MemberSelectTree)tp.getLeaf();
+                        if (mst.getIdentifier().contentEquals("*"))
+                            break;
+                        TreePath exprPath = new TreePath(tp, mst.getExpression());
+                        TypeMirror site = at.trees().getTypeMirror(exprPath);
+                        boolean staticOnly = isStaticContext(at, exprPath);
+                        ImportTree it = findImport(tp);
+                        boolean isImport = it != null;
+
+                        List<? extends Element> members = membersOf(at, site, staticOnly && !isImport);
+                        Predicate<Element> filter = accessibility;
+                        Function<Boolean, String> paren = DEFAULT_PAREN;
 
-                        filter = filter.and(IS_PACKAGE);
-                    } else if (isThrowsClause(tp)) {
-                        staticOnly = true;
-                        filter = filter.and(IS_PACKAGE.or(IS_CLASS).or(IS_INTERFACE));
-                        smartFilter = IS_PACKAGE.negate().and(smartTypeFilter);
-                    } else if (isImport) {
-                        paren = NO_PAREN;
-                        if (!it.isStatic()) {
+                        if (isNewClass(tp)) { // new xxx.|
+                            Predicate<Element> constructorFilter = accessibility.and(IS_CONSTRUCTOR)
+                                .and(el -> {
+                                    if (el.getEnclosingElement().getEnclosingElement().getKind() == ElementKind.CLASS) {
+                                        return el.getEnclosingElement().getModifiers().contains(Modifier.STATIC);
+                                    }
+                                    return true;
+                                });
+                            addElements(membersOf(at, members), constructorFilter, smartFilter, result);
+
+                            filter = filter.and(IS_PACKAGE);
+                        } else if (isThrowsClause(tp)) {
+                            staticOnly = true;
                             filter = filter.and(IS_PACKAGE.or(IS_CLASS).or(IS_INTERFACE));
+                            smartFilter = IS_PACKAGE.negate().and(smartTypeFilter);
+                        } else if (isImport) {
+                            paren = NO_PAREN;
+                            if (!it.isStatic()) {
+                                filter = filter.and(IS_PACKAGE.or(IS_CLASS).or(IS_INTERFACE));
+                            }
+                        } else {
+                            filter = filter.and(IS_CONSTRUCTOR.negate());
                         }
-                    } else {
-                        filter = filter.and(IS_CONSTRUCTOR.negate());
-                    }
-
-                    filter = filter.and(staticOnly ? STATIC_ONLY : INSTANCE_ONLY);
 
-                    addElements(members, filter, smartFilter, paren, result);
-                    break;
-                }
-                case IDENTIFIER:
-                    if (isNewClass(tp)) {
-                        Function<Element, Iterable<? extends Element>> listEnclosed =
-                                el -> el.getKind() == ElementKind.PACKAGE ? Collections.singletonList(el)
-                                                                          : el.getEnclosedElements();
-                        Predicate<Element> filter = accessibility.and(IS_CONSTRUCTOR.or(IS_PACKAGE));
-                        NewClassTree newClassTree = (NewClassTree)tp.getParentPath().getLeaf();
-                        ExpressionTree enclosingExpression = newClassTree.getEnclosingExpression();
-                        if (enclosingExpression != null) { // expr.new IDENT|
-                            TypeMirror site = at.trees().getTypeMirror(new TreePath(tp, enclosingExpression));
-                            filter = filter.and(el -> el.getEnclosingElement().getKind() == ElementKind.CLASS && !el.getEnclosingElement().getModifiers().contains(Modifier.STATIC));
-                            addElements(membersOf(at, membersOf(at, site, false)), filter, smartFilter, result);
-                        } else {
-                            addScopeElements(at, scope, listEnclosed, filter, smartFilter, result);
-                        }
+                        filter = filter.and(staticOnly ? STATIC_ONLY : INSTANCE_ONLY);
+
+                        addElements(members, filter, smartFilter, paren, result);
                         break;
                     }
-                    if (isThrowsClause(tp)) {
-                        Predicate<Element> accept = accessibility.and(STATIC_ONLY)
-                                .and(IS_PACKAGE.or(IS_CLASS).or(IS_INTERFACE));
-                        addScopeElements(at, scope, IDENTITY, accept, IS_PACKAGE.negate().and(smartTypeFilter), result);
+                    case IDENTIFIER:
+                        if (isNewClass(tp)) {
+                            Function<Element, Iterable<? extends Element>> listEnclosed =
+                                    el -> el.getKind() == ElementKind.PACKAGE ? Collections.singletonList(el)
+                                                                              : el.getEnclosedElements();
+                            Predicate<Element> filter = accessibility.and(IS_CONSTRUCTOR.or(IS_PACKAGE));
+                            NewClassTree newClassTree = (NewClassTree)tp.getParentPath().getLeaf();
+                            ExpressionTree enclosingExpression = newClassTree.getEnclosingExpression();
+                            if (enclosingExpression != null) { // expr.new IDENT|
+                                TypeMirror site = at.trees().getTypeMirror(new TreePath(tp, enclosingExpression));
+                                filter = filter.and(el -> el.getEnclosingElement().getKind() == ElementKind.CLASS && !el.getEnclosingElement().getModifiers().contains(Modifier.STATIC));
+                                addElements(membersOf(at, membersOf(at, site, false)), filter, smartFilter, result);
+                            } else {
+                                addScopeElements(at, scope, listEnclosed, filter, smartFilter, result);
+                            }
+                            break;
+                        }
+                        if (isThrowsClause(tp)) {
+                            Predicate<Element> accept = accessibility.and(STATIC_ONLY)
+                                    .and(IS_PACKAGE.or(IS_CLASS).or(IS_INTERFACE));
+                            addScopeElements(at, scope, IDENTITY, accept, IS_PACKAGE.negate().and(smartTypeFilter), result);
+                            break;
+                        }
+                        ImportTree it = findImport(tp);
+                        if (it != null) {
+                            // the context of the identifier is an import, look for
+                            // package names that start with the identifier.
+                            // If and when Java allows imports from the default
+                            // package to the the default package which would allow
+                            // JShell to change to use the default package, and that
+                            // change is done, then this should use some variation
+                            // of membersOf(at, at.getElements().getPackageElement("").asType(), false)
+                            addElements(listPackages(at, ""),
+                                    it.isStatic()
+                                            ? STATIC_ONLY.and(accessibility)
+                                            : accessibility,
+                                    smartFilter, result);
+                        }
+                        break;
+                    case CLASS: {
+                        Predicate<Element> accept = accessibility.and(IS_TYPE);
+                        addScopeElements(at, scope, IDENTITY, accept, smartFilter, result);
+                        addElements(primitivesOrVoid(at), TRUE, smartFilter, result);
                         break;
                     }
-                    ImportTree it = findImport(tp);
-                    if (it != null) {
-                        // the context of the identifier is an import, look for
-                        // package names that start with the identifier.
-                        // If and when Java allows imports from the default
-                        // package to the the default package which would allow
-                        // JShell to change to use the default package, and that
-                        // change is done, then this should use some variation
-                        // of membersOf(at, at.getElements().getPackageElement("").asType(), false)
-                        addElements(listPackages(at, ""),
-                                it.isStatic()
-                                        ? STATIC_ONLY.and(accessibility)
-                                        : accessibility,
-                                smartFilter, result);
-                    }
-                    break;
-                case CLASS: {
-                    Predicate<Element> accept = accessibility.and(IS_TYPE);
-                    addScopeElements(at, scope, IDENTITY, accept, smartFilter, result);
-                    addElements(primitivesOrVoid(at), TRUE, smartFilter, result);
-                    break;
-                }
-                case BLOCK:
-                case EMPTY_STATEMENT:
-                case ERRONEOUS: {
-                    boolean staticOnly = ReplResolve.isStatic(((JavacScope)scope).getEnv());
-                    Predicate<Element> accept = accessibility.and(staticOnly ? STATIC_ONLY : TRUE);
-                    if (isClass(tp)) {
-                        ClassTree clazz = (ClassTree) tp.getParentPath().getLeaf();
-                        if (clazz.getExtendsClause() == tp.getLeaf()) {
-                            accept = accept.and(IS_TYPE);
-                            smartFilter = smartFilter.and(el -> el.getKind() == ElementKind.CLASS);
-                        } else {
-                            Predicate<Element> f = smartFilterFromList(at, tp, clazz.getImplementsClause(), tp.getLeaf());
+                    case BLOCK:
+                    case EMPTY_STATEMENT:
+                    case ERRONEOUS: {
+                        boolean staticOnly = ReplResolve.isStatic(((JavacScope)scope).getEnv());
+                        Predicate<Element> accept = accessibility.and(staticOnly ? STATIC_ONLY : TRUE);
+                        if (isClass(tp)) {
+                            ClassTree clazz = (ClassTree) tp.getParentPath().getLeaf();
+                            if (clazz.getExtendsClause() == tp.getLeaf()) {
+                                accept = accept.and(IS_TYPE);
+                                smartFilter = smartFilter.and(el -> el.getKind() == ElementKind.CLASS);
+                            } else {
+                                Predicate<Element> f = smartFilterFromList(at, tp, clazz.getImplementsClause(), tp.getLeaf());
+                                if (f != null) {
+                                    accept = accept.and(IS_TYPE);
+                                    smartFilter = f.and(el -> el.getKind() == ElementKind.INTERFACE);
+                                }
+                            }
+                        } else if (isTypeParameter(tp)) {
+                            TypeParameterTree tpt = (TypeParameterTree) tp.getParentPath().getLeaf();
+                            Predicate<Element> f = smartFilterFromList(at, tp, tpt.getBounds(), tp.getLeaf());
                             if (f != null) {
                                 accept = accept.and(IS_TYPE);
-                                smartFilter = f.and(el -> el.getKind() == ElementKind.INTERFACE);
+                                smartFilter = f;
+                                if (!tpt.getBounds().isEmpty() && tpt.getBounds().get(0) != tp.getLeaf()) {
+                                    smartFilter = smartFilter.and(el -> el.getKind() == ElementKind.INTERFACE);
+                                }
+                            }
+                        } else if (isVariable(tp)) {
+                            VariableTree var = (VariableTree) tp.getParentPath().getLeaf();
+                            if (var.getType() == tp.getLeaf()) {
+                                accept = accept.and(IS_TYPE);
                             }
                         }
-                    } else if (isTypeParameter(tp)) {
-                        TypeParameterTree tpt = (TypeParameterTree) tp.getParentPath().getLeaf();
-                        Predicate<Element> f = smartFilterFromList(at, tp, tpt.getBounds(), tp.getLeaf());
-                        if (f != null) {
-                            accept = accept.and(IS_TYPE);
-                            smartFilter = f;
-                            if (!tpt.getBounds().isEmpty() && tpt.getBounds().get(0) != tp.getLeaf()) {
-                                smartFilter = smartFilter.and(el -> el.getKind() == ElementKind.INTERFACE);
-                            }
-                        }
-                    } else if (isVariable(tp)) {
-                        VariableTree var = (VariableTree) tp.getParentPath().getLeaf();
-                        if (var.getType() == tp.getLeaf()) {
-                            accept = accept.and(IS_TYPE);
-                        }
-                    }
 
-                    addScopeElements(at, scope, IDENTITY, accept, smartFilter, result);
+                        addScopeElements(at, scope, IDENTITY, accept, smartFilter, result);
 
-                    Tree parent = tp.getParentPath().getLeaf();
-                    switch (parent.getKind()) {
-                        case VARIABLE:
-                            accept = ((VariableTree)parent).getType() == tp.getLeaf() ?
-                                    IS_VOID.negate() :
-                                    TRUE;
-                            break;
-                        case PARAMETERIZED_TYPE: // TODO: JEP 218: Generics over Primitive Types
-                        case TYPE_PARAMETER:
-                        case CLASS:
-                        case INTERFACE:
-                        case ENUM:
-                            accept = FALSE;
-                            break;
-                        default:
-                            accept = TRUE;
-                            break;
+                        Tree parent = tp.getParentPath().getLeaf();
+                        switch (parent.getKind()) {
+                            case VARIABLE:
+                                accept = ((VariableTree)parent).getType() == tp.getLeaf() ?
+                                        IS_VOID.negate() :
+                                        TRUE;
+                                break;
+                            case PARAMETERIZED_TYPE: // TODO: JEP 218: Generics over Primitive Types
+                            case TYPE_PARAMETER:
+                            case CLASS:
+                            case INTERFACE:
+                            case ENUM:
+                                accept = FALSE;
+                                break;
+                            default:
+                                accept = TRUE;
+                                break;
+                        }
+                        addElements(primitivesOrVoid(at), accept, smartFilter, result);
+                        break;
                     }
-                    addElements(primitivesOrVoid(at), accept, smartFilter, result);
-                    break;
                 }
             }
-        }
-        anchor[0] = cursor;
-        return result;
+            anchor[0] = cursor;
+            return result;
+        });
     }
 
     private static final Set<Kind> CLASS_KINDS = EnumSet.of(
@@ -1167,78 +1169,79 @@
             return Collections.emptyList();
 
         OuterWrap codeWrap = proc.outerMap.wrapInTrialClass(Wrap.methodWrap(code));
-        AnalyzeTask at = proc.taskFactory.new AnalyzeTask(codeWrap, keepParameterNames);
-        SourcePositions sp = at.trees().getSourcePositions();
-        CompilationUnitTree topLevel = at.firstCuTree();
-        TreePath tp = pathFor(topLevel, sp, codeWrap.snippetIndexToWrapIndex(cursor));
-
-        if (tp == null)
-            return Collections.emptyList();
-
-        TreePath prevPath = null;
-        while (tp != null && tp.getLeaf().getKind() != Kind.METHOD_INVOCATION &&
-               tp.getLeaf().getKind() != Kind.NEW_CLASS && tp.getLeaf().getKind() != Kind.IDENTIFIER &&
-               tp.getLeaf().getKind() != Kind.MEMBER_SELECT) {
-            prevPath = tp;
-            tp = tp.getParentPath();
-        }
+        return proc.taskFactory.analyze(codeWrap, List.of(keepParameterNames), at -> {
+            SourcePositions sp = at.trees().getSourcePositions();
+            CompilationUnitTree topLevel = at.firstCuTree();
+            TreePath tp = pathFor(topLevel, sp, codeWrap.snippetIndexToWrapIndex(cursor));
 
-        if (tp == null)
-            return Collections.emptyList();
-
-        Stream<Element> elements;
-        Iterable<Pair<ExecutableElement, ExecutableType>> candidates;
-        List<? extends ExpressionTree> arguments;
+            if (tp == null)
+                return Collections.emptyList();
 
-        if (tp.getLeaf().getKind() == Kind.METHOD_INVOCATION || tp.getLeaf().getKind() == Kind.NEW_CLASS) {
-            if (tp.getLeaf().getKind() == Kind.METHOD_INVOCATION) {
-                MethodInvocationTree mit = (MethodInvocationTree) tp.getLeaf();
-                candidates = methodCandidates(at, tp);
-                arguments = mit.getArguments();
-            } else {
-                NewClassTree nct = (NewClassTree) tp.getLeaf();
-                candidates = newClassCandidates(at, tp);
-                arguments = nct.getArguments();
+            TreePath prevPath = null;
+            while (tp != null && tp.getLeaf().getKind() != Kind.METHOD_INVOCATION &&
+                   tp.getLeaf().getKind() != Kind.NEW_CLASS && tp.getLeaf().getKind() != Kind.IDENTIFIER &&
+                   tp.getLeaf().getKind() != Kind.MEMBER_SELECT) {
+                prevPath = tp;
+                tp = tp.getParentPath();
             }
 
-            if (!isEmptyArgumentsContext(arguments)) {
-                List<TypeMirror> actuals = computeActualInvocationTypes(at, arguments, prevPath);
-                List<TypeMirror> fullActuals = actuals != null ? actuals : Collections.emptyList();
+            if (tp == null)
+                return Collections.emptyList();
+
+            Stream<Element> elements;
+            Iterable<Pair<ExecutableElement, ExecutableType>> candidates;
+            List<? extends ExpressionTree> arguments;
+
+            if (tp.getLeaf().getKind() == Kind.METHOD_INVOCATION || tp.getLeaf().getKind() == Kind.NEW_CLASS) {
+                if (tp.getLeaf().getKind() == Kind.METHOD_INVOCATION) {
+                    MethodInvocationTree mit = (MethodInvocationTree) tp.getLeaf();
+                    candidates = methodCandidates(at, tp);
+                    arguments = mit.getArguments();
+                } else {
+                    NewClassTree nct = (NewClassTree) tp.getLeaf();
+                    candidates = newClassCandidates(at, tp);
+                    arguments = nct.getArguments();
+                }
 
-                candidates =
-                        this.filterExecutableTypesByArguments(at, candidates, fullActuals)
-                            .stream()
-                            .filter(method -> parameterType(method.fst, method.snd, fullActuals.size(), true).findAny().isPresent())
-                            .collect(Collectors.toList());
-            }
+                if (!isEmptyArgumentsContext(arguments)) {
+                    List<TypeMirror> actuals = computeActualInvocationTypes(at, arguments, prevPath);
+                    List<TypeMirror> fullActuals = actuals != null ? actuals : Collections.emptyList();
+
+                    candidates =
+                            this.filterExecutableTypesByArguments(at, candidates, fullActuals)
+                                .stream()
+                                .filter(method -> parameterType(method.fst, method.snd, fullActuals.size(), true).findAny().isPresent())
+                                .collect(Collectors.toList());
+                }
 
-            elements = Util.stream(candidates).map(method -> method.fst);
-        } else if (tp.getLeaf().getKind() == Kind.IDENTIFIER || tp.getLeaf().getKind() == Kind.MEMBER_SELECT) {
-            Element el = at.trees().getElement(tp);
+                elements = Util.stream(candidates).map(method -> method.fst);
+            } else if (tp.getLeaf().getKind() == Kind.IDENTIFIER || tp.getLeaf().getKind() == Kind.MEMBER_SELECT) {
+                Element el = at.trees().getElement(tp);
 
-            if (el == null ||
-                el.asType().getKind() == TypeKind.ERROR ||
-                (el.getKind() == ElementKind.PACKAGE && el.getEnclosedElements().isEmpty())) {
-                //erroneous element:
+                if (el == null ||
+                    el.asType().getKind() == TypeKind.ERROR ||
+                    (el.getKind() == ElementKind.PACKAGE && el.getEnclosedElements().isEmpty())) {
+                    //erroneous element:
+                    return Collections.emptyList();
+                }
+
+                elements = Stream.of(el);
+            } else {
                 return Collections.emptyList();
             }
 
-            elements = Stream.of(el);
-        } else {
-            return Collections.emptyList();
-        }
-
-        List<Documentation> result = Collections.emptyList();
+            List<Documentation> result = Collections.emptyList();
 
-        try (JavadocHelper helper = JavadocHelper.create(at.task, findSources())) {
-            result = elements.map(el -> constructDocumentation(at, helper, el, computeJavadoc))
-                             .filter(Objects::nonNull)
-                             .collect(Collectors.toList());
-        } catch (IOException ex) {
-            proc.debug(ex, "JavadocHelper.close()");
-        }
+            try (JavadocHelper helper = JavadocHelper.create(at.task, findSources())) {
+                result = elements.map(el -> constructDocumentation(at, helper, el, computeJavadoc))
+                                 .filter(Objects::nonNull)
+                                 .collect(Collectors.toList());
+            } catch (IOException ex) {
+                proc.debug(ex, "JavadocHelper.close()");
+            }
 
-        return result;
+            return result;
+        });
     }
 
     private Documentation constructDocumentation(AnalyzeTask at, JavadocHelper helper, Element el, boolean computeJavadoc) {
@@ -1494,51 +1497,52 @@
 
     @Override
     public QualifiedNames listQualifiedNames(String code, int cursor) {
-        code = code.substring(0, cursor);
-        if (code.trim().isEmpty()) {
+        String codeFin = code.substring(0, cursor);
+        if (codeFin.trim().isEmpty()) {
             return new QualifiedNames(Collections.emptyList(), -1, true, false);
         }
         OuterWrap codeWrap;
-        switch (guessKind(code)) {
+        switch (guessKind(codeFin)) {
             case IMPORT:
                 return new QualifiedNames(Collections.emptyList(), -1, true, false);
             case METHOD:
-                codeWrap = proc.outerMap.wrapInTrialClass(Wrap.classMemberWrap(code));
+                codeWrap = proc.outerMap.wrapInTrialClass(Wrap.classMemberWrap(codeFin));
                 break;
             default:
-                codeWrap = proc.outerMap.wrapInTrialClass(Wrap.methodWrap(code));
+                codeWrap = proc.outerMap.wrapInTrialClass(Wrap.methodWrap(codeFin));
                 break;
         }
-        AnalyzeTask at = proc.taskFactory.new AnalyzeTask(codeWrap);
-        SourcePositions sp = at.trees().getSourcePositions();
-        CompilationUnitTree topLevel = at.firstCuTree();
-        TreePath tp = pathFor(topLevel, sp, codeWrap.snippetIndexToWrapIndex(code.length()));
-        if (tp.getLeaf().getKind() != Kind.IDENTIFIER) {
-            return new QualifiedNames(Collections.emptyList(), -1, true, false);
-        }
-        Scope scope = at.trees().getScope(tp);
-        TypeMirror type = at.trees().getTypeMirror(tp);
-        Element el = at.trees().getElement(tp);
+        return proc.taskFactory.analyze(codeWrap, at -> {
+            SourcePositions sp = at.trees().getSourcePositions();
+            CompilationUnitTree topLevel = at.firstCuTree();
+            TreePath tp = pathFor(topLevel, sp, codeWrap.snippetIndexToWrapIndex(codeFin.length()));
+            if (tp.getLeaf().getKind() != Kind.IDENTIFIER) {
+                return new QualifiedNames(Collections.emptyList(), -1, true, false);
+            }
+            Scope scope = at.trees().getScope(tp);
+            TypeMirror type = at.trees().getTypeMirror(tp);
+            Element el = at.trees().getElement(tp);
 
-        boolean erroneous = (type.getKind() == TypeKind.ERROR && el.getKind() == ElementKind.CLASS) ||
-                            (el.getKind() == ElementKind.PACKAGE && el.getEnclosedElements().isEmpty());
-        String simpleName = ((IdentifierTree) tp.getLeaf()).getName().toString();
-        boolean upToDate;
-        List<String> result;
+            boolean erroneous = (type.getKind() == TypeKind.ERROR && el.getKind() == ElementKind.CLASS) ||
+                                (el.getKind() == ElementKind.PACKAGE && el.getEnclosedElements().isEmpty());
+            String simpleName = ((IdentifierTree) tp.getLeaf()).getName().toString();
+            boolean upToDate;
+            List<String> result;
 
-        synchronized (currentIndexes) {
-            upToDate = classpathVersion == indexVersion;
-            result = currentIndexes.values()
-                                   .stream()
-                                   .flatMap(idx -> idx.classSimpleName2FQN.getOrDefault(simpleName,
-                                                                                        Collections.emptyList()).stream())
-                                   .distinct()
-                                   .filter(fqn -> isAccessible(at, scope, fqn))
-                                   .sorted()
-                                   .collect(Collectors.toList());
-        }
+            synchronized (currentIndexes) {
+                upToDate = classpathVersion == indexVersion;
+                result = currentIndexes.values()
+                                       .stream()
+                                       .flatMap(idx -> idx.classSimpleName2FQN.getOrDefault(simpleName,
+                                                                                            Collections.emptyList()).stream())
+                                       .distinct()
+                                       .filter(fqn -> isAccessible(at, scope, fqn))
+                                       .sorted()
+                                       .collect(Collectors.toList());
+            }
 
-        return new QualifiedNames(result, simpleName.length(), upToDate, !erroneous);
+            return new QualifiedNames(result, simpleName.length(), upToDate, !erroneous);
+        });
     }
 
     private boolean isAccessible(AnalyzeTask at, Scope scope, String fqn) {
--- a/src/jdk.jshell/share/classes/jdk/jshell/TaskFactory.java	Mon Oct 16 08:47:59 2017 -0700
+++ b/src/jdk.jshell/share/classes/jdk/jshell/TaskFactory.java	Tue Oct 17 14:33:32 2017 -0700
@@ -29,10 +29,8 @@
 import com.sun.source.tree.Tree;
 import com.sun.source.util.Trees;
 import com.sun.tools.javac.api.JavacTaskImpl;
-import com.sun.tools.javac.api.JavacTool;
 import com.sun.tools.javac.util.Context;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.List;
 import javax.tools.Diagnostic;
 import javax.tools.DiagnosticCollector;
@@ -62,18 +60,28 @@
 import jdk.jshell.MemoryFileManager.SourceMemoryJavaFileObject;
 import java.lang.Runtime.Version;
 import java.nio.CharBuffer;
+import java.util.function.BiFunction;
 import com.sun.source.tree.Tree.Kind;
+import com.sun.source.util.TaskEvent;
+import com.sun.source.util.TaskListener;
+import com.sun.tools.javac.api.JavacTaskPool;
+import com.sun.tools.javac.code.ClassFinder;
 import com.sun.tools.javac.code.Kinds;
 import com.sun.tools.javac.code.Symbol.ClassSymbol;
+import com.sun.tools.javac.code.Symbol.PackageSymbol;
 import com.sun.tools.javac.code.Symbol.VarSymbol;
+import com.sun.tools.javac.code.Symtab;
+import com.sun.tools.javac.comp.Attr;
 import com.sun.tools.javac.parser.Parser;
+import com.sun.tools.javac.parser.ParserFactory;
 import com.sun.tools.javac.tree.JCTree.JCClassDecl;
 import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
 import com.sun.tools.javac.tree.JCTree.JCExpression;
 import com.sun.tools.javac.tree.JCTree.JCTypeCast;
 import com.sun.tools.javac.tree.JCTree.Tag;
-import com.sun.tools.javac.util.Context.Factory;
+import com.sun.tools.javac.util.Log;
 import com.sun.tools.javac.util.Log.DiscardDiagnosticHandler;
+import com.sun.tools.javac.util.Names;
 import jdk.jshell.Snippet.Status;
 
 /**
@@ -101,6 +109,7 @@
         }
         this.fileManager = new MemoryFileManager(
                 compiler.getStandardFileManager(null, null, null), state);
+        initTaskPool();
     }
 
     void addToClasspath(String path) {
@@ -108,27 +117,130 @@
         List<String> args = new ArrayList<>();
         args.add(classpath);
         fileManager().handleOption("-classpath", args.iterator());
+        initTaskPool();
     }
 
     MemoryFileManager fileManager() {
         return fileManager;
     }
 
+    public <Z> Z parse(String source,
+                       boolean forceExpression,
+                       Worker<ParseTask, Z> worker) {
+        StringSourceHandler sh = new StringSourceHandler();
+        return runTask(Stream.of(source),
+                       sh,
+                       List.of("-XDallowStringFolding=false", "-proc:none",
+                               "-XDneedsReplParserFactory=" + forceExpression),
+                       (jti, diagnostics) -> new ParseTask(sh, jti, diagnostics, forceExpression),
+                       worker);
+    }
+
+    public <Z> Z analyze(OuterWrap wrap,
+                         Worker<AnalyzeTask, Z> worker) {
+        return analyze(Collections.singletonList(wrap), worker);
+    }
+
+    public <Z> Z analyze(OuterWrap wrap,
+                         List<String> extraArgs,
+                         Worker<AnalyzeTask, Z> worker) {
+        return analyze(Collections.singletonList(wrap), extraArgs, worker);
+    }
+
+    public <Z> Z analyze(Collection<OuterWrap> wraps,
+                         Worker<AnalyzeTask, Z> worker) {
+        return analyze(wraps, Collections.emptyList(), worker);
+    }
+
+    public <Z> Z analyze(Collection<OuterWrap> wraps,
+                         List<String> extraArgs,
+                         Worker<AnalyzeTask, Z> worker) {
+        WrapSourceHandler sh = new WrapSourceHandler();
+        List<String> allOptions = new ArrayList<>();
+
+        allOptions.add("--should-stop:at=FLOW");
+        allOptions.add("-Xlint:unchecked");
+        allOptions.add("-proc:none");
+        allOptions.addAll(extraArgs);
+
+        return runTask(wraps.stream(),
+                       sh,
+                       allOptions,
+                       (jti, diagnostics) -> new AnalyzeTask(sh, jti, diagnostics),
+                       worker);
+    }
+
+    public <Z> Z compile(Collection<OuterWrap> wraps,
+                         Worker<CompileTask, Z> worker) {
+        WrapSourceHandler sh = new WrapSourceHandler();
+
+        return runTask(wraps.stream(),
+                       sh,
+                       List.of("-Xlint:unchecked", "-proc:none", "-parameters"),
+                       (jti, diagnostics) -> new CompileTask(sh, jti, diagnostics),
+                       worker);
+    }
+
+    private <S, T extends BaseTask, Z> Z runTask(Stream<S> inputs,
+                                                 SourceHandler<S> sh,
+                                                 List<String> options,
+                                                 BiFunction<JavacTaskImpl, DiagnosticCollector<JavaFileObject>, T> creator,
+                                                 Worker<T, Z> worker) {
+            List<String> allOptions = new ArrayList<>(options.size() + state.extraCompilerOptions.size());
+            allOptions.addAll(options);
+            allOptions.addAll(state.extraCompilerOptions);
+            Iterable<? extends JavaFileObject> compilationUnits = inputs
+                            .map(in -> sh.sourceToFileObject(fileManager, in))
+                            .collect(Collectors.toList());
+            DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<>();
+            return javacTaskPool.getTask(null, fileManager, diagnostics, allOptions, null,
+                                         compilationUnits, task -> {
+                 JavacTaskImpl jti = (JavacTaskImpl) task;
+                 Context context = jti.getContext();
+                 jti.addTaskListener(new TaskListenerImpl(context, state));
+                 try {
+                     return worker.withTask(creator.apply(jti, diagnostics));
+                 } finally {
+                     //additional cleanup: purge the REPL package:
+                     Symtab syms = Symtab.instance(context);
+                     Names names = Names.instance(context);
+                     PackageSymbol repl = syms.getPackage(syms.unnamedModule, names.fromString(Util.REPL_PACKAGE));
+                     if (repl != null) {
+                         for (ClassSymbol clazz : syms.getAllClasses()) {
+                             if (clazz.packge() == repl) {
+                                 syms.removeClass(syms.unnamedModule, clazz.flatName());
+                             }
+                         }
+                         repl.members_field = null;
+                         repl.completer = ClassFinder.instance(context).getCompleter();
+                     }
+                 }
+            });
+    }
+
+    interface Worker<T extends BaseTask, Z> {
+        public Z withTask(T task);
+    }
+
     // Parse a snippet and return our parse task handler
-    ParseTask parse(final String source) {
-        ParseTask pt = state.taskFactory.new ParseTask(source, false);
-        if (!pt.units().isEmpty()
-                && pt.units().get(0).getKind() == Kind.EXPRESSION_STATEMENT
-                && pt.getDiagnostics().hasOtherThanNotStatementErrors()) {
-            // It failed, it may be an expression being incorrectly
-            // parsed as having a leading type variable, example:   a < b
-            // Try forcing interpretation as an expression
-            ParseTask ept = state.taskFactory.new ParseTask(source, true);
-            if (!ept.getDiagnostics().hasOtherThanNotStatementErrors()) {
-                return ept;
+    <Z> Z parse(final String source, Worker<ParseTask, Z> worker) {
+        return parse(source, false, pt -> {
+            if (!pt.units().isEmpty()
+                    && pt.units().get(0).getKind() == Kind.EXPRESSION_STATEMENT
+                    && pt.getDiagnostics().hasOtherThanNotStatementErrors()) {
+                // It failed, it may be an expression being incorrectly
+                // parsed as having a leading type variable, example:   a < b
+                // Try forcing interpretation as an expression
+                return parse(source, true, ept -> {
+                    if (!ept.getDiagnostics().hasOtherThanNotStatementErrors()) {
+                        return worker.withTask(ept);
+                    } else {
+                        return worker.withTask(pt);
+                    }
+                });
             }
-        }
-        return pt;
+            return worker.withTask(pt);
+        });
     }
 
     private interface SourceHandler<T> {
@@ -210,11 +322,12 @@
         private final Iterable<? extends CompilationUnitTree> cuts;
         private final List<? extends Tree> units;
 
-        ParseTask(final String source, final boolean forceExpression) {
-            super(Stream.of(source),
-                    new StringSourceHandler(),
-                    "-XDallowStringFolding=false", "-proc:none");
-            ReplParserFactory.preRegister(getContext(), forceExpression);
+        private ParseTask(SourceHandler<String> sh,
+                          JavacTaskImpl task,
+                          DiagnosticCollector<JavaFileObject> diagnostics,
+                          boolean forceExpression) {
+            super(sh, task, diagnostics);
+            ReplParserFactory.preRegister(context, forceExpression);
             cuts = parse();
             units = Util.stream(cuts)
                     .flatMap(cut -> {
@@ -249,22 +362,10 @@
 
         private final Iterable<? extends CompilationUnitTree> cuts;
 
-        AnalyzeTask(final OuterWrap wrap, String... extraArgs) {
-            this(Collections.singletonList(wrap), extraArgs);
-        }
-
-        AnalyzeTask(final Collection<OuterWrap> wraps, String... extraArgs) {
-            this(wraps.stream(),
-                    new WrapSourceHandler(),
-                    Util.join(new String[] {
-                        "--should-stop:at=FLOW", "-Xlint:unchecked",
-                        "-proc:none"
-                    }, extraArgs));
-        }
-
-        private <T>AnalyzeTask(final Stream<T> stream, SourceHandler<T> sourceHandler,
-                String... extraOptions) {
-            super(stream, sourceHandler, extraOptions);
+        private AnalyzeTask(SourceHandler<OuterWrap> sh,
+                            JavacTaskImpl task,
+                            DiagnosticCollector<JavaFileObject> diagnostics) {
+            super(sh, task, diagnostics);
             cuts = analyze();
         }
 
@@ -299,9 +400,10 @@
 
         private final Map<OuterWrap, List<OutputMemoryJavaFileObject>> classObjs = new HashMap<>();
 
-        CompileTask(final Collection<OuterWrap> wraps) {
-            super(wraps.stream(), new WrapSourceHandler(),
-                    "-Xlint:unchecked", "-proc:none", "-parameters");
+        CompileTask(SourceHandler<OuterWrap>sh,
+                    JavacTaskImpl jti,
+                    DiagnosticCollector<JavaFileObject> diagnostics) {
+            super(sh, jti, diagnostics);
         }
 
         boolean compile() {
@@ -346,32 +448,30 @@
         }
     }
 
+    private JavacTaskPool javacTaskPool;
+
+    private void initTaskPool() {
+        javacTaskPool = new JavacTaskPool(5);
+    }
+
     abstract class BaseTask {
 
-        final DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<>();
+        final DiagnosticCollector<JavaFileObject> diagnostics;
         final JavacTaskImpl task;
         private DiagList diags = null;
         private final SourceHandler<?> sourceHandler;
-        final Context context = new Context();
+        final Context context;
         private Types types;
         private JavacMessages messages;
         private Trees trees;
 
-        private <T>BaseTask(Stream<T> inputs,
-                //BiFunction<MemoryFileManager, T, JavaFileObject> sfoCreator,
-                SourceHandler<T> sh,
-                String... extraOptions) {
+        private <T>BaseTask(SourceHandler<T> sh,
+                            JavacTaskImpl task,
+                            DiagnosticCollector<JavaFileObject> diagnostics) {
             this.sourceHandler = sh;
-            List<String> options = new ArrayList<>(extraOptions.length + state.extraCompilerOptions.size());
-            options.addAll(Arrays.asList(extraOptions));
-            options.addAll(state.extraCompilerOptions);
-            Iterable<? extends JavaFileObject> compilationUnits = inputs
-                            .map(in -> sh.sourceToFileObject(fileManager, in))
-                            .collect(Collectors.toList());
-            JShellJavaCompiler.preRegister(context, state);
-            this.task = (JavacTaskImpl) ((JavacTool) compiler).getTask(null,
-                    fileManager, diagnostics, options, null,
-                    compilationUnits, context);
+            this.task = task;
+            context = task.getContext();
+            this.diagnostics = diagnostics;
         }
 
         abstract Iterable<? extends CompilationUnitTree> cuTrees();
@@ -478,32 +578,36 @@
         }
     }
 
-    private static final class JShellJavaCompiler extends com.sun.tools.javac.main.JavaCompiler {
+    private static final class TaskListenerImpl implements TaskListener {
 
-        public static void preRegister(Context c, JShell state) {
-            c.put(compilerKey, (Factory<com.sun.tools.javac.main.JavaCompiler>) i -> new JShellJavaCompiler(i, state));
-        }
-
+        private final Context context;
         private final JShell state;
 
-        public JShellJavaCompiler(Context context, JShell state) {
-            super(context);
+        public TaskListenerImpl(Context context, JShell state) {
+            this.context = context;
             this.state = state;
         }
 
         @Override
-        public void processAnnotations(com.sun.tools.javac.util.List<JCCompilationUnit> roots, Collection<String> classnames) {
-            super.processAnnotations(roots, classnames);
+        public void finished(TaskEvent e) {
+            if (e.getKind() != TaskEvent.Kind.ENTER)
+                return ;
             state.maps
                  .snippetList()
                  .stream()
                  .filter(s -> s.status() == Status.VALID)
                  .filter(s -> s.kind() == Snippet.Kind.VAR)
                  .filter(s -> s.subKind() == Snippet.SubKind.VAR_DECLARATION_WITH_INITIALIZER_SUBKIND)
-                 .forEach(s -> setVariableType(roots, (VarSnippet) s));
+                 .forEach(s -> setVariableType((JCCompilationUnit) e.getCompilationUnit(), (VarSnippet) s));
         }
 
-        private void setVariableType(com.sun.tools.javac.util.List<JCCompilationUnit> roots, VarSnippet s) {
+        private void setVariableType(JCCompilationUnit root, VarSnippet s) {
+            Symtab syms = Symtab.instance(context);
+            Names names = Names.instance(context);
+            Log log  = Log.instance(context);
+            ParserFactory parserFactory = ParserFactory.instance(context);
+            Attr attr = Attr.instance(context);
+
             ClassSymbol clazz = syms.getClass(syms.unnamedModule, names.fromString(s.classFullName()));
             if (clazz == null || !clazz.isCompleted())
                 return;
@@ -520,7 +624,7 @@
                         JCTypeCast tree = (JCTypeCast) expr;
                         if (tree.clazz.hasTag(Tag.TYPEINTERSECTION)) {
                             field.type = attr.attribType(tree.clazz,
-                                                         ((JCClassDecl) roots.head.getTypeDecls().head).sym);
+                                                         ((JCClassDecl) root.getTypeDecls().head).sym);
                         }
                     }
                 } finally {
--- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/IdentNode.java	Mon Oct 16 08:47:59 2017 -0700
+++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/IdentNode.java	Tue Oct 17 14:33:32 2017 -0700
@@ -477,4 +477,14 @@
     public IdentNode setIsDestructuredParameter() {
         return new IdentNode(this, name, type, flags | DESTRUCTURED_PARAMETER, programPoint, conversion);
     }
+
+    /**
+     * Checks whether the source code for this ident contains a unicode escape sequence by comparing
+     * the length of its name with its length in source code.
+     *
+     * @return true if ident source contains a unicode escape sequence
+     */
+    public boolean containsEscapes() {
+        return Token.descLength(getToken()) != name.length();
+    }
 }
--- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Lexer.java	Mon Oct 16 08:47:59 2017 -0700
+++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Lexer.java	Tue Oct 17 14:33:32 2017 -0700
@@ -786,15 +786,9 @@
             if (ch0 == '\\' && ch1 == 'u') {
                 skip(2);
                 final int ch = hexSequence(4, TokenType.IDENT);
-                if (isWhitespace((char)ch)) {
-                    return null;
-                }
-                if (ch < 0) {
-                    sb.append('\\');
-                    sb.append('u');
-                } else {
-                    sb.append((char)ch);
-                }
+                assert ! isWhitespace((char)ch);
+                assert ch >= 0;
+                sb.append((char)ch);
             } else {
                 // Add regular character.
                 sb.append(ch0);
@@ -994,9 +988,6 @@
             if (ch0 == '\\') {
                 type = ESCSTRING;
                 skip(1);
-                if (! isEscapeCharacter(ch0)) {
-                    error(Lexer.message("invalid.escape.char"), STRING, position, limit);
-                }
                 if (isEOL(ch0)) {
                     // Multiline string literal
                     skipEOL(false);
@@ -1093,9 +1084,6 @@
             } else if (ch0 == '\\') {
                 skip(1);
                 // EscapeSequence
-                if (!isEscapeCharacter(ch0)) {
-                    error(Lexer.message("invalid.escape.char"), TEMPLATE, position, limit);
-                }
                 if (isEOL(ch0)) {
                     // LineContinuation
                     skipEOL(false);
@@ -1115,16 +1103,6 @@
     }
 
     /**
-     * Is the given character a valid escape char after "\" ?
-     *
-     * @param ch character to be checked
-     * @return if the given character is valid after "\"
-     */
-    protected boolean isEscapeCharacter(final char ch) {
-        return true;
-    }
-
-    /**
      * Convert string to number.
      *
      * @param valueString  String to convert.
--- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java	Mon Oct 16 08:47:59 2017 -0700
+++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java	Tue Oct 17 14:33:32 2017 -0700
@@ -1472,12 +1472,7 @@
      */
     private void verifyIdent(final IdentNode ident, final String contextString) {
         verifyStrictIdent(ident, contextString);
-        if (isES6()) {
-            final TokenType tokenType = TokenLookup.lookupKeyword(ident.getName().toCharArray(), 0, ident.getName().length());
-            if (tokenType != IDENT && tokenType.getKind() != TokenKind.FUTURESTRICT) {
-                throw error(expectMessage(IDENT));
-            }
-        }
+        checkEscapedKeyword(ident);
     }
 
     /**
@@ -1502,6 +1497,18 @@
         }
     }
 
+    /**
+     * ES6 11.6.2: A code point in a ReservedWord cannot be expressed by a | UnicodeEscapeSequence.
+     */
+    private void checkEscapedKeyword(final IdentNode ident) {
+        if (isES6() && ident.containsEscapes()) {
+            final TokenType tokenType = TokenLookup.lookupKeyword(ident.getName().toCharArray(), 0, ident.getName().length());
+            if (tokenType != IDENT && !(tokenType.getKind() == TokenKind.FUTURESTRICT && !isStrictMode)) {
+                throw error(AbstractParser.message("keyword.escaped.character"), ident.getToken());
+            }
+        }
+    }
+
     /*
      * VariableStatement :
      *      var VariableDeclarationList ;
@@ -2646,7 +2653,7 @@
                     });
                 } else {
                     // ECMA 12.4.1 strict mode restrictions
-                    verifyStrictIdent((IdentNode) exception, "catch argument");
+                    verifyIdent((IdentNode) exception, "catch argument");
                 }
 
 
@@ -2761,6 +2768,7 @@
                 break;
             }
             detectSpecialProperty(ident);
+            checkEscapedKeyword(ident);
             return ident;
         case OCTAL_LEGACY:
             if (isStrictMode) {
@@ -3404,6 +3412,7 @@
             // Catch special functions.
             if (lhs instanceof IdentNode) {
                 detectSpecialFunction((IdentNode)lhs);
+                checkEscapedKeyword((IdentNode)lhs);
             }
 
             lhs = new CallNode(callLine, callToken, finish, lhs, arguments, false);
@@ -3779,7 +3788,7 @@
                 expect(IDENT);
             }
             name = getIdent();
-            verifyStrictIdent(name, "function name");
+            verifyIdent(name, "function name");
         } else if (isStatement) {
             // Nashorn extension: anonymous function statements.
             // Do not allow anonymous function statement if extensions
@@ -4871,7 +4880,7 @@
         final String contextString = "function parameter";
         if (param instanceof IdentNode) {
             final IdentNode ident = (IdentNode)param;
-            verifyStrictIdent(ident, contextString);
+            verifyIdent(ident, contextString);
             final ParserContextFunctionNode currentFunction = lc.getCurrentFunction();
             if (currentFunction != null) {
                 currentFunction.addParameterBinding(ident);
--- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/PropertyHashMap.java	Mon Oct 16 08:47:59 2017 -0700
+++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/PropertyHashMap.java	Tue Oct 17 14:33:32 2017 -0700
@@ -31,23 +31,34 @@
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
+import jdk.nashorn.internal.runtime.options.Options;
 
 /**
- * Immutable hash map implementation for properties.  Properties are keyed on strings.
- * Copying and cloning is avoided by relying on immutability.
+ * Immutable hash map implementation for properties. Properties are keyed on strings
+ * or symbols (ES6). Copying and cloning is avoided by relying on immutability.
  * <p>
  * When adding an element to a hash table, only the head of a bin list is updated, thus
  * an add only requires the cloning of the bins array and adding an element to the head
  * of the bin list.  Similarly for removal, only a portion of a bin list is updated.
  * <p>
+ * For large tables with hundreds or thousands of elements, even just cloning the bins
+ * array when adding properties is an expensive operation. For this case, we put new
+ * elements in a separate list called {@link ElementQueue}.
+ * The list component is merged into the hash table at regular intervals during element
+ * insertion to keep it from growing too long. Also, when a map with a queue component
+ * is queried repeatedly, the map will replace itself with a pure hash table version
+ * of itself to optimize lookup performance.
+ * <p>
  * A separate chronological list is kept for quick generation of keys and values, and,
- * for rehashing.
+ * for rehashing. For very small maps where the overhead of the hash table would
+ * outweigh its benefits we deliberately avoid creating a hash structure and use the
+ * chronological list alone for element storage.
  * <p>
  * Details:
  * <p>
  * The main goal is to be able to retrieve properties from a map quickly, keying on
- * the property name (String.)  A secondary, but important goal, is to keep maps
- * immutable, so that a map can be shared by multiple objects in a context.
+ * the property name (String or Symbol). A secondary, but important goal, is to keep
+ * maps immutable, so that a map can be shared by multiple objects in a context.
  * Sharing maps allows objects to be categorized as having similar properties, a
  * fact that call site guards rely on.  In this discussion, immutability allows us
  * to significantly reduce the amount of duplication we have in our maps.
@@ -109,6 +120,9 @@
     /** Threshold before using bins. */
     private static final int LIST_THRESHOLD = 8;
 
+    /** Threshold before adding new elements to queue instead of directly adding to hash bins. */
+    private static final int QUEUE_THRESHOLD = Options.getIntProperty("nashorn.propmap.queue.threshold", 500);
+
     /** Initial map. */
     public static final PropertyHashMap EMPTY_HASHMAP = new PropertyHashMap();
 
@@ -122,7 +136,10 @@
     private final Element list;
 
     /** Hash map bins. */
-    private final Element[] bins;
+    private Element[] bins;
+
+    /** Queue for adding elements to large maps with delayed hashing. */
+    private ElementQueue queue;
 
     /** All properties as an array (lazy). */
     private Property[] properties;
@@ -134,33 +151,26 @@
         this.size      = 0;
         this.threshold = 0;
         this.bins      = null;
+        this.queue     = null;
         this.list      = null;
     }
 
     /**
-     * Clone Constructor
+     * Constructor used internally to create new maps
      *
-     * @param map Original {@link PropertyHashMap}.
+     * @param map the new map
      */
-    private PropertyHashMap(final PropertyHashMap map) {
+    private PropertyHashMap(final MapBuilder map) {
         this.size      = map.size;
-        this.threshold = map.threshold;
-        this.bins      = map.bins;
+        if (map.qhead == null) {
+            this.bins = map.bins;
+            this.queue = null;
+        } else {
+            this.bins = null;
+            this.queue = new ElementQueue(map.qhead, map.bins);
+        }
         this.list      = map.list;
-    }
-
-    /**
-     * Constructor used internally to extend a map
-     *
-     * @param size Size of the new {@link PropertyHashMap}.
-     * @param bins The hash bins.
-     * @param list The {@link Property} list.
-     */
-    private PropertyHashMap(final int size, final Element[] bins, final Element list) {
-        this.size      = size;
-        this.threshold = bins != null ? threeQuarters(bins.length) : 0;
-        this.bins      = bins;
-        this.list      = list;
+        this.threshold = map.bins != null ? threeQuarters(map.bins.length) : 0;
     }
 
     /**
@@ -173,7 +183,9 @@
     public PropertyHashMap immutableReplace(final Property property, final Property newProperty) {
         assert property.getKey().equals(newProperty.getKey()) : "replacing properties with different keys: '" + property.getKey() + "' != '" + newProperty.getKey() + "'";
         assert findElement(property.getKey()) != null         : "replacing property that doesn't exist in map: '" + property.getKey() + "'";
-        return cloneMap().replaceNoClone(property.getKey(), newProperty);
+        final MapBuilder builder = newMapBuilder(size);
+        builder.replaceProperty(property.getKey(), newProperty);
+        return new PropertyHashMap(builder);
     }
 
     /**
@@ -185,9 +197,9 @@
      */
     public PropertyHashMap immutableAdd(final Property property) {
         final int newSize = size + 1;
-        PropertyHashMap newMap = cloneMap(newSize);
-        newMap = newMap.addNoClone(property);
-        return newMap;
+        MapBuilder builder = newMapBuilder(newSize);
+        builder.addProperty(property);
+        return new PropertyHashMap(builder);
     }
 
     /**
@@ -199,11 +211,11 @@
      */
     public PropertyHashMap immutableAdd(final Property... newProperties) {
         final int newSize = size + newProperties.length;
-        PropertyHashMap newMap = cloneMap(newSize);
+        MapBuilder builder = newMapBuilder(newSize);
         for (final Property property : newProperties) {
-            newMap = newMap.addNoClone(property);
+            builder.addProperty(property);
         }
-        return newMap;
+        return new PropertyHashMap(builder);
     }
 
     /**
@@ -216,27 +228,16 @@
     public PropertyHashMap immutableAdd(final Collection<Property> newProperties) {
         if (newProperties != null) {
             final int newSize = size + newProperties.size();
-            PropertyHashMap newMap = cloneMap(newSize);
+            MapBuilder builder = newMapBuilder(newSize);
             for (final Property property : newProperties) {
-                newMap = newMap.addNoClone(property);
+                builder.addProperty(property);
             }
-            return newMap;
+            return new PropertyHashMap(builder);
         }
         return this;
     }
 
     /**
-     * Clone a {@link PropertyHashMap} and remove a {@link Property}.
-     *
-     * @param property {@link Property} to remove.
-     *
-     * @return New {@link PropertyHashMap}.
-     */
-    public PropertyHashMap immutableRemove(final Property property) {
-        return immutableRemove(property.getKey());
-    }
-
-    /**
      * Clone a {@link PropertyHashMap} and remove a {@link Property} based on its key.
      *
      * @param key Key of {@link Property} to remove.
@@ -244,22 +245,10 @@
      * @return New {@link PropertyHashMap}.
      */
     public PropertyHashMap immutableRemove(final Object key) {
-        if (bins != null) {
-            final int binIndex = binIndex(bins, key);
-            final Element bin = bins[binIndex];
-            if (findElement(bin, key) != null) {
-                final int newSize = size - 1;
-                Element[] newBins = null;
-                if (newSize >= LIST_THRESHOLD) {
-                    newBins = bins.clone();
-                    newBins[binIndex] = removeFromList(bin, key);
-                }
-                final Element newList = removeFromList(list, key);
-                return new PropertyHashMap(newSize, newBins, newList);
-            }
-        } else if (findElement(list, key) != null) {
-            final int newSize = size - 1;
-            return newSize != 0 ? new PropertyHashMap(newSize, null, removeFromList(list, key)) : EMPTY_HASHMAP;
+        MapBuilder builder = newMapBuilder(size);
+        builder.removeProperty(key);
+        if (builder.size < size) {
+            return builder.size != 0 ? new PropertyHashMap(builder) : EMPTY_HASHMAP;
         }
         return this;
     }
@@ -356,7 +345,9 @@
      * @return {@link Element} matching key or {@code null} if not found.
      */
     private Element findElement(final Object key) {
-        if (bins != null) {
+        if (queue != null) {
+            return queue.find(key);
+        } else if (bins != null) {
             final int binIndex = binIndex(bins, key);
             return findElement(bins[binIndex], key);
         }
@@ -380,73 +371,52 @@
         return null;
     }
 
-
-    private PropertyHashMap cloneMap() {
-        return new PropertyHashMap(size, bins == null ? null : bins.clone(), list);
-    }
-
     /**
-     * Clone {@link PropertyHashMap} to accommodate new size.
+     * Create a {@code MapBuilder} to add new elements to.
      *
      * @param newSize New size of {@link PropertyHashMap}.
      *
-     * @return Cloned {@link PropertyHashMap} with new size.
+     * @return {@link MapBuilder} for the new size.
      */
-    private PropertyHashMap cloneMap(final int newSize) {
-        Element[] newBins;
-        if (bins == null && newSize <= LIST_THRESHOLD) {
-            newBins = null;
+    private MapBuilder newMapBuilder(final int newSize) {
+        if (bins == null && newSize < LIST_THRESHOLD) {
+            return new MapBuilder(bins, list, size, false);
         } else if (newSize > threshold) {
-            newBins = rehash(list, binsNeeded(newSize));
+            return new MapBuilder(rehash(list, binsNeeded(newSize)), list, size, true);
+        } else if (shouldCloneBins(size, newSize)) {
+            return new MapBuilder(cloneBins(), list, size, true);
+        } else if (queue == null) {
+            return new MapBuilder(bins, list, size, false);
         } else {
-            newBins = bins.clone();
+            return new MapBuilder(queue, list, size, false);
         }
-        return new PropertyHashMap(newSize, newBins, list);
     }
 
-
-
     /**
-     * Add a {@link Property} to a temporary {@link PropertyHashMap}, that has
-     * been already cloned.  Removes duplicates if necessary.
+     * Create a cloned or new bins array and merge the elements in the queue into it if there are any.
      *
-     * @param property {@link Property} to add.
-     *
-     * @return New {@link PropertyHashMap}.
+     * @return the cloned bins array
      */
-    private PropertyHashMap addNoClone(final Property property) {
-        int newSize = size;
-        final Object key = property.getKey();
-        Element newList = list;
-        if (bins != null) {
-            final int binIndex = binIndex(bins, key);
-            Element bin = bins[binIndex];
-            if (findElement(bin, key) != null) {
-                newSize--;
-                bin = removeFromList(bin, key);
-                newList = removeFromList(list, key);
-            }
-            bins[binIndex] = new Element(bin, property);
-        } else {
-            if (findElement(list, key) != null) {
-                newSize--;
-                newList = removeFromList(list, key);
-            }
+    private Element[] cloneBins() {
+        if (queue != null) {
+            return queue.cloneAndMergeBins();
         }
-        newList = new Element(newList, property);
-        return new PropertyHashMap(newSize, bins, newList);
+
+        return bins.clone();
     }
 
-    private PropertyHashMap replaceNoClone(final Object key, final Property property) {
-        if (bins != null) {
-            final int binIndex = binIndex(bins, key);
-            Element bin = bins[binIndex];
-            bin = replaceInList(bin, key, property);
-            bins[binIndex] = bin;
-        }
-        Element newList = list;
-        newList = replaceInList(newList, key, property);
-        return new PropertyHashMap(size, bins, newList);
+    /**
+     * Used on insertion to determine whether the bins array should be cloned, or we should keep
+     * using the ancestor's bins array and put new elements into the queue.
+     *
+     * @param oldSize the old map size
+     * @param newSize the new map size
+     * @return whether to clone the bins array
+     */
+    private boolean shouldCloneBins(final int oldSize, final int newSize) {
+        // For maps with less than QUEUE_THRESHOLD elements we clone the bins array on every insertion.
+        // Above that threshold we put new elements into the queue and only merge every 512  elements.
+        return newSize < QUEUE_THRESHOLD || (newSize >>> 9) > (oldSize >>> 9);
     }
 
     /**
@@ -681,4 +651,210 @@
         }
     }
 
+    /**
+     * A hybrid map/list structure to add elements to the map without the need to clone and rehash the main table.
+     * This is used for large maps to reduce the overhead of adding elements. Instances of this class can replace
+     * themselves with a pure hash map version of themselves to optimize query performance.
+     */
+    private class ElementQueue {
+
+        /** List of elements not merged into bins */
+        private final Element qhead;
+
+        /** Our own bins array. Differs from original PropertyHashMap bins when queue is merged. */
+        private final Element[] qbins;
+
+        /** Count searches to trigger merging of queue into bins. */
+        int searchCount = 0;
+
+        ElementQueue(final Element qhead, final Element[] qbins) {
+            this.qhead = qhead;
+            this.qbins = qbins;
+        }
+
+        Element find(final Object key) {
+            final int binIndex = binIndex(qbins, key);
+            final Element element = findElement(qbins[binIndex], key);
+            if (element != null) {
+                return element;
+            }
+            if (qhead != null) {
+                if (++searchCount > 2) {
+                    // Merge the queue into the hash bins if this map is queried more than a few times
+                    final Element[] newBins = cloneAndMergeBins();
+                    assert newBins != qbins;
+                    PropertyHashMap.this.queue = new ElementQueue(null, newBins);
+                    return PropertyHashMap.this.queue.find(key);
+                }
+                return findElement(qhead, key);
+            }
+            return null;
+        }
+
+        /**
+         * Create a cloned or new bins array and merge the elements in the queue into it if there are any.
+         *
+         * @return the cloned bins array
+         */
+        private Element[] cloneAndMergeBins() {
+            if (qhead == null) {
+                return qbins;
+            }
+
+            final Element[] newBins = qbins.clone();
+
+            for (Element element = qhead; element != null; element = element.getLink()) {
+                final Property property = element.getProperty();
+                final Object key = property.getKey();
+                final int binIndex = binIndex(newBins, key);
+
+                newBins[binIndex] = new Element(newBins[binIndex], property);
+            }
+
+            return newBins;
+        }
+
+    }
+
+    /**
+     * A builder class used for adding, replacing, or removing elements.
+     */
+    private static class MapBuilder {
+
+        /** Bins array - may be shared with map that created us. */
+        private Element[] bins;
+        /** Whether our bins are shared */
+        private boolean hasOwnBins;
+
+        /** Queue of unmerged elements */
+        private Element qhead;
+
+        /** Full property list. */
+        private Element list;
+
+        /** Number of properties. */
+        private int size;
+
+        MapBuilder(final Element[] bins, final Element list, final int size, final boolean hasOwnBins) {
+            this.bins  = bins;
+            this.hasOwnBins = hasOwnBins;
+            this.list  = list;
+            this.qhead = null;
+            this.size  = size;
+        }
+
+        MapBuilder(final ElementQueue queue, final Element list, final int size, final boolean hasOwnBins) {
+            this.bins  = queue.qbins;
+            this.hasOwnBins = hasOwnBins;
+            this.list  = list;
+            this.qhead = queue.qhead;
+            this.size  = size;
+        }
+
+        /**
+         * Add a {@link Property}. Removes duplicates if necessary.
+         *
+         * @param property {@link Property} to add.
+         */
+        private void addProperty(final Property property) {
+            final Object key = property.getKey();
+
+            if (bins != null) {
+                final int binIndex = binIndex(bins, key);
+                if (findElement(bins[binIndex], key) != null) {
+                    ensureOwnBins();
+                    bins[binIndex] = removeExistingElement(bins[binIndex], key);
+                } else if (findElement(qhead, key) != null) {
+                    qhead = removeExistingElement(qhead, key);
+                }
+                if (hasOwnBins) {
+                    bins[binIndex] = new Element(bins[binIndex], property);
+                } else {
+                    qhead = new Element(qhead, property);
+                }
+            } else {
+                if (findElement(list, key) != null) {
+                    list = removeFromList(list, key);
+                    size--;
+                }
+            }
+
+            list = new Element(list, property);
+            size++;
+        }
+
+        /**
+         * Replace an existing {@link Property} with a new one with the same key.
+         *
+         * @param key the property key
+         * @param property the property to replace the old one with
+         */
+        private void replaceProperty(final Object key, final Property property) {
+
+            if (bins != null) {
+                final int binIndex = binIndex(bins, key);
+                Element bin = bins[binIndex];
+                if (findElement(bin, key) != null) {
+                    ensureOwnBins();
+                    bins[binIndex] = replaceInList(bin, key, property);
+                } else if (qhead != null) {
+                    qhead = replaceInList(qhead, key, property);
+                }
+            }
+
+            list = replaceInList(list, key, property);
+        }
+
+        /**
+         * Remove a {@link Property} based on its key.
+         *
+         * @param key Key of {@link Property} to remove.
+         */
+        void removeProperty(final Object key) {
+
+            if (bins != null) {
+                final int binIndex = binIndex(bins, key);
+                final Element bin = bins[binIndex];
+                if (findElement(bin, key) != null) { ;
+                    if (size >= LIST_THRESHOLD) {
+                        ensureOwnBins();
+                        bins[binIndex] = removeFromList(bin, key);
+                    } else {
+                        // Go back to list-only representation for small maps
+                        bins = null;
+                        qhead = null;
+                    }
+                } else if (findElement(qhead, key) != null) {
+                    qhead = removeFromList(qhead, key);
+                }
+            }
+
+            list = removeFromList(list, key);
+            size--;
+        }
+
+        /**
+         * Removes an element known to exist from an element list and the main {@code list} and decreases {@code size}.
+         *
+         * @param element the element list
+         * @param key the key to remove
+         * @return the new element list
+         */
+        private Element removeExistingElement(Element element, Object key) {
+            size--;
+            list = removeFromList(list, key);
+            return removeFromList(element, key);
+        }
+
+        /**
+         * Make sure we own the bins we have, cloning them if necessary.
+         */
+        private void ensureOwnBins() {
+            if (!hasOwnBins) {
+                bins = bins.clone();
+            }
+            hasOwnBins = true;
+        }
+    }
+
 }
--- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/resources/Messages.properties	Mon Oct 16 08:47:59 2017 -0700
+++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/resources/Messages.properties	Tue Oct 17 14:33:32 2017 -0700
@@ -62,6 +62,7 @@
 parser.error.trailing.comma.in.json=Trailing comma is not allowed in JSON
 parser.error.missing.const.assignment=Missing assignment to constant "{0}"
 parser.error.unterminated.template.expression=Expected } after expression in template literal
+parser.error.keyword.escaped.character=Keyword must not contain escaped characters
 
 # ES6 mode error messages
 parser.error.multiple.constructors=Class contains more than one constructor
--- a/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipUtils.java	Mon Oct 16 08:47:59 2017 -0700
+++ b/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipUtils.java	Tue Oct 17 14:33:32 2017 -0700
@@ -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	Mon Oct 16 08:47:59 2017 -0700
+++ b/test/TestCommon.gmk	Tue Oct 17 14:33:32 2017 -0700
@@ -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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/nio/channels/FileChannel/CleanerTest.java	Tue Oct 17 14:33:32 2017 -0700
@@ -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);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/util/ServiceLoader/CachingTest.java	Tue Oct 17 14:33:32 2017 -0700
@@ -0,0 +1,187 @@
+/*
+ * 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
+ * @summary Test ServiceLoader caches
+ * @run testng CachingTest
+ */
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ServiceLoader;
+import java.util.ServiceLoader.Provider;
+import java.util.Spliterator;
+import java.util.stream.Collectors;
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+import static org.testng.Assert.*;
+
+public class CachingTest {
+
+    // service type
+    public static interface S { }
+
+    // service provider implementations
+    public static class S1 implements S { }
+
+    public static class S2 implements S { }
+
+    private ClassLoader testClassLoader;
+
+    // creates the services configuration file and sets the ClassLoader
+    @BeforeClass
+    void setup() throws Exception {
+        String classes = System.getProperty("test.classes");
+        Path dir = Paths.get(classes, "META-INF", "services");
+        Files.createDirectories(dir);
+        Path config = dir.resolve(S.class.getName());
+        Files.write(config, List.of(S1.class.getName(), S2.class.getName()));
+        this.testClassLoader = CachingTest.class.getClassLoader();
+    }
+
+    private void checkLists(List<?> list1, List<?> list2) {
+        assertTrue(list1.size() == 2);
+        assertTrue(list2.size() == 2);
+        Iterator<?> iterator1 = list1.iterator();
+        Iterator<?> iterator2 = list2.iterator();
+        while (iterator1.hasNext()) {
+            assertTrue(iterator1.next() == iterator2.next());
+        }
+    }
+
+    @Test
+    public void testIterator1() {
+        ServiceLoader<S> sl = ServiceLoader.load(S.class, testClassLoader);
+
+        List<S> list1 = new ArrayList<>();
+        List<S> list2 = new ArrayList<>();
+
+        // 1-1-2-2
+        sl.forEach(list1::add);
+        sl.forEach(list2::add);
+
+        checkLists(list1, list2);
+    }
+
+    // interleaved
+    @Test
+    public void testIterator2() {
+        ServiceLoader<S> sl = ServiceLoader.load(S.class, testClassLoader);
+
+        List<S> list1 = new ArrayList<>();
+        List<S> list2 = new ArrayList<>();
+
+        Iterator<S> iterator1 = sl.iterator();
+        Iterator<S> iterator2 = sl.iterator();
+
+        // 1-2-1-2
+        list1.add(iterator1.next());
+        list2.add(iterator2.next());
+        list1.add(iterator1.next());
+        list2.add(iterator2.next());
+
+        checkLists(list1, list2);
+    }
+
+    // interleaved
+    @Test
+    public void testIterator3() {
+        ServiceLoader<S> sl = ServiceLoader.load(S.class, testClassLoader);
+
+        List<S> list1 = new ArrayList<>();
+        List<S> list2 = new ArrayList<>();
+
+        Iterator<S> iterator1 = sl.iterator();
+        Iterator<S> iterator2 = sl.iterator();
+
+        // 1-2-2-1
+        list1.add(iterator1.next());
+        list2.add(iterator2.next());
+        list2.add(iterator2.next());
+        list1.add(iterator1.next());
+
+        checkLists(list1, list2);
+    }
+
+    @Test
+    public void testStream1() {
+        ServiceLoader<S> sl = ServiceLoader.load(S.class, testClassLoader);
+
+        // 1-1-2-2
+        List<Provider<S>> list1 = sl.stream().collect(Collectors.toList());
+        List<Provider<S>> list2 = sl.stream().collect(Collectors.toList());
+        checkLists(list1, list2);
+    }
+
+    // interleaved
+    @Test
+    public void testStream2() {
+        ServiceLoader<S> sl = ServiceLoader.load(S.class, testClassLoader);
+
+        List<Provider<S>> list1 = new ArrayList<>();
+        List<Provider<S>> list2 = new ArrayList<>();
+
+        Spliterator<Provider<S>> spliterator1 = sl.stream().spliterator();
+        Spliterator<Provider<S>> spliterator2 = sl.stream().spliterator();
+
+        // 1-2-1-2
+        spliterator1.tryAdvance(list1::add);
+        spliterator2.tryAdvance(list2::add);
+        spliterator1.tryAdvance(list1::add);
+        spliterator2.tryAdvance(list2::add);
+
+        assertFalse(spliterator1.tryAdvance(e -> assertTrue(false)));
+        assertFalse(spliterator2.tryAdvance(e -> assertTrue(false)));
+
+        checkLists(list1, list2);
+    }
+
+    // interleaved
+    @Test
+    public void testStream3() {
+        ServiceLoader<S> sl = ServiceLoader.load(S.class, testClassLoader);
+
+        List<Provider<S>> list1 = new ArrayList<>();
+        List<Provider<S>> list2 = new ArrayList<>();
+
+        Spliterator<Provider<S>> spliterator1 = sl.stream().spliterator();
+        Spliterator<Provider<S>> spliterator2 = sl.stream().spliterator();
+
+        // 1-2-2-1
+        spliterator1.tryAdvance(list1::add);
+        spliterator2.tryAdvance(list2::add);
+        spliterator2.tryAdvance(list2::add);
+        spliterator1.tryAdvance(list1::add);
+
+        assertFalse(spliterator1.tryAdvance(e -> assertTrue(false)));
+        assertFalse(spliterator2.tryAdvance(e -> assertTrue(false)));
+
+        checkLists(list1, list2);
+    }
+}
--- a/test/jdk/java/util/ServiceLoader/security/test/module-info.java	Mon Oct 16 08:47:59 2017 -0700
+++ b/test/jdk/java/util/ServiceLoader/security/test/module-info.java	Tue Oct 17 14:33:32 2017 -0700
@@ -26,8 +26,16 @@
 module test {
     uses S1;
     uses S2;
+    uses S3;
+    uses S4;
+    uses S5;
+    uses S6;
     provides S1 with P1;
     provides S2 with P2;
+    provides S3 with P3;
+    provides S4 with P4;
+    provides S5 with P5;
+    provides S6 with P6;
     requires testng;
     exports p to testng;
 }
--- a/test/jdk/java/util/ServiceLoader/security/test/p/Tests.java	Mon Oct 16 08:47:59 2017 -0700
+++ b/test/jdk/java/util/ServiceLoader/security/test/p/Tests.java	Tue Oct 17 14:33:32 2017 -0700
@@ -38,14 +38,16 @@
 import java.util.ServiceLoader.Provider;
 import static java.security.AccessController.doPrivileged;
 
+import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
 import org.testng.annotations.BeforeTest;
 import static org.testng.Assert.*;
 
 /**
- * Basic tests with a security manager to ensure that the provider code
- * is run with permissions restricted by whatever created the ServiceLoader
- * object.
+ * Tests ServiceLoader when running with a security manager, specifically
+ * tests to ensure that provider code is run with permissions restricted by
+ * the creater of ServiceLoader, and also testing of exceptions thrown
+ * when loading or initializing a provider.
  */
 
 public class Tests {
@@ -163,11 +165,35 @@
         }
     }
 
+    @DataProvider(name = "failingServices")
+    public Object[][] failingServices() {
+        return new Object[][] {
+            { S3.class,    P3.Error3.class },
+            { S4.class,    P4.Error4.class },
+            { S5.class,    P5.Error5.class },
+            { S6.class,    P6.Error6.class },
+        };
+    }
+
+    @Test(dataProvider = "failingServices")
+    public void testFailingService(Class<?> service, Class<? extends Error> errorClass) {
+        ServiceLoader<?> sl = ServiceLoader.load(service);
+        try {
+            sl.iterator().next();
+            assertTrue(false);
+        } catch (ServiceConfigurationError e) {
+            assertTrue(e.getCause().getClass() == errorClass);
+        }
+    }
 
     // service types and implementations
 
     public static interface S1 { }
     public static interface S2 { }
+    public static interface S3 { }
+    public static interface S4 { }
+    public static interface S5 { }
+    public static interface S6 { }
 
     public static class P1 implements S1 {
         public P1() {
@@ -182,4 +208,36 @@
             return new P2();
         }
     }
+
+    public static class P3 implements S3 {
+        static class Error3 extends Error { }
+        static {
+            if (1==1) throw new Error3();  // fail
+        }
+        public P3() { }
+    }
+
+    public static class P4 implements S4 {
+        static class Error4 extends Error { }
+        static {
+            if (1==1) throw new Error4();  // fail
+        }
+        public static S4 provider() {
+            return new P4();
+        }
+    }
+
+    public static class P5 implements S5 {
+        static class Error5 extends Error { }
+        public P5() {
+            throw new Error5();  // fail
+        }
+    }
+
+    public static class P6 implements S6 {
+        static class Error6 extends Error { }
+        public static S6 provider() {
+            throw new Error6();   // fail
+        }
+    }
 }
--- a/test/jdk/java/util/concurrent/ConcurrentQueues/GCRetention.java	Mon Oct 16 08:47:59 2017 -0700
+++ b/test/jdk/java/util/concurrent/ConcurrentQueues/GCRetention.java	Tue Oct 17 14:33:32 2017 -0700
@@ -35,7 +35,7 @@
  * @bug 6785442
  * @summary Benchmark that tries to GC-tenure head, followed by
  * many add/remove operations.
- * @run main GCRetention 12345
+ * @run main GCRetention just-testing
  */
 
 import static java.util.concurrent.TimeUnit.SECONDS;
@@ -60,8 +60,8 @@
 import java.util.Map;
 
 public class GCRetention {
-    // Suitable for benchmarking.  Overridden by args[0] for testing.
-    int count = 1024 * 1024;
+    boolean benchmarkMode;
+    int count;
 
     /** No guarantees, but effective in practice. */
     static void forceFullGc() {
@@ -124,8 +124,9 @@
     }
 
     void test(String[] args) {
-        if (args.length > 0)
-            count = Integer.valueOf(args[0]);
+        benchmarkMode = ! (args.length > 0 && args[0].equals("just-testing"));
+        count = benchmarkMode ? 1024 * 1024 : 30;
+
         // Warmup
         for (Queue<Boolean> queue : queues())
             test(queue);
@@ -140,7 +141,7 @@
         long t0 = System.nanoTime();
         for (int i = 0; i < count; i++)
             check(q.add(Boolean.TRUE));
-        forceFullGc();
+        if (benchmarkMode) forceFullGc();
         // forceFullGc();
         Boolean x;
         while ((x = q.poll()) != null)
--- a/test/jdk/java/util/concurrent/ExecutorService/Invoke.java	Mon Oct 16 08:47:59 2017 -0700
+++ b/test/jdk/java/util/concurrent/ExecutorService/Invoke.java	Tue Oct 17 14:33:32 2017 -0700
@@ -28,12 +28,18 @@
  * @author  Martin Buchholz
  */
 
-import java.util.Arrays;
+import static java.util.concurrent.TimeUnit.NANOSECONDS;
+import static java.util.concurrent.TimeUnit.SECONDS;
+
 import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
 import java.util.concurrent.Callable;
+import java.util.concurrent.CyclicBarrier;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
+import java.util.concurrent.ThreadLocalRandom;
 import java.util.concurrent.atomic.AtomicLong;
 
 public class Invoke {
@@ -61,36 +67,162 @@
         check(condition, "Assertion failure");
     }
 
+    static long secondsElapsedSince(long startTime) {
+        return NANOSECONDS.toSeconds(System.nanoTime() - startTime);
+    }
+
+    static void awaitInterrupt(long timeoutSeconds) {
+        long startTime = System.nanoTime();
+        try {
+            Thread.sleep(SECONDS.toMillis(timeoutSeconds));
+            fail("timed out waiting for interrupt");
+        } catch (InterruptedException expected) {
+            check(secondsElapsedSince(startTime) < timeoutSeconds);
+        }
+    }
+
     public static void main(String[] args) {
         try {
-            final AtomicLong count = new AtomicLong(0);
-            ExecutorService fixed = Executors.newFixedThreadPool(5);
-            class Inc implements Callable<Long> {
-                public Long call() throws Exception {
-                    Thread.sleep(200); // Catch IE from possible cancel
-                    return count.incrementAndGet();
-                }
+            testInvokeAll();
+            testInvokeAny();
+            testInvokeAny_cancellationInterrupt();
+        } catch (Throwable t) {  unexpected(t); }
+
+        if (failed > 0)
+            throw new Error(
+                    String.format("Passed = %d, failed = %d", passed, failed));
+    }
+
+    static final long timeoutSeconds = 10L;
+
+    static void testInvokeAll() throws Throwable {
+        final ThreadLocalRandom rnd = ThreadLocalRandom.current();
+        final int nThreads = rnd.nextInt(2, 7);
+        final boolean timed = rnd.nextBoolean();
+        final ExecutorService pool = Executors.newFixedThreadPool(nThreads);
+        final AtomicLong count = new AtomicLong(0);
+        class Task implements Callable<Long> {
+            public Long call() throws Exception {
+                return count.incrementAndGet();
             }
-            List<Inc> tasks = Arrays.asList(new Inc(), new Inc(), new Inc());
-            List<Future<Long>> futures = fixed.invokeAll(tasks);
+        }
+
+        try {
+            final List<Task> tasks =
+                IntStream.range(0, nThreads)
+                .mapToObj(i -> new Task())
+                .collect(Collectors.toList());
+
+            List<Future<Long>> futures;
+            if (timed) {
+                long startTime = System.nanoTime();
+                futures = pool.invokeAll(tasks, timeoutSeconds, SECONDS);
+                check(secondsElapsedSince(startTime) < timeoutSeconds);
+            }
+            else
+                futures = pool.invokeAll(tasks);
             check(futures.size() == tasks.size());
             check(count.get() == tasks.size());
 
             long gauss = 0;
             for (Future<Long> future : futures) gauss += future.get();
-            check(gauss == ((tasks.size()+1)*tasks.size())/2);
+            check(gauss == (tasks.size()+1)*tasks.size()/2);
+
+            pool.shutdown();
+            check(pool.awaitTermination(10L, SECONDS));
+        } finally {
+            pool.shutdownNow();
+        }
+    }
 
-            ExecutorService single = Executors.newSingleThreadExecutor();
-            long save = count.get();
-            check(single.invokeAny(tasks) == save + 1);
-            check(count.get() == save + 1);
+    static void testInvokeAny() throws Throwable {
+        final ThreadLocalRandom rnd = ThreadLocalRandom.current();
+        final boolean timed = rnd.nextBoolean();
+        final ExecutorService pool = Executors.newSingleThreadExecutor();
+        final AtomicLong count = new AtomicLong(0);
+        class Task implements Callable<Long> {
+            public Long call() throws Exception {
+                long x = count.incrementAndGet();
+                check(x <= 2);
+                if (x == 2)
+                    // wait for main thread to interrupt us
+                    awaitInterrupt(timeoutSeconds);
+                return x;
+            }
+        }
+
+        try {
+            final List<Task> tasks =
+                IntStream.range(0, rnd.nextInt(1, 7))
+                .mapToObj(i -> new Task())
+                .collect(Collectors.toList());
+
+            long val;
+            if (timed) {
+                long startTime = System.nanoTime();
+                val = pool.invokeAny(tasks, timeoutSeconds, SECONDS);
+                check(secondsElapsedSince(startTime) < timeoutSeconds);
+            }
+            else
+                val = pool.invokeAny(tasks);
+            check(val == 1);
+
+            // inherent race between main thread interrupt and
+            // start of second task
+            check(count.get() == 1 || count.get() == 2);
 
-            fixed.shutdown();
-            single.shutdown();
+            pool.shutdown();
+            check(pool.awaitTermination(timeoutSeconds, SECONDS));
+        } finally {
+            pool.shutdownNow();
+        }
+    }
 
-        } catch (Throwable t) { unexpected(t); }
+    /**
+     * Every remaining running task is sent an interrupt for cancellation.
+     */
+    static void testInvokeAny_cancellationInterrupt() throws Throwable {
+        final ThreadLocalRandom rnd = ThreadLocalRandom.current();
+        final int nThreads = rnd.nextInt(2, 7);
+        final boolean timed = rnd.nextBoolean();
+        final ExecutorService pool = Executors.newFixedThreadPool(nThreads);
+        final AtomicLong count = new AtomicLong(0);
+        final AtomicLong interruptedCount = new AtomicLong(0);
+        final CyclicBarrier allStarted = new CyclicBarrier(nThreads);
+        class Task implements Callable<Long> {
+            public Long call() throws Exception {
+                allStarted.await();
+                long x = count.incrementAndGet();
+                if (x > 1)
+                    // main thread will interrupt us
+                    awaitInterrupt(timeoutSeconds);
+                return x;
+            }
+        }
 
-        System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
-        if (failed > 0) throw new Error("Some tests failed");
+        try {
+            final List<Task> tasks =
+                IntStream.range(0, nThreads)
+                .mapToObj(i -> new Task())
+                .collect(Collectors.toList());
+
+            long val;
+            if (timed) {
+                long startTime = System.nanoTime();
+                val = pool.invokeAny(tasks, timeoutSeconds, SECONDS);
+                check(secondsElapsedSince(startTime) < timeoutSeconds);
+            }
+            else
+                val = pool.invokeAny(tasks);
+            check(val == 1);
+
+            pool.shutdown();
+            check(pool.awaitTermination(timeoutSeconds, SECONDS));
+
+            // Check after shutdown to avoid race
+            check(count.get() == nThreads);
+        } finally {
+            pool.shutdownNow();
+        }
     }
 }
--- a/test/jdk/java/util/concurrent/tck/ConcurrentLinkedDequeTest.java	Mon Oct 16 08:47:59 2017 -0700
+++ b/test/jdk/java/util/concurrent/tck/ConcurrentLinkedDequeTest.java	Tue Oct 17 14:33:32 2017 -0700
@@ -40,7 +40,10 @@
 import java.util.NoSuchElementException;
 import java.util.Queue;
 import java.util.Random;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ConcurrentLinkedDeque;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.atomic.LongAdder;
 
 import junit.framework.Test;
 
@@ -932,4 +935,78 @@
             } catch (NullPointerException success) {}
         }
     }
+
+    /**
+     * Non-traversing Deque operations are linearizable.
+     * https://bugs.openjdk.java.net/browse/JDK-8188900
+     * ant -Djsr166.expensiveTests=true -Djsr166.tckTestClass=ConcurrentLinkedDequeTest -Djsr166.methodFilter=testBug8188900 tck
+     */
+    public void testBug8188900() {
+        final ThreadLocalRandom rnd = ThreadLocalRandom.current();
+        final LongAdder nulls = new LongAdder(), zeros = new LongAdder();
+        for (int n = expensiveTests ? 100_000 : 10; n--> 0; ) {
+            ConcurrentLinkedDeque<Integer> d = new ConcurrentLinkedDeque<>();
+
+            boolean peek = rnd.nextBoolean();
+            Runnable getter = () -> {
+                Integer x = peek ? d.peekFirst() : d.pollFirst();
+                if (x == null) nulls.increment();
+                else if (x == 0) zeros.increment();
+                else
+                    throw new AssertionError(
+                        String.format(
+                            "unexpected value %d after %d nulls and %d zeros",
+                            x, nulls.sum(), zeros.sum()));
+            };
+
+            Runnable adder = () -> {
+                d.addFirst(0);
+                d.addLast(42);
+            };
+
+            boolean b = rnd.nextBoolean();
+            Runnable r1 = b ? getter : adder;
+            Runnable r2 = b ? adder : getter;
+            CompletableFuture<Void> f1 = CompletableFuture.runAsync(r1);
+            CompletableFuture<Void> f2 = CompletableFuture.runAsync(r2);
+            f1.join();
+            f2.join();
+        }
+    }
+
+    /**
+     * Reverse direction variant of testBug8188900
+     */
+    public void testBug8188900_reverse() {
+        final ThreadLocalRandom rnd = ThreadLocalRandom.current();
+        final LongAdder nulls = new LongAdder(), zeros = new LongAdder();
+        for (int n = expensiveTests ? 100_000 : 10; n--> 0; ) {
+            ConcurrentLinkedDeque<Integer> d = new ConcurrentLinkedDeque<>();
+
+            boolean peek = rnd.nextBoolean();
+            Runnable getter = () -> {
+                Integer x = peek ? d.peekLast() : d.pollLast();
+                if (x == null) nulls.increment();
+                else if (x == 0) zeros.increment();
+                else
+                    throw new AssertionError(
+                        String.format(
+                            "unexpected value %d after %d nulls and %d zeros",
+                            x, nulls.sum(), zeros.sum()));
+            };
+
+            Runnable adder = () -> {
+                d.addLast(0);
+                d.addFirst(42);
+            };
+
+            boolean b = rnd.nextBoolean();
+            Runnable r1 = b ? getter : adder;
+            Runnable r2 = b ? adder : getter;
+            CompletableFuture<Void> f1 = CompletableFuture.runAsync(r1);
+            CompletableFuture<Void> f2 = CompletableFuture.runAsync(r2);
+            f1.join();
+            f2.join();
+        }
+    }
 }
--- a/test/jdk/java/util/concurrent/tck/SplittableRandomTest.java	Mon Oct 16 08:47:59 2017 -0700
+++ b/test/jdk/java/util/concurrent/tck/SplittableRandomTest.java	Tue Oct 17 14:33:32 2017 -0700
@@ -31,9 +31,14 @@
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
+import java.util.Arrays;
+import java.util.List;
 import java.util.SplittableRandom;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.LongAdder;
+import java.lang.reflect.Method;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
 
 import junit.framework.Test;
 import junit.framework.TestSuite;
@@ -552,4 +557,64 @@
         assertEquals(size, counter.sum());
     }
 
+    /**
+     * SplittableRandom should implement most of Random's public methods
+     */
+    public void testShouldImplementMostRandomMethods() throws Throwable {
+        Predicate<Method> wasForgotten = method -> {
+            String name = method.getName();
+            // some methods deliberately not implemented
+            if (name.equals("setSeed")) return false;
+            if (name.equals("nextFloat")) return false;
+            if (name.equals("nextGaussian")) return false;
+            try {
+                SplittableRandom.class.getMethod(
+                    method.getName(), method.getParameterTypes());
+            } catch (ReflectiveOperationException ex) {
+                return true;
+            }
+            return false;
+        };
+        List<Method> forgotten =
+            Arrays.stream(java.util.Random.class.getMethods())
+            .filter(wasForgotten)
+            .collect(Collectors.toList());
+        if (!forgotten.isEmpty())
+            throw new AssertionError("Please implement: " + forgotten);
+    }
+
+    /**
+     * Repeated calls to nextBytes produce at least values of different signs for every byte
+     */
+    public void testNextBytes() {
+        SplittableRandom sr = new SplittableRandom();
+        int n = sr.nextInt(1, 20);
+        byte[] bytes = new byte[n];
+        outer:
+        for (int i = 0; i < n; i++) {
+            for (int tries = NCALLS; tries-->0; ) {
+                byte before = bytes[i];
+                sr.nextBytes(bytes);
+                byte after = bytes[i];
+                if (after * before < 0)
+                    continue outer;
+            }
+            fail("not enough variation in random bytes");
+        }
+    }
+
+    /**
+     * Filling an empty array with random bytes succeeds without effect.
+     */
+    public void testNextBytes_emptyArray() {
+        new SplittableRandom().nextBytes(new byte[0]);
+    }
+
+    public void testNextBytes_nullArray() {
+        try {
+            new SplittableRandom().nextBytes(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
 }
--- a/test/jdk/java/util/concurrent/tck/StampedLockTest.java	Mon Oct 16 08:47:59 2017 -0700
+++ b/test/jdk/java/util/concurrent/tck/StampedLockTest.java	Tue Oct 17 14:33:32 2017 -0700
@@ -35,6 +35,11 @@
 import static java.util.concurrent.TimeUnit.DAYS;
 import static java.util.concurrent.TimeUnit.MILLISECONDS;
 
+import static java.util.concurrent.locks.StampedLock.isLockStamp;
+import static java.util.concurrent.locks.StampedLock.isOptimisticReadStamp;
+import static java.util.concurrent.locks.StampedLock.isReadLockStamp;
+import static java.util.concurrent.locks.StampedLock.isWriteLockStamp;
+
 import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.CountDownLatch;
@@ -1286,11 +1291,115 @@
                 } while (stamp == 0);
                 return Math.hypot(currentX, currentY);
             }
+
+            double distanceFromOrigin2() {
+                long stamp = sl.tryOptimisticRead();
+                try {
+                    retryHoldingLock:
+                    for (;; stamp = sl.readLock()) {
+                        if (stamp == 0L)
+                            continue retryHoldingLock;
+                        // possibly racy reads
+                        double currentX = x;
+                        double currentY = y;
+                        if (!sl.validate(stamp))
+                            continue retryHoldingLock;
+                        return Math.hypot(currentX, currentY);
+                    }
+                } finally {
+                    if (StampedLock.isReadLockStamp(stamp))
+                        sl.unlockRead(stamp);
+                }
+            }
+
+            void moveIfAtOrigin(double newX, double newY) {
+                long stamp = sl.readLock();
+                try {
+                    while (x == 0.0 && y == 0.0) {
+                        long ws = sl.tryConvertToWriteLock(stamp);
+                        if (ws != 0L) {
+                            stamp = ws;
+                            x = newX;
+                            y = newY;
+                            return;
+                        }
+                        else {
+                            sl.unlockRead(stamp);
+                            stamp = sl.writeLock();
+                        }
+                    }
+                } finally {
+                    sl.unlock(stamp);
+                }
+            }
         }
 
         Point p = new Point();
         p.move(3.0, 4.0);
         assertEquals(5.0, p.distanceFromOrigin());
+        p.moveIfAtOrigin(5.0, 12.0);
+        assertEquals(5.0, p.distanceFromOrigin2());
+    }
+
+    /**
+     * Stamp inspection methods work as expected, and do not inspect
+     * the state of the lock itself.
+     */
+    public void testStampStateInspectionMethods() {
+        StampedLock lock = new StampedLock();
+
+        assertFalse(isWriteLockStamp(0L));
+        assertFalse(isReadLockStamp(0L));
+        assertFalse(isLockStamp(0L));
+        assertFalse(isOptimisticReadStamp(0L));
+
+        {
+            long stamp = lock.writeLock();
+            for (int i = 0; i < 2; i++) {
+                assertTrue(isWriteLockStamp(stamp));
+                assertFalse(isReadLockStamp(stamp));
+                assertTrue(isLockStamp(stamp));
+                assertFalse(isOptimisticReadStamp(stamp));
+                if (i == 0)
+                    lock.unlockWrite(stamp);
+            }
+        }
+
+        {
+            long stamp = lock.readLock();
+            for (int i = 0; i < 2; i++) {
+                assertFalse(isWriteLockStamp(stamp));
+                assertTrue(isReadLockStamp(stamp));
+                assertTrue(isLockStamp(stamp));
+                assertFalse(isOptimisticReadStamp(stamp));
+                if (i == 0)
+                    lock.unlockRead(stamp);
+            }
+        }
+
+        {
+            long optimisticStamp = lock.tryOptimisticRead();
+            long readStamp = lock.tryConvertToReadLock(optimisticStamp);
+            long writeStamp = lock.tryConvertToWriteLock(readStamp);
+            for (int i = 0; i < 2; i++) {
+                assertFalse(isWriteLockStamp(optimisticStamp));
+                assertFalse(isReadLockStamp(optimisticStamp));
+                assertFalse(isLockStamp(optimisticStamp));
+                assertTrue(isOptimisticReadStamp(optimisticStamp));
+
+                assertFalse(isWriteLockStamp(readStamp));
+                assertTrue(isReadLockStamp(readStamp));
+                assertTrue(isLockStamp(readStamp));
+                assertFalse(isOptimisticReadStamp(readStamp));
+
+                assertTrue(isWriteLockStamp(writeStamp));
+                assertFalse(isReadLockStamp(writeStamp));
+                assertTrue(isLockStamp(writeStamp));
+                assertFalse(isOptimisticReadStamp(writeStamp));
+                if (i == 0)
+                    lock.unlockWrite(writeStamp);
+            }
+        }
     }
 
 }
--- a/test/jdk/java/util/concurrent/tck/ThreadLocalRandomTest.java	Mon Oct 16 08:47:59 2017 -0700
+++ b/test/jdk/java/util/concurrent/tck/ThreadLocalRandomTest.java	Tue Oct 17 14:33:32 2017 -0700
@@ -412,4 +412,38 @@
         fail("all threads generate the same pseudo-random sequence");
     }
 
+    /**
+     * Repeated calls to nextBytes produce at least values of different signs for every byte
+     */
+    public void testNextBytes() {
+        ThreadLocalRandom rnd = ThreadLocalRandom.current();
+        int n = rnd.nextInt(1, 20);
+        byte[] bytes = new byte[n];
+        outer:
+        for (int i = 0; i < n; i++) {
+            for (int tries = NCALLS; tries-->0; ) {
+                byte before = bytes[i];
+                rnd.nextBytes(bytes);
+                byte after = bytes[i];
+                if (after * before < 0)
+                    continue outer;
+            }
+            fail("not enough variation in random bytes");
+        }
+    }
+
+    /**
+     * Filling an empty array with random bytes succeeds without effect.
+     */
+    public void testNextBytes_emptyArray() {
+        ThreadLocalRandom.current().nextBytes(new byte[0]);
+    }
+
+    public void testNextBytes_nullArray() {
+        try {
+            ThreadLocalRandom.current().nextBytes(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
 }
--- a/test/jdk/java/util/zip/ZipFile/ZeroDate.java	Mon Oct 16 08:47:59 2017 -0700
+++ b/test/jdk/java/util/zip/ZipFile/ZeroDate.java	Tue Oct 17 14:33:32 2017 -0700
@@ -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	Mon Oct 16 08:47:59 2017 -0700
+++ b/test/jdk/jdk/nio/zipfs/ZeroDate.java	Tue Oct 17 14:33:32 2017 -0700
@@ -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	Mon Oct 16 08:47:59 2017 -0700
+++ b/test/langtools/jdk/javadoc/doclet/lib/JavadocTester.java	Tue Oct 17 14:33:32 2017 -0700
@@ -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	Mon Oct 16 08:47:59 2017 -0700
+++ b/test/langtools/jdk/javadoc/doclet/testAnchorNames/TestAnchorNames.java	Tue Oct 17 14:33:32 2017 -0700
@@ -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	Mon Oct 16 08:47:59 2017 -0700
+++ b/test/langtools/jdk/javadoc/doclet/testDocEncoding/TestDocEncoding.java	Tue Oct 17 14:33:32 2017 -0700
@@ -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	Mon Oct 16 08:47:59 2017 -0700
+++ b/test/langtools/jdk/javadoc/doclet/testSearch/TestSearch.java	Tue Oct 17 14:33:32 2017 -0700
@@ -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/tools/javac/T7093325.java	Mon Oct 16 08:47:59 2017 -0700
+++ b/test/langtools/tools/javac/T7093325.java	Tue Oct 17 14:33:32 2017 -0700
@@ -130,9 +130,9 @@
 
     @Override
     public void doWork() throws IOException {
-        verifyBytecode(newCompilationTask()
+        newCompilationTask()
                 .withSourceFromTemplate(source_template)
-                .generate());
+                .generate(this::verifyBytecode);
     }
 
     void verifyBytecode(Result<Iterable<? extends JavaFileObject>> result) {
--- a/test/langtools/tools/javac/cast/intersection/IntersectionTypeCastTest.java	Mon Oct 16 08:47:59 2017 -0700
+++ b/test/langtools/tools/javac/cast/intersection/IntersectionTypeCastTest.java	Tue Oct 17 14:33:32 2017 -0700
@@ -254,9 +254,9 @@
 
     @Override
     public void doWork() throws IOException {
-        check(newCompilationTask()
+        newCompilationTask()
                 .withSourceFromTemplate(bodyTemplate)
-                .analyze());
+                .analyze(this::check);
     }
 
     String bodyTemplate = "class Test {\n" +
--- a/test/langtools/tools/javac/defaultMethods/static/hiding/InterfaceMethodHidingTest.java	Mon Oct 16 08:47:59 2017 -0700
+++ b/test/langtools/tools/javac/defaultMethods/static/hiding/InterfaceMethodHidingTest.java	Tue Oct 17 14:33:32 2017 -0700
@@ -154,10 +154,10 @@
 
     @Override
     public void doWork() throws IOException {
-        check(newCompilationTask()
+        newCompilationTask()
                 .withOption("-XDallowStaticInterfaceMethods")
                 .withSourceFromTemplate(template, this::returnExpr)
-                .analyze());
+                .analyze(this::check);
     }
 
     ComboParameter returnExpr(String name) {
--- a/test/langtools/tools/javac/defaultMethods/super/TestDefaultSuperCall.java	Mon Oct 16 08:47:59 2017 -0700
+++ b/test/langtools/tools/javac/defaultMethods/super/TestDefaultSuperCall.java	Tue Oct 17 14:33:32 2017 -0700
@@ -303,9 +303,9 @@
 
     @Override
     public void doWork() throws IOException {
-        check(newCompilationTask()
+        newCompilationTask()
                 .withSourceFromTemplate(template, this::methodName)
-                .analyze());
+                .analyze(this::check);
     }
 
     ComboParameter methodName(String parameterName) {
--- a/test/langtools/tools/javac/failover/CheckAttributedTree.java	Mon Oct 16 08:47:59 2017 -0700
+++ b/test/langtools/tools/javac/failover/CheckAttributedTree.java	Tue Oct 17 14:33:32 2017 -0700
@@ -67,6 +67,7 @@
 import java.util.List;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.BiConsumer;
 
 import javax.lang.model.element.Element;
 import javax.swing.DefaultComboBoxModel;
@@ -287,61 +288,54 @@
                     errWriter.println(file);
                 fileCount.incrementAndGet();
                 NPETester p = new NPETester();
-                p.test(read(file));
-            } catch (AttributionException e) {
+                readAndCheck(file, p::test);
+            } catch (Throwable t) {
                 if (!quiet) {
-                    error("Error attributing " + file + "\n" + e.getMessage());
+                    error("Error checking " + file + "\n" + t.getMessage());
                 }
-            } catch (IOException e) {
-                error("Error reading " + file + ": " + e);
             }
         }
 
         /**
-         * Read a file.
+         * Read and check a file.
          * @param file the file to be read
          * @return the tree for the content of the file
          * @throws IOException if any IO errors occur
          * @throws AttributionException if any errors occur while analyzing the file
          */
-        List<Pair<JCCompilationUnit, JCTree>> read(File file) throws IOException, AttributionException {
-            try {
-                Iterable<? extends JavaFileObject> files = fileManager().getJavaFileObjects(file);
-                final List<Element> analyzedElems = new ArrayList<>();
-                final List<CompilationUnitTree> trees = new ArrayList<>();
-                Iterable<? extends Element> elems = newCompilationTask()
-                    .withWriter(pw)
-                        .withOption("--should-stop:at=ATTR")
-                        .withOption("-XDverboseCompilePolicy")
-                        .withSource(files.iterator().next())
-                        .withListener(new TaskListener() {
-                            public void started(TaskEvent e) {
-                                if (e.getKind() == TaskEvent.Kind.ANALYZE)
-                                analyzedElems.add(e.getTypeElement());
-                        }
+        void readAndCheck(File file, BiConsumer<JCCompilationUnit, JCTree> c) throws IOException {
+            Iterable<? extends JavaFileObject> files = fileManager().getJavaFileObjects(file);
+            final List<Element> analyzedElems = new ArrayList<>();
+            final List<CompilationUnitTree> trees = new ArrayList<>();
+            newCompilationTask()
+                .withWriter(pw)
+                    .withOption("--should-stop:at=ATTR")
+                    .withOption("-XDverboseCompilePolicy")
+                    .withSource(files.iterator().next())
+                    .withListener(new TaskListener() {
+                        public void started(TaskEvent e) {
+                            if (e.getKind() == TaskEvent.Kind.ANALYZE)
+                            analyzedElems.add(e.getTypeElement());
+                    }
 
-                        public void finished(TaskEvent e) {
-                            if (e.getKind() == Kind.PARSE)
-                                trees.add(e.getCompilationUnit());
-                        }
-                    }).analyze().get();
+                    public void finished(TaskEvent e) {
+                        if (e.getKind() == Kind.PARSE)
+                            trees.add(e.getCompilationUnit());
+                    }
+                }).analyze(res -> {
+                Iterable<? extends Element> elems = res.get();
                 if (!elems.iterator().hasNext())
-                    throw new AttributionException("No results from analyze");
-                List<Pair<JCCompilationUnit, JCTree>> res = new ArrayList<>();
+                    throw new AssertionError("No results from analyze");
                 for (CompilationUnitTree t : trees) {
                    JCCompilationUnit cu = (JCCompilationUnit)t;
                    for (JCTree def : cu.defs) {
                        if (def.hasTag(CLASSDEF) &&
                                analyzedElems.contains(((JCTree.JCClassDecl)def).sym)) {
-                           res.add(new Pair<>(cu, def));
+                           c.accept(cu, def);
                        }
                    }
                 }
-                return res;
-            }
-            catch (Throwable t) {
-                throw new AttributionException("Exception while attributing file: " + file);
-            }
+            });
         }
 
         /**
@@ -361,13 +355,11 @@
          * left uninitialized after attribution
          */
         private class NPETester extends TreeScanner {
-            void test(List<Pair<JCCompilationUnit, JCTree>> trees) {
-                for (Pair<JCCompilationUnit, JCTree> p : trees) {
-                    sourcefile = p.fst.sourcefile;
-                    endPosTable = p.fst.endPositions;
-                    encl = new Info(p.snd, endPosTable);
-                    p.snd.accept(this);
-                }
+            void test(JCCompilationUnit cut, JCTree tree) {
+                sourcefile = cut.sourcefile;
+                endPosTable = cut.endPositions;
+                encl = new Info(tree, endPosTable);
+                tree.accept(this);
             }
 
             @Override
@@ -537,21 +529,6 @@
     }
 
     /**
-     * Thrown when errors are found parsing a java file.
-     */
-    private static class ParseException extends Exception {
-        ParseException(String msg) {
-            super(msg);
-        }
-    }
-
-    private static class AttributionException extends Exception {
-        AttributionException(String msg) {
-            super(msg);
-        }
-    }
-
-    /**
      * GUI viewer for issues found by TreePosTester. The viewer provides a drop
      * down list for selecting error conditions, a header area providing details
      * about an error, and a text area with the ranges of text highlighted as
--- a/test/langtools/tools/javac/file/SymLinkTest.java	Mon Oct 16 08:47:59 2017 -0700
+++ b/test/langtools/tools/javac/file/SymLinkTest.java	Tue Oct 17 14:33:32 2017 -0700
@@ -23,22 +23,26 @@
 
 /*
  * @test
- * @bug 8178017
+ * @bug 8178017 8181897
  * @summary JDK 9 change to symlink handling causes misleading
- *      class.public.should.be.in.file diagnostic
+ *      class.public.should.be.in.file diagnostic and SourceFile
+ *      attribute content
  * @library /tools/lib
  * @modules jdk.compiler/com.sun.tools.javac.api
  *          jdk.compiler/com.sun.tools.javac.main
+ *          jdk.jdeps/com.sun.tools.classfile
  * @build toolbox.JavacTask toolbox.TestRunner toolbox.ToolBox
  * @run main SymLinkTest
  */
 
-import java.io.IOException;
 import java.nio.file.FileSystemException;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 
+import com.sun.tools.classfile.Attribute;
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.SourceFile_attribute;
 import toolbox.JavacTask;
 import toolbox.TestRunner;
 import toolbox.TestRunner.Test;
@@ -56,16 +60,16 @@
     }
 
     @Test
-    public void testgetKind(Path base) throws IOException {
+    public void testgetKind(Path base) throws Exception {
         test(base, "SOURCE");
     }
 
     @Test
-    public void testSymLink(Path base) throws IOException {
+    public void testSymLink(Path base) throws Exception {
         test(base, "SOURCE.java");
     }
 
-    void test(Path base, String name) throws IOException {
+    void test(Path base, String name) throws Exception{
         Path file = base.resolve(name);
         Path javaFile = base.resolve("HelloWorld.java");
         tb.writeFile(file,
@@ -89,6 +93,14 @@
             .files(javaFile)
             .run()
             .writeAll();
+
+        ClassFile cf = ClassFile.read(classes.resolve("HelloWorld.class"));
+        SourceFile_attribute sf = (SourceFile_attribute) cf.attributes.get(Attribute.SourceFile);
+        String sourceFile = sf.getSourceFile(cf.constant_pool);
+
+        if (!"HelloWorld.java".equals(sourceFile)) {
+            throw new AssertionError("Unexpected SourceFile attribute value: " + sourceFile);
+        }
     }
 }
 
--- a/test/langtools/tools/javac/generics/diamond/7046778/DiamondAndInnerClassTest.java	Mon Oct 16 08:47:59 2017 -0700
+++ b/test/langtools/tools/javac/generics/diamond/7046778/DiamondAndInnerClassTest.java	Tue Oct 17 14:33:32 2017 -0700
@@ -238,9 +238,9 @@
 
     @Override
     public void doWork() throws IOException {
-        check(newCompilationTask()
+        newCompilationTask()
                 .withSourceFromTemplate("#{DECL}")
-                .analyze());
+                .analyze(this::check);
     }
 
     void check(Result<?> res) {
--- a/test/langtools/tools/javac/generics/inference/8176534/TestUncheckedCalls.java	Mon Oct 16 08:47:59 2017 -0700
+++ b/test/langtools/tools/javac/generics/inference/8176534/TestUncheckedCalls.java	Tue Oct 17 14:33:32 2017 -0700
@@ -241,9 +241,9 @@
 
     @Override
     public void doWork() throws Throwable {
-        check(newCompilationTask()
+        newCompilationTask()
                 .withSourceFromTemplate(sourceTemplate)
-                .analyze());
+                .analyze(this::check);
     }
 
     void check(Result<Iterable<? extends Element>> result) {
--- a/test/langtools/tools/javac/generics/rawOverride/7062745/GenericOverrideTest.java	Mon Oct 16 08:47:59 2017 -0700
+++ b/test/langtools/tools/javac/generics/rawOverride/7062745/GenericOverrideTest.java	Tue Oct 17 14:33:32 2017 -0700
@@ -189,11 +189,11 @@
 
     @Override
     public void doWork() throws IOException {
-        check(newCompilationTask()
+        newCompilationTask()
                 .withOption("-XDuseUnsharedTable") //this test relies on predictable name indexes!
                 .withOptions(level.opts)
                 .withSourceFromTemplate(template)
-                .analyze());
+                .analyze(this::check);
     }
 
     void check(Result<?> res) {
--- a/test/langtools/tools/javac/lambda/FunctionalInterfaceConversionTest.java	Mon Oct 16 08:47:59 2017 -0700
+++ b/test/langtools/tools/javac/lambda/FunctionalInterfaceConversionTest.java	Tue Oct 17 14:33:32 2017 -0700
@@ -188,11 +188,11 @@
 
     @Override
     public void doWork() throws IOException {
-        check(newCompilationTask()
+        newCompilationTask()
                 .withSourceFromTemplate("Sam", samSource)
                 .withSourceFromTemplate("PackageClass", pkgClassSource)
                 .withSourceFromTemplate("Client", clientSource, this::importStmt)
-                .analyze());
+                .analyze(this::check);
     }
 
     ComboParameter importStmt(String name) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/lambda/LambdaInSuperCallCapturingOuterThis.java	Tue Oct 17 14:33:32 2017 -0700
@@ -0,0 +1,59 @@
+/*
+ * 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 8184989
+ * @summary Incorrect class file created when passing lambda in inner class constructor and outer is subclass
+ * @run main LambdaInSuperCallCapturingOuterThis
+ */
+
+class A8184989 {
+    public boolean test() {
+        return true;
+    }
+
+    class AA {
+        public AA(Condition8184989<AA> condition) {
+        }
+    }
+}
+
+interface Condition8184989<T> {
+    boolean check(T t);
+}
+
+public class LambdaInSuperCallCapturingOuterThis extends A8184989 {
+
+    public LambdaInSuperCallCapturingOuterThis() {
+        new BA();
+    }
+    public class BA extends AA {
+        public BA() {
+            super(o -> test());
+        }
+    }
+    public static void main(String[] args) {
+        LambdaInSuperCallCapturingOuterThis b = new LambdaInSuperCallCapturingOuterThis();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/lambda/LambdaInSuperCallCapturingOuterThis2.java	Tue Oct 17 14:33:32 2017 -0700
@@ -0,0 +1,62 @@
+/*
+ * 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 8184989
+ * @summary Incorrect class file created when passing lambda in inner class constructor and outer is subclass
+ * @run main LambdaInSuperCallCapturingOuterThis2
+ */
+
+class A8184989_2 {
+    public boolean test() {
+        return true;
+    }
+    class AA {
+        public AA(Condition8184989_2<AA> condition) {
+            if (condition.check(this) != true) {
+                throw new AssertionError("Incorrect output");
+            }
+        }
+    }
+}
+
+interface Condition8184989_2<T> {
+    boolean check(T t);
+}
+
+public class LambdaInSuperCallCapturingOuterThis2 extends A8184989_2 {
+    public boolean test() {return false;}
+    public void b() {}
+
+    class C extends A8184989_2 {
+        public class BA extends AA {
+            public BA() {
+                super(o -> {b(); return test();});
+            }
+        }
+    }
+    public static void main(String[] args) {
+        new LambdaInSuperCallCapturingOuterThis2().new C().new BA();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/lambda/LambdaInSuperCallCapturingOuterThis3.java	Tue Oct 17 14:33:32 2017 -0700
@@ -0,0 +1,65 @@
+/*
+ * 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 8184989
+ * @summary Incorrect class file created when passing lambda in inner class constructor and outer is subclass
+ * @run main LambdaInSuperCallCapturingOuterThis3
+ */
+
+interface I8184989_3 {
+    public default boolean test(){
+        return true;
+    }
+}
+
+class A8184989_3 implements I8184989_3 {
+    class AA {
+        public AA(Condition8184989_3<AA> condition) {
+            if (condition.check(this) != true) {
+                throw new AssertionError("Incorrect output");
+            }
+        }
+    }
+}
+
+interface Condition8184989_3<T> {
+    boolean check(T t);
+}
+
+public class LambdaInSuperCallCapturingOuterThis3 extends A8184989_3 {
+    public boolean test() {return false;}
+    public void b() {}
+
+    class C extends A8184989_3 {
+        public class BA extends AA {
+            public BA() {
+                super(o -> {b(); return test();});
+            }
+        }
+    }
+    public static void main(String[] args) {
+        new LambdaInSuperCallCapturingOuterThis3().new C().new BA();
+    }
+}
--- a/test/langtools/tools/javac/lambda/LambdaParserTest.java	Mon Oct 16 08:47:59 2017 -0700
+++ b/test/langtools/tools/javac/lambda/LambdaParserTest.java	Tue Oct 17 14:33:32 2017 -0700
@@ -246,9 +246,9 @@
 
     @Override
     public void doWork() throws IOException {
-        check(newCompilationTask()
+        newCompilationTask()
                 .withSourceFromTemplate(template)
-                .parse());
+                .parse(this::check);
     }
 
     void check(Result<?> res) {
--- a/test/langtools/tools/javac/lambda/MethodReferenceParserTest.java	Mon Oct 16 08:47:59 2017 -0700
+++ b/test/langtools/tools/javac/lambda/MethodReferenceParserTest.java	Tue Oct 17 14:33:32 2017 -0700
@@ -203,9 +203,9 @@
 
     @Override
     public void doWork() throws IOException {
-        check(newCompilationTask()
+        newCompilationTask()
                 .withSourceFromTemplate(template)
-                .parse());
+                .parse(this::check);
     }
 
     void check(Result<?> res) {
--- a/test/langtools/tools/javac/lambda/TestInvokeDynamic.java	Mon Oct 16 08:47:59 2017 -0700
+++ b/test/langtools/tools/javac/lambda/TestInvokeDynamic.java	Tue Oct 17 14:33:32 2017 -0700
@@ -252,17 +252,16 @@
 
     @Override
     public void doWork() throws IOException {
-        ComboTask comboTask = newCompilationTask()
+        newCompilationTask()
                 .withOption("-g")
-                .withSourceFromTemplate(source_template);
-
-        JavacTaskImpl ct = (JavacTaskImpl)comboTask.getTask();
-        Context context = ct.getContext();
-        Symtab syms = Symtab.instance(context);
-        Names names = Names.instance(context);
-        Types types = Types.instance(context);
-        ct.addTaskListener(new Indifier(syms, names, types));
-        verifyBytecode(comboTask.generate());
+                .withSourceFromTemplate(source_template)
+                .withListenerFactory(context -> {
+                        Symtab syms = Symtab.instance(context);
+                        Names names = Names.instance(context);
+                        Types types = Types.instance(context);
+                        return new Indifier(syms, names, types);
+                    })
+                .generate(this::verifyBytecode);
     }
 
     void verifyBytecode(Result<Iterable<? extends JavaFileObject>> res) {
--- a/test/langtools/tools/javac/lambda/TestLambdaToMethodStats.java	Mon Oct 16 08:47:59 2017 -0700
+++ b/test/langtools/tools/javac/lambda/TestLambdaToMethodStats.java	Tue Oct 17 14:33:32 2017 -0700
@@ -121,10 +121,10 @@
 
     @Override
     public void doWork() throws IOException {
-        check(newCompilationTask()
+        newCompilationTask()
                 .withOption("--debug:dumpLambdaToMethodStats")
                 .withSourceFromTemplate(template)
-                .generate());
+                .generate(this::check);
     }
 
     void check(Result<?> res) {
--- a/test/langtools/tools/javac/lambda/bytecode/TestLambdaBytecode.java	Mon Oct 16 08:47:59 2017 -0700
+++ b/test/langtools/tools/javac/lambda/bytecode/TestLambdaBytecode.java	Tue Oct 17 14:33:32 2017 -0700
@@ -193,9 +193,9 @@
 
     @Override
     public void doWork() throws IOException {
-        verifyBytecode(newCompilationTask()
+        newCompilationTask()
                 .withSourceFromTemplate(source_template)
-                .generate());
+                .generate(this::verifyBytecode);
     }
 
     void verifyBytecode(Result<Iterable<? extends JavaFileObject>> res) {
--- a/test/langtools/tools/javac/lambda/mostSpecific/StructuralMostSpecificTest.java	Mon Oct 16 08:47:59 2017 -0700
+++ b/test/langtools/tools/javac/lambda/mostSpecific/StructuralMostSpecificTest.java	Tue Oct 17 14:33:32 2017 -0700
@@ -208,10 +208,10 @@
 
     @Override
     public void doWork() throws Throwable {
-        check(newCompilationTask()
+        newCompilationTask()
                 .withSourceFromTemplate(sourceTemplate)
                 .withOption("--debug:verboseResolution=all,-predef,-internal,-object-init")
-                .analyze());
+                .analyze(this::check);
     }
 
     void check(Result<Iterable<? extends Element>> result) {
--- a/test/langtools/tools/javac/lambda/typeInference/combo/TypeInferenceComboTest.java	Mon Oct 16 08:47:59 2017 -0700
+++ b/test/langtools/tools/javac/lambda/typeInference/combo/TypeInferenceComboTest.java	Tue Oct 17 14:33:32 2017 -0700
@@ -281,14 +281,14 @@
 
     @Override
     public void doWork() throws IOException {
-        Result<?> res = newCompilationTask()
+        newCompilationTask()
                 .withSourceFromTemplate("Sam", sam_template, this::samClass)
                 .withSourceFromTemplate("Client", client_template, this::clientContext)
-                .analyze();
-
-        if (res.hasErrors() == checkTypeInference()) {
-            fail("Unexpected compilation output when compiling instance: " + res.compilationInfo());
-        }
+                .analyze(res -> {
+            if (res.hasErrors() == checkTypeInference()) {
+                fail("Unexpected compilation output when compiling instance: " + res.compilationInfo());
+            }
+        });
     }
 
     ComboParameter samClass(String parameterName) {
--- a/test/langtools/tools/javac/lib/combo/ComboTask.java	Mon Oct 16 08:47:59 2017 -0700
+++ b/test/langtools/tools/javac/lib/combo/ComboTask.java	Tue Oct 17 14:33:32 2017 -0700
@@ -26,8 +26,9 @@
 import com.sun.source.tree.CompilationUnitTree;
 import com.sun.source.util.JavacTask;
 import com.sun.source.util.TaskListener;
-import com.sun.tools.javac.api.JavacTool;
+import com.sun.tools.javac.api.JavacTaskImpl;
 import com.sun.tools.javac.util.Assert;
+import com.sun.tools.javac.util.Context;
 import com.sun.tools.javac.util.List;
 import combo.ComboParameter.Resolver;
 
@@ -40,16 +41,11 @@
 import java.io.IOException;
 import java.io.Writer;
 import java.net.URI;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.util.ArrayList;
 import java.util.function.Consumer;
 import java.util.function.Function;
 import java.util.HashMap;
 import java.util.Map;
-import java.util.Optional;
 import java.util.stream.Collectors;
-import java.util.stream.StreamSupport;
 
 /**
  * This class represents a compilation task associated with a combo test instance. This is a small
@@ -73,8 +69,8 @@
     /** Listeners associated with this task. */
     private List<TaskListener> listeners = List.nil();
 
-    /** Underlying javac task object. */
-    private JavacTask task;
+    /** Listener factories associated with this task. */
+    private List<Function<Context, TaskListener>> listenerFactories = List.nil();
 
     /** Combo execution environment. */
     private ComboTestHelper<?>.Env env;
@@ -170,77 +166,55 @@
     }
 
     /**
+     * Add a task listener factory to this task.
+     */
+    public ComboTask withListenerFactory(Function<Context, TaskListener> factory) {
+        listenerFactories = listenerFactories.prepend(factory);
+        return this;
+    }
+
+    /**
      * Parse the sources associated with this task.
      */
-    public Result<Iterable<? extends CompilationUnitTree>> parse() throws IOException {
-        return new Result<>(getTask().parse());
+    public void parse(Consumer<Result<Iterable<? extends CompilationUnitTree>>> c) {
+        doRunTest(c, JavacTask::parse);
     }
 
     /**
      * Parse and analyzes the sources associated with this task.
      */
-    public Result<Iterable<? extends Element>> analyze() throws IOException {
-        return new Result<>(getTask().analyze());
+    public void analyze(Consumer<Result<Iterable<? extends Element>>> c) {
+        doRunTest(c, JavacTask::analyze);
     }
 
     /**
      * Parse, analyze and perform code generation for the sources associated with this task.
      */
-    public Result<Iterable<? extends JavaFileObject>> generate() throws IOException {
-        return new Result<>(getTask().generate());
-    }
-
-    /**
-     * Parse, analyze, perform code generation for the sources associated with this task and finally
-     * executes them
-     */
-    public <Z> Optional<Z> execute(Function<ExecutionTask, Z> executionFunc) throws IOException {
-        Result<Iterable<? extends JavaFileObject>> generationResult = generate();
-        Iterable<? extends JavaFileObject> jfoIterable = generationResult.get();
-        if (generationResult.hasErrors()) {
-            // we have nothing else to do
-            return Optional.empty();
-        }
-        java.util.List<URL> urlList = new ArrayList<>();
-        for (JavaFileObject jfo : jfoIterable) {
-            String urlStr = jfo.toUri().toURL().toString();
-            urlStr = urlStr.substring(0, urlStr.length() - jfo.getName().length());
-            urlList.add(new URL(urlStr));
-        }
-        return Optional.of(
-                executionFunc.apply(
-                        new ExecutionTask(new URLClassLoader(urlList.toArray(new URL[urlList.size()])))));
+    public void generate(Consumer<Result<Iterable<? extends JavaFileObject>>> c) {
+        doRunTest(c, JavacTask::generate);
     }
 
-    /**
-     * Fork a new compilation task; if possible the compilation context from previous executions is
-     * retained (see comments in ReusableContext as to when it's safe to do so); otherwise a brand
-     * new context is created.
-     */
-    public JavacTask getTask() {
-        if (task == null) {
-            ReusableContext context = env.context();
-            String opts = options == null ? "" :
-                    StreamSupport.stream(options.spliterator(), false).collect(Collectors.joining());
-            context.clear();
-            if (!context.polluted && (context.opts == null || context.opts.equals(opts))) {
-                //we can reuse former context
-                env.info().ctxReusedCount++;
-            } else {
-                env.info().ctxDroppedCount++;
-                //it's not safe to reuse context - create a new one
-                context = env.setContext(new ReusableContext());
+    private <V> void doRunTest(Consumer<Result<Iterable<? extends V>>> c,
+                               Convertor<V> task2Data) {
+        env.pool().getTask(out, env.fileManager(),
+                diagsCollector, options, null, sources, task -> {
+            try {
+                for (TaskListener l : listeners) {
+                    task.addTaskListener(l);
+                }
+                for (Function<Context, TaskListener> f : listenerFactories) {
+                    task.addTaskListener(f.apply(((JavacTaskImpl) task).getContext()));
+                }
+                c.accept(new Result<>(task2Data.convert(task)));
+                return null;
+            } catch (IOException ex) {
+                throw new AssertionError(ex);
             }
-            context.opts = opts;
-            JavacTask javacTask = ((JavacTool)env.javaCompiler()).getTask(out, env.fileManager(),
-                    diagsCollector, options, null, sources, context);
-            javacTask.setTaskListener(context);
-            for (TaskListener l : listeners) {
-                javacTask.addTaskListener(l);
-            }
-            task = javacTask;
-        }
-        return task;
+        });
+    }
+
+    interface Convertor<V> {
+        public Iterable<? extends V> convert(JavacTask task) throws IOException;
     }
 
     /**
--- a/test/langtools/tools/javac/lib/combo/ComboTestHelper.java	Mon Oct 16 08:47:59 2017 -0700
+++ b/test/langtools/tools/javac/lib/combo/ComboTestHelper.java	Tue Oct 17 14:33:32 2017 -0700
@@ -28,6 +28,7 @@
 import javax.tools.ToolProvider;
 
 import java.io.IOException;
+import java.io.Writer;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -38,6 +39,12 @@
 import java.util.function.Predicate;
 import java.util.function.Supplier;
 
+import javax.tools.DiagnosticListener;
+import javax.tools.JavaFileManager;
+import javax.tools.JavaFileObject;
+
+import com.sun.source.util.JavacTask;
+import com.sun.tools.javac.api.JavacTaskPool;
 
 /**
  * An helper class for defining combinatorial (aka "combo" tests). A combo test is made up of one
@@ -93,8 +100,8 @@
     /** Shared file manager used across all combo test instances. */
     StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
 
-    /** Shared context used across all combo instances. */
-    ReusableContext context = new ReusableContext();
+    /** JavacTask pool shared across all combo instances. */
+    JavacTaskPool pool = new JavacTaskPool(1);
 
     /**
      * Set failure mode for this combo test.
@@ -248,7 +255,7 @@
         } catch (IOException ex) {
             throw new AssertionError("Failure when closing down shared file manager; ", ex);
         } finally {
-            info.dump();
+            info.dump(this);
         }
     }
 
@@ -375,19 +382,16 @@
         int passCount;
         int comboCount;
         int skippedCount;
-        int ctxReusedCount;
-        int ctxDroppedCount;
         Optional<String> lastFailure = Optional.empty();
         Optional<Throwable> lastError = Optional.empty();
 
-        void dump() {
+        void dump(ComboTestHelper<?> helper) {
             System.err.println(String.format("%d total checks executed", comboCount));
             System.err.println(String.format("%d successes found", passCount));
             System.err.println(String.format("%d failures found", failCount));
             System.err.println(String.format("%d errors found", errCount));
             System.err.println(String.format("%d skips found", skippedCount));
-            System.err.println(String.format("%d contexts shared", ctxReusedCount));
-            System.err.println(String.format("%d contexts dropped", ctxDroppedCount));
+            helper.pool.printStatistics(System.err);
         }
 
         public boolean hasFailures() {
@@ -400,7 +404,7 @@
     }
 
     /**
-     * THe execution environment for a given combo test instance. An environment contains the
+     * The execution environment for a given combo test instance. An environment contains the
      * bindings for all the dimensions, along with the combo parameter cache (this is non-empty
      * only if one or more dimensions are subclasses of the {@code ComboParameter} interface).
      */
@@ -430,12 +434,8 @@
             return comp;
         }
 
-        ReusableContext context() {
-            return context;
-        }
-
-        ReusableContext setContext(ReusableContext context) {
-            return ComboTestHelper.this.context = context;
+        JavacTaskPool pool() {
+            return pool;
         }
     }
 }
--- a/test/langtools/tools/javac/lib/combo/ReusableContext.java	Mon Oct 16 08:47:59 2017 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,229 +0,0 @@
-/*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package combo;
-
-import com.sun.source.tree.ClassTree;
-import com.sun.source.tree.CompilationUnitTree;
-import com.sun.source.util.JavacTask;
-import com.sun.source.util.TaskEvent;
-import com.sun.source.util.TaskEvent.Kind;
-import com.sun.source.util.TaskListener;
-import com.sun.source.util.TreeScanner;
-import com.sun.tools.javac.api.MultiTaskListener;
-import com.sun.tools.javac.code.Kinds;
-import com.sun.tools.javac.code.Symbol;
-import com.sun.tools.javac.code.Symtab;
-import com.sun.tools.javac.code.Type;
-import com.sun.tools.javac.code.Type.ClassType;
-import com.sun.tools.javac.code.TypeTag;
-import com.sun.tools.javac.code.Types;
-import com.sun.tools.javac.comp.Annotate;
-import com.sun.tools.javac.comp.Check;
-import com.sun.tools.javac.comp.CompileStates;
-import com.sun.tools.javac.comp.Enter;
-import com.sun.tools.javac.comp.Modules;
-import com.sun.tools.javac.main.Arguments;
-import com.sun.tools.javac.main.JavaCompiler;
-import com.sun.tools.javac.tree.JCTree.JCClassDecl;
-import com.sun.tools.javac.util.Context;
-import com.sun.tools.javac.util.Log;
-
-import javax.tools.Diagnostic;
-import javax.tools.DiagnosticListener;
-import javax.tools.JavaFileManager;
-import javax.tools.JavaFileObject;
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * A reusable context is a context that can be used safely across multiple compilation rounds
- * arising from execution of a combo test. It achieves reuse by replacing some components
- * (most notably JavaCompiler and Log) with reusable counterparts, and by exposing a method
- * to cleanup leftovers from previous compilation.
- * <p>
- * There are, however, situations in which reusing the context is not safe: (i) when different
- * compilations are using different sets of compiler options (as most option values are cached
- * inside components themselves) and (ii) when the compilation unit happens to redefine classes
- * in the java.* packages.
- */
-class ReusableContext extends Context implements TaskListener {
-
-    Set<CompilationUnitTree> roots = new HashSet<>();
-
-    String opts;
-    boolean polluted = false;
-
-    ReusableContext() {
-        super();
-        put(Log.logKey, ReusableLog.factory);
-        put(JavaCompiler.compilerKey, ReusableJavaCompiler.factory);
-    }
-
-    void clear() {
-        drop(Arguments.argsKey);
-        drop(DiagnosticListener.class);
-        drop(Log.outKey);
-        drop(Log.errKey);
-        drop(JavaFileManager.class);
-        drop(JavacTask.class);
-
-        if (ht.get(Log.logKey) instanceof ReusableLog) {
-            //log already inited - not first round
-            ((ReusableLog)Log.instance(this)).clear();
-            Enter.instance(this).newRound();
-            ((ReusableJavaCompiler)ReusableJavaCompiler.instance(this)).clear();
-            Types.instance(this).newRound();
-            Check.instance(this).newRound();
-            Modules.instance(this).newRound();
-            Annotate.instance(this).newRound();
-            CompileStates.instance(this).clear();
-            MultiTaskListener.instance(this).clear();
-
-            //find if any of the roots have redefined java.* classes
-            Symtab syms = Symtab.instance(this);
-            pollutionScanner.scan(roots, syms);
-            roots.clear();
-        }
-    }
-
-    /**
-     * This scanner detects as to whether the shared context has been polluted. This happens
-     * whenever a compiled program redefines a core class (in 'java.*' package) or when
-     * (typically because of cyclic inheritance) the symbol kind of a core class has been touched.
-     */
-    TreeScanner<Void, Symtab> pollutionScanner = new TreeScanner<Void, Symtab>() {
-        @Override
-        public Void visitClass(ClassTree node, Symtab syms) {
-            Symbol sym = ((JCClassDecl)node).sym;
-            if (sym != null) {
-                syms.removeClass(sym.packge().modle, sym.flatName());
-                Type sup = supertype(sym);
-                if (isCoreClass(sym) ||
-                        (sup != null && isCoreClass(sup.tsym) && sup.tsym.kind != Kinds.Kind.TYP)) {
-                    polluted = true;
-                }
-            }
-            return super.visitClass(node, syms);
-        }
-
-        private boolean isCoreClass(Symbol s) {
-            return s.flatName().toString().startsWith("java.");
-        }
-
-        private Type supertype(Symbol s) {
-            if (s.type == null ||
-                    !s.type.hasTag(TypeTag.CLASS)) {
-                return null;
-            } else {
-                ClassType ct = (ClassType)s.type;
-                return ct.supertype_field;
-            }
-        }
-    };
-
-    @Override
-    public void finished(TaskEvent e) {
-        if (e.getKind() == Kind.PARSE) {
-            roots.add(e.getCompilationUnit());
-        }
-    }
-
-    @Override
-    public void started(TaskEvent e) {
-        //do nothing
-    }
-
-    <T> void drop(Key<T> k) {
-        ht.remove(k);
-    }
-
-    <T> void drop(Class<T> c) {
-        ht.remove(key(c));
-    }
-
-    /**
-     * Reusable JavaCompiler; exposes a method to clean up the component from leftovers associated with
-     * previous compilations.
-     */
-    static class ReusableJavaCompiler extends JavaCompiler {
-
-        static Factory<JavaCompiler> factory = ReusableJavaCompiler::new;
-
-        ReusableJavaCompiler(Context context) {
-            super(context);
-        }
-
-        @Override
-        public void close() {
-            //do nothing
-        }
-
-        void clear() {
-            newRound();
-        }
-
-        @Override
-        protected void checkReusable() {
-            //do nothing - it's ok to reuse the compiler
-        }
-    }
-
-    /**
-     * Reusable Log; exposes a method to clean up the component from leftovers associated with
-     * previous compilations.
-     */
-    static class ReusableLog extends Log {
-
-        static Factory<Log> factory = ReusableLog::new;
-
-        Context context;
-
-        ReusableLog(Context context) {
-            super(context);
-            this.context = context;
-        }
-
-        void clear() {
-            recorded.clear();
-            sourceMap.clear();
-            nerrors = 0;
-            nwarnings = 0;
-            //Set a fake listener that will lazily lookup the context for the 'real' listener. Since
-            //this field is never updated when a new task is created, we cannot simply reset the field
-            //or keep old value. This is a hack to workaround the limitations in the current infrastructure.
-            diagListener = new DiagnosticListener<JavaFileObject>() {
-                DiagnosticListener<JavaFileObject> cachedListener;
-
-                @Override
-                @SuppressWarnings("unchecked")
-                public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
-                    if (cachedListener == null) {
-                        cachedListener = context.get(DiagnosticListener.class);
-                    }
-                    cachedListener.report(diagnostic);
-                }
-            };
-        }
-    }
-}
--- a/test/langtools/tools/javac/multicatch/7030606/DisjunctiveTypeWellFormednessTest.java	Mon Oct 16 08:47:59 2017 -0700
+++ b/test/langtools/tools/javac/multicatch/7030606/DisjunctiveTypeWellFormednessTest.java	Tue Oct 17 14:33:32 2017 -0700
@@ -128,9 +128,9 @@
 
     @Override
     public void doWork() throws IOException {
-        check(newCompilationTask()
+        newCompilationTask()
                 .withSourceFromTemplate(template)
-                .analyze());
+                .analyze(this::check);
     }
 
     void check(Result<?> res) {
--- a/test/langtools/tools/javac/resolve/BitWiseOperators.java	Mon Oct 16 08:47:59 2017 -0700
+++ b/test/langtools/tools/javac/resolve/BitWiseOperators.java	Tue Oct 17 14:33:32 2017 -0700
@@ -100,13 +100,14 @@
 
     @Override
     public void doWork() throws IOException {
-        Result<?> res = newCompilationTask()
+        newCompilationTask()
                 .withSourceFromTemplate(template)
-                .analyze();
-        if (res.hasErrors() == OperandType.compatible(opTypes[0], opTypes[1])) {
-            fail("Unexpected behavior. Type1: " + opTypes[0] +
-                    "; type2: " + opTypes[1] +
-                    "; " + res.compilationInfo());
-        }
+                .analyze(res -> {
+            if (res.hasErrors() == OperandType.compatible(opTypes[0], opTypes[1])) {
+                fail("Unexpected behavior. Type1: " + opTypes[0] +
+                        "; type2: " + opTypes[1] +
+                        "; " + res.compilationInfo());
+            }
+        });
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/tree/ScopeClassHeaderTest.java	Tue Oct 17 14:33:32 2017 -0700
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug     8186694
+ * @summary Verify that taking a Scope inside a class header
+ *          does not taint internal structures
+ * @modules jdk.compiler
+ * @run main ScopeClassHeaderTest
+ */
+
+import com.sun.source.tree.CompilationUnitTree;
+import com.sun.source.tree.Scope;
+import com.sun.source.util.JavacTask;
+import com.sun.source.util.TreePathScanner;
+import com.sun.source.util.Trees;
+
+import java.io.IOException;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collections;
+
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileObject;
+import javax.tools.JavaFileObject.Kind;
+import javax.tools.SimpleJavaFileObject;
+import javax.tools.ToolProvider;
+
+import com.sun.source.tree.IdentifierTree;
+
+public class ScopeClassHeaderTest {
+
+    public static void main(String... args) throws Exception {
+        verifyScopeForClassHeader();
+    }
+
+    private static void verifyScopeForClassHeader() throws Exception {
+        JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
+        JavaFileObject source = new SimpleJavaFileObject(URI.create("mem://Test.java"), Kind.SOURCE) {
+            @Override public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
+                return "import java.util.*; class O { public void m() { class X<T extends ArrayList> { public void test() { String o; } } } }";
+            }
+            @Override public boolean isNameCompatible(String simpleName, Kind kind) {
+                return !"module-info".equals(simpleName);
+            }
+        };
+        Iterable<? extends JavaFileObject> fos = Collections.singletonList(source);
+        JavacTask task = (JavacTask) tool.getTask(null, null, null, new ArrayList<String>(), null, fos);
+        final Trees trees = Trees.instance(task);
+        CompilationUnitTree cu = task.parse().iterator().next();
+
+        task.analyze();
+
+        new TreePathScanner<Void, Void>() {
+            @Override
+            public Void visitIdentifier(IdentifierTree node, Void p) {
+                if (node.getName().contentEquals("ArrayList") || node.getName().contentEquals("String")) {
+                    Scope scope = trees.getScope(getCurrentPath());
+                    System.err.println("scope: " + scope);
+                }
+                return super.visitIdentifier(node, p);
+            }
+        }.scan(cu, null);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/util/JavacTaskPoolTest.java	Tue Oct 17 14:33:32 2017 -0700
@@ -0,0 +1,91 @@
+/*
+ * 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 8186694
+ * @summary Check that JavacTaskPool reuses JavacTask internals when it should
+ * @modules jdk.compiler/com.sun.tools.javac.api
+ * @run main JavacTaskPoolTest
+ */
+
+import java.util.List;
+
+import javax.lang.model.util.Types;
+
+import com.sun.tools.javac.api.JavacTaskPool;
+
+public class JavacTaskPoolTest {
+    public static void main(String... args) throws Exception {
+        new JavacTaskPoolTest().run();
+    }
+
+    void run() throws Exception {
+        JavacTaskPool pool = new JavacTaskPool(2);
+        Types tps1 = pool.getTask(null, null, null, List.of("-XDone"), null, null, task -> {
+            task.getElements(); //initialize
+            return task.getTypes();
+        });
+        Types tps2  = pool.getTask(null, null, null, List.of("-XDone"), null, null, task -> {
+            task.getElements(); //initialize
+            return task.getTypes();
+        });
+
+        assertSame(tps1, tps2);
+
+        Types tps3 = pool.getTask(null, null, null, List.of("-XDtwo"), null, null, task -> {
+            task.getElements(); //initialize
+            return task.getTypes();
+        });
+
+        assertNotSame(tps1, tps3);
+
+        Types tps4 = pool.getTask(null, null, null, List.of("-XDthree"), null, null, task -> {
+            task.getElements(); //initialize
+            return task.getTypes();
+        });
+
+        assertNotSame(tps1, tps4);
+        assertNotSame(tps3, tps4);
+
+        Types tps5 = pool.getTask(null, null, null, List.of("-XDone"), null, null, task -> {
+            task.getElements(); //initialize
+            return task.getTypes();
+        });
+
+        assertNotSame(tps1, tps5);
+    }
+
+    void assertSame(Object expected, Object actual) {
+        if (expected != actual) {
+            throw new IllegalStateException("expected=" + expected + "; actual=" + actual);
+        }
+    }
+
+    void assertNotSame(Object expected, Object actual) {
+        if (expected == actual) {
+            throw new IllegalStateException("expected=" + expected + "; actual=" + actual);
+        }
+    }
+
+}
--- a/test/langtools/tools/javac/varargs/7042566/T7042566.java	Mon Oct 16 08:47:59 2017 -0700
+++ b/test/langtools/tools/javac/varargs/7042566/T7042566.java	Tue Oct 17 14:33:32 2017 -0700
@@ -224,9 +224,9 @@
 
     @Override
     public void doWork() throws IOException {
-        check(newCompilationTask()
+        newCompilationTask()
                 .withSourceFromTemplate(source_template, this::getMethodDecl)
-                .generate());
+                .generate(this::check);
     }
 
     ComboParameter getMethodDecl(String parameterName) {
--- a/test/langtools/tools/javac/varargs/warning/Warn4.java	Mon Oct 16 08:47:59 2017 -0700
+++ b/test/langtools/tools/javac/varargs/warning/Warn4.java	Tue Oct 17 14:33:32 2017 -0700
@@ -231,12 +231,12 @@
 
     @Override
     public void doWork() throws IOException {
-        check(newCompilationTask()
+        newCompilationTask()
                 .withOption("-Xlint:unchecked")
                 .withOption("-source")
                 .withOption(sourceLevel.sourceKey)
                 .withSourceFromTemplate(template)
-                .analyze());
+                .analyze(this::check);
     }
 
     void check(Result<?> res) {
--- a/test/langtools/tools/javac/varargs/warning/Warn5.java	Mon Oct 16 08:47:59 2017 -0700
+++ b/test/langtools/tools/javac/varargs/warning/Warn5.java	Tue Oct 17 14:33:32 2017 -0700
@@ -235,12 +235,12 @@
 
     @Override
     public void doWork() throws IOException {
-        check(newCompilationTask()
+        newCompilationTask()
                 .withOption(xlint.getXlintOption())
                 .withOption("-source")
                 .withOption(sourceLevel.sourceKey)
                 .withSourceFromTemplate(template)
-                .analyze());
+                .analyze(this::check);
     }
 
     void check(Result<?> res) {
--- a/test/langtools/tools/jdeps/listdeps/ListModuleDeps.java	Mon Oct 16 08:47:59 2017 -0700
+++ b/test/langtools/tools/jdeps/listdeps/ListModuleDeps.java	Tue Oct 17 14:33:32 2017 -0700
@@ -24,7 +24,7 @@
 /*
  * @test
  * @bug 8167057
- * @summary Tests --list-deps and --list-reduced-deps options
+ * @summary Tests --list-deps, --list-reduced-deps, --print-module-deps options
  * @modules java.logging
  *          java.xml
  *          jdk.compiler
@@ -38,6 +38,7 @@
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.Arrays;
+import java.util.stream.Collectors;
 
 import org.testng.annotations.BeforeTest;
 import org.testng.annotations.DataProvider;
@@ -139,8 +140,7 @@
                                 "java.logging",
                                 "java.sql",
                                 "java.xml/jdk.xml.internal",
-                                "jdk.unsupported",
-                                "unnamed module: lib"
+                                "jdk.unsupported"
                             }
             },
 
@@ -153,8 +153,7 @@
                                 "java.base",
                                 "java.logging",
                                 "java.sql",
-                                "java.xml",
-                                "unnamed module: lib"
+                                "java.xml"
                             }
             },
 
@@ -166,7 +165,7 @@
 
             { UNSAFE_CLASS, new String[] {
                                 "java.base/jdk.internal.misc",
-                                "jdk.unsupported",
+                                "jdk.unsupported"
                             }
             },
         };
@@ -182,8 +181,7 @@
                                 "java.base/sun.security.util",
                                 "java.sql",
                                 "java.xml/jdk.xml.internal",
-                                "jdk.unsupported",
-                                "unnamed module: lib"
+                                "jdk.unsupported"
                             }
             },
 
@@ -193,8 +191,8 @@
             },
 
             { FOO_CLASS,    new String[] {
-                                "java.sql",
-                                "unnamed module: lib"
+                                "java.base",
+                                "java.sql"
                             }
             },
 
@@ -206,10 +204,36 @@
 
             { UNSAFE_CLASS, new String[] {
                                 "java.base/jdk.internal.misc",
-                                "jdk.unsupported",
+                                "jdk.unsupported"
                             }
             },
         };
     }
 
+    @Test(dataProvider = "moduledeps")
+    public void testPrintModuleDeps(Path classes, String expected) {
+        JdepsRunner jdeps = JdepsRunner.run(
+            "--class-path", LIB_DIR.toString(),
+            "--print-module-deps", classes.toString()
+        );
+        String output = Arrays.stream(jdeps.output())
+            .map(s -> s.trim())
+            .collect(Collectors.joining(","));
+        assertEquals(output, expected);
+    }
+
+
+    @DataProvider(name = "moduledeps")
+    public Object[][] moduledeps() {
+        Path barClass = CLASSES_DIR.resolve("z").resolve("Bar.class");
+
+        return new Object[][] {
+            // java.xml is an implied reads edge from java.sql
+            { CLASSES_DIR,  "java.base,java.sql,jdk.unsupported"},
+            { HI_CLASS,     "java.base"},
+            { FOO_CLASS,    "java.base,java.sql"},
+            { BAR_CLASS,    "java.base,java.xml"},
+            { UNSAFE_CLASS, "java.base,jdk.unsupported"},
+        };
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/make/TestCopyFiles.gmk	Tue Oct 17 14:33:32 2017 -0700
@@ -0,0 +1,80 @@
+#
+# 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.
+#
+
+default: all
+
+include $(SPEC)
+include MakeBase.gmk
+include UtilsForTests.gmk
+
+THIS_FILE := $(TOPDIR)/test/make/TestCopyFiles.gmk
+DEPS := $(THIS_FILE) \
+    $(TOPDIR)/make/common/MakeBase.gmk \
+    #
+
+OUTPUT_DIR := $(TESTMAKE_OUTPUTDIR)/copy-files
+$(call MakeDir, $(OUTPUT_DIR))
+
+################################################################################
+# Test SetupCopyFiles with CacheFind and files with spaces in their names.
+
+SRC_DIR := $(OUTPUT_DIR)/src
+DEST_DIR := $(OUTPUT_DIR)/dest
+
+$(OUTPUT_DIR)/_src_created: $(DEPS)
+	$(RM) -r $(SRC_DIR)
+	$(MKDIR) -p $(SRC_DIR)
+	$(MKDIR) -p $(SRC_DIR)/foo
+	$(TOUCH) $(SRC_DIR)/file
+	$(TOUCH) $(SRC_DIR)/foo/foofile
+	$(TOUCH) "$(SRC_DIR)/foo/foo file"
+        # Spaces in directories only works with gnu make 4.0 or later
+        ifeq (4.0, $(firstword $(sort 4.0 $(MAKE_VERSION))))
+	  $(MKDIR) -p "$(SRC_DIR)/foo bar"
+	  $(TOUCH) "$(SRC_DIR)/foo bar/foobarfile"
+	  $(TOUCH) "$(SRC_DIR)/foo bar/foo bar file"
+        endif
+	$(LN) -s file "$(SRC_DIR)/link to file"
+	$(TOUCH) $@
+
+$(eval $(call SetupCopyFiles, COPY_1, \
+    SRC := $(SRC_DIR), \
+    DEST := $(DEST_DIR), \
+    FILES := $(call CacheFind, $(SRC_DIR)), \
+))
+
+do-copy1: $(COPY_1)
+
+run-test1: $(OUTPUT_DIR)/_src_created
+	+$(MAKE) -f $(THIS_FILE) do-copy1
+	$(DIFF) -r $(SRC_DIR) $(DEST_DIR)
+
+TEST_TARGETS += run-test1
+
+.PHONY: do-copy1 run-test1
+
+################################################################################
+
+all: $(TEST_TARGETS)
--- a/test/make/TestIdea.gmk	Mon Oct 16 08:47:59 2017 -0700
+++ b/test/make/TestIdea.gmk	Tue Oct 17 14:33:32 2017 -0700
@@ -35,11 +35,11 @@
 
 verify-idea:
 	$(MKDIR) -p $(IDEA_OUTPUT_DIR)
-	$(BASH) $(TOPDIR)/common/bin/idea.sh -o $(IDEA_OUTPUT_DIR)/idea1
-	$(BASH) $(TOPDIR)/common/bin/idea.sh -o $(IDEA_OUTPUT_DIR)/idea2 java.base
-	$(BASH) $(TOPDIR)/common/bin/idea.sh -o $(IDEA_OUTPUT_DIR)/idea3 java.base jdk.compiler
+	MAKEFLAGS= MFLAGS= $(BASH) $(TOPDIR)/bin/idea.sh -o $(IDEA_OUTPUT_DIR)/idea1
+	MAKEFLAGS= MFLAGS= $(BASH) $(TOPDIR)/bin/idea.sh -o $(IDEA_OUTPUT_DIR)/idea2 java.base
+	MAKEFLAGS= MFLAGS= $(BASH) $(TOPDIR)/bin/idea.sh -o $(IDEA_OUTPUT_DIR)/idea3 java.base jdk.compiler
 
-TEST_TARGETS += verify-idea 
+TEST_TARGETS += verify-idea
 
 all: $(TEST_TARGETS)
 
--- a/test/make/TestJavaCompilation.gmk	Mon Oct 16 08:47:59 2017 -0700
+++ b/test/make/TestJavaCompilation.gmk	Tue Oct 17 14:33:32 2017 -0700
@@ -29,6 +29,7 @@
 include MakeBase.gmk
 include JarArchive.gmk
 include JavaCompilation.gmk
+include UtilsForTests.gmk
 
 THIS_FILE := $(TOPDIR)/test/make/TestJavaCompilation.gmk
 DEPS := $(THIS_FILE) \
@@ -90,8 +91,8 @@
 create-jar2: $(OUTPUT_DIR)/_jar1_verified
 TEST_TARGETS += $(OUTPUT_DIR)/_jar1_verified
 
-# Change a source file and call this makefile again to force the jar to be 
-# updated. 
+# Change a source file and call this makefile again to force the jar to be
+# updated.
 $(OUTPUT_DIR)/_jar1_updated: $(OUTPUT_DIR)/_jar1_verified
 	$(ECHO) updated > $(JAR1_SRC_ROOT)/dir1/file1.class
 	$(ECHO) updated > $(JAR1_SRC_ROOT)/META-INF/metafile
@@ -104,6 +105,7 @@
 # Change the manifest file and call this makefile again to force the jar
 # to be updated
 $(OUTPUT_DIR)/_jar1_updated_manifest: $(OUTPUT_DIR)/_jar1_updated
+	$(SLEEP_ON_MAC)
 	$(ECHO) "Test-Attribute: foobar" > $(JAR1_MANIFEST)
 	+$(MAKE) -f $(THIS_FILE) $(BUILD_JAR1)
 	$(RM) -r $(JAR1_UNZIP)
--- a/test/make/TestMake.gmk	Mon Oct 16 08:47:59 2017 -0700
+++ b/test/make/TestMake.gmk	Tue Oct 17 14:33:32 2017 -0700
@@ -33,10 +33,13 @@
 java-compilation:
 	+$(MAKE) -f TestJavaCompilation.gmk $(TEST_SUBTARGET)
 
+copy-files:
+	+$(MAKE) -f TestCopyFiles.gmk $(TEST_SUBTARGET)
+
 test-idea:
 	+$(MAKE) -f TestIdea.gmk $(TEST_SUBTARGET)
 
 
-all: make-base java-compilation test-idea
+all: make-base java-compilation copy-files test-idea
 
-.PHONY: default all make-base java-compilation test-idea
+.PHONY: default all make-base java-compilation copy-files test-idea
--- a/test/make/TestMakeBase.gmk	Mon Oct 16 08:47:59 2017 -0700
+++ b/test/make/TestMakeBase.gmk	Tue Oct 17 14:33:32 2017 -0700
@@ -27,28 +27,13 @@
 
 include $(SPEC)
 include MakeBase.gmk
+include UtilsForTests.gmk
 
 THIS_FILE := $(TOPDIR)/test/make/TestMakeBase.gmk
 DEPS := $(THIS_FILE) \
     $(TOPDIR)/make/common/MakeBase.gmk \
     #
 
-# Assert two strings are equal
-# 1 - Tested value
-# 2 - Exepected value
-# 3 - Error message
-define assert-equals
-  ifneq ($$(strip $1),$$(strip $2))
-    $$(error $3 - Expected >$$(strip $2)< - Got >$$(strip $1)<)
-  endif
-endef
-
-# On macosx, file system timestamps only have 1 second resultion so must add
-# sleeps to properly test dependencies.
-ifeq ($(OPENJDK_BUILD_OS), macosx)
-  SLEEP_ON_MAC := sleep 1
-endif
-
 OUTPUT_DIR := $(TESTMAKE_OUTPUTDIR)/make-base
 $(call MakeDir, $(OUTPUT_DIR))
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/make/UtilsForTests.gmk	Tue Oct 17 14:33:32 2017 -0700
@@ -0,0 +1,42 @@
+#
+# 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.
+#
+
+# This file contains utilities common for multiple test makefiles.
+
+# Assert two strings are equal
+# 1 - Tested value
+# 2 - Exepected value
+# 3 - Error message
+define assert-equals
+  ifneq ($$(strip $1),$$(strip $2))
+    $$(error $3 - Expected >$$(strip $2)< - Got >$$(strip $1)<)
+  endif
+endef
+
+# On macosx, file system timestamps only have 1 second resultion so must add
+# sleeps to properly test dependencies.
+ifeq ($(OPENJDK_BUILD_OS), macosx)
+  SLEEP_ON_MAC := sleep 1
+endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/nashorn/script/basic/JDK-8027302.js	Tue Oct 17 14:33:32 2017 -0700
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8027302: Identifiers containing unicode escapes are not recognized as reserved words
+ *
+ * @test
+ * @run
+ */
+
+// keywords containing escapes
+
+try {
+    eval("v\\u0061r i;");
+    fail("Expected error");
+} catch (e) {
+    Assert.assertTrue(e instanceof SyntaxError);
+}
+
+try {
+    eval("\\u0069f (true) ;");
+    fail("Expected error");
+} catch (e) {
+    Assert.assertTrue(e instanceof ReferenceError); // no SyntaxError in ES5
+}
+
+try {
+    eval("if (true) ; \\u0065lse ;");
+    fail("Expected error");
+} catch (e) {
+    Assert.assertTrue(e instanceof ReferenceError); // no SyntaxError in ES5
+}
+
+try {
+    eval("f\\u0075nction x() {}");
+    fail("Expected error");
+} catch (e) {
+    Assert.assertTrue(e instanceof SyntaxError);
+}
+
+try {
+    eval("var f = f\\u0075nction() {}");
+    fail("Expected error");
+} catch (e) {
+    Assert.assertTrue(e instanceof SyntaxError);
+}
+
+try {
+    eval("var o = { f: f\\u0075nction() {}}");
+    fail("Expected error");
+} catch (e) {
+    Assert.assertTrue(e instanceof SyntaxError);
+}
+
+try {
+    eval("var a = [f\\u0075nction() {}]");
+    fail("Expected error");
+} catch (e) {
+    Assert.assertTrue(e instanceof SyntaxError);
+}
+
+// keywords as identifiers, with and without escapes
+
+try {
+    eval("function break() {}");
+    fail("Expected error");
+} catch (e) {
+    Assert.assertTrue(e instanceof SyntaxError);
+}
+
+try {
+    eval("function bre\\u0061k() {}");
+} catch (e) {
+    fail("Unexpected error");
+}
+
+try {
+    eval("function f(break) {}");
+    fail("Expected error");
+} catch (e) {
+    Assert.assertTrue(e instanceof SyntaxError);
+}
+
+try {
+    eval("function f(bre\\u0061k) {}");
+} catch (e) {
+    fail("Unexpected error");
+}
+
+try {
+    eval("var break = 3");
+    fail("Expected error");
+} catch (e) {
+    Assert.assertTrue(e instanceof SyntaxError);
+}
+
+try {
+    eval("'use strict'; var break = 3");
+    fail("Expected error");
+} catch (e) {
+    Assert.assertTrue(e instanceof SyntaxError);
+}
+
+try {
+    eval("var bre\\u0061k = 3");
+} catch (e) {
+    fail("Unexpected error");
+}
+
+try {
+    eval("'use strict'; var bre\\u0061k = 3");
+} catch (e) {
+    fail("Unexpected error");
+}
+
+try {
+    eval("var package = 3");
+} catch (e) {
+    fail("Unexpected error");
+}
+
+try {
+    eval("'use strict'; var package = 3");
+    fail("Expected error");
+} catch (e) {
+    Assert.assertTrue(e instanceof SyntaxError);
+}
+
+try {
+    eval("var p\\u0061ckage = 3");
+} catch (e) {
+    fail("Unexpected error");
+}
+
+try {
+    eval("'use strict'; var p\\u0061ckage = 3");
+} catch (e) {
+    fail("Unexpected error");
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/nashorn/script/basic/JDK-8068513.js	Tue Oct 17 14:33:32 2017 -0700
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8068513: Adding elements to a javascript 'object' (a map) is slow
+ *
+ * @test
+ * @run
+ */
+
+var map = {};
+var keys = [];
+var values = [];
+
+for (i = 0; i < 5000; i++) {
+    var key = 'key' + i;
+    var value = i;
+    keys.push(key);
+    values.push(value);
+    map[key] = value;
+}
+
+function testAssertions() {
+    Assert.assertTrue(Object.keys(map).length === values.length);
+
+    var c = 0;
+    for (var k in map) {
+        Assert.assertTrue(k === keys[c]);
+        Assert.assertTrue(map[k] === values[c]);
+        c++;
+    }
+
+    Assert.assertTrue(c === values.length);
+}
+
+// redefine existing property
+Object.defineProperty(map, "key2000", { enumerable: true, get: function() { return 'new value 2000' } });
+values[2000] = 'new value 2000';
+
+testAssertions();
+
+// define new property
+Object.defineProperty(map, "defined property", { enumerable: true, configurable: true, get: function() { return 13 } });
+keys.push('defined property');
+values.push(13);
+
+testAssertions();
+
+// delete and redefine
+delete map.key3000;
+map.key3000 = 'new value';
+keys.splice(3000, 1);
+values.splice(3000, 1);
+keys.push('key3000');
+values.push('new value');
+
+testAssertions();
+
+// delete all properties
+while (values.length > 0) {
+    values.pop();
+    delete map[keys.pop()];
+}
+
+testAssertions();
+
+// add a few new ones
+for (var i = 0; i < 1000; i++) {
+    keys.push('k' + i);
+    values.push('v' + i);
+    map['k' + i] = 'v' + i;
+}
+
+testAssertions();
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/nashorn/script/basic/es6/JDK-8027302.js	Tue Oct 17 14:33:32 2017 -0700
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8027302: Identifiers containing unicode escapes are not recognized as reserved words
+ *
+ * @test
+ * @run
+ * @option --language=es6
+ */
+
+// keywords containing escapes
+
+try {
+    eval("v\\u0061r i;");
+    fail("Expected error");
+} catch (e) {
+    Assert.assertTrue(e instanceof SyntaxError);
+}
+
+try {
+    eval("\\u0069f (true) ;");
+    fail("Expected error");
+} catch (e) {
+    Assert.assertTrue(e instanceof SyntaxError);
+}
+
+try {
+    eval("if (true) ; \\u0065lse ;");
+    fail("Expected error");
+} catch (e) {
+    Assert.assertTrue(e instanceof SyntaxError);
+}
+
+try {
+    eval("f\\u0075nction x() {}");
+    fail("Expected error");
+} catch (e) {
+    Assert.assertTrue(e instanceof SyntaxError);
+}
+
+try {
+    eval("var f = f\\u0075nction() {}");
+    fail("Expected error");
+} catch (e) {
+    Assert.assertTrue(e instanceof SyntaxError);
+}
+
+try {
+    eval("var o = { f: f\\u0075nction() {}}");
+    fail("Expected error");
+} catch (e) {
+    Assert.assertTrue(e instanceof SyntaxError);
+}
+
+try {
+    eval("var a = [f\\u0075nction() {}]");
+    fail("Expected error");
+} catch (e) {
+    Assert.assertTrue(e instanceof SyntaxError);
+}
+
+// keywords as identifiers, with and without escapes
+
+try {
+    eval("function break() {}");
+    fail("Expected error");
+} catch (e) {
+    Assert.assertTrue(e instanceof SyntaxError);
+}
+
+try {
+    eval("function bre\\u0061k() {}");
+    fail("Expected error");
+} catch (e) {
+    Assert.assertTrue(e instanceof SyntaxError);
+}
+
+try {
+    eval("function f(break) {}");
+    fail("Expected error");
+} catch (e) {
+    Assert.assertTrue(e instanceof SyntaxError);
+}
+
+try {
+    eval("function f(bre\\u0061k) {}");
+    fail("Expected error");
+} catch (e) {
+    Assert.assertTrue(e instanceof SyntaxError);
+}
+
+try {
+    eval("var break = 3");
+    fail("Expected error");
+} catch (e) {
+    Assert.assertTrue(e instanceof SyntaxError);
+}
+
+try {
+    eval("'use strict'; var break = 3");
+    fail("Expected error");
+} catch (e) {
+    Assert.assertTrue(e instanceof SyntaxError);
+}
+
+try {
+    eval("var bre\\u0061k = 3");
+    fail("Expected error");
+} catch (e) {
+    Assert.assertTrue(e instanceof SyntaxError);
+}
+
+try {
+    eval("'use strict'; var bre\\u0061k = 3");
+    fail("Expected error");
+} catch (e) {
+    Assert.assertTrue(e instanceof SyntaxError);
+}
+
+try {
+    eval("var package = 3");
+} catch (e) {
+    fail("Unexpected error");
+}
+
+try {
+    eval("'use strict'; var package = 3");
+    fail("Expected error");
+} catch (e) {
+    Assert.assertTrue(e instanceof SyntaxError);
+}
+
+try {
+    eval("var p\\u0061ckage = 3");
+} catch (e) {
+    fail("Unexpected error");
+}
+
+try {
+    eval("'use strict'; var p\\u0061ckage = 3");
+    fail("Expected error");
+} catch (e) {
+    Assert.assertTrue(e instanceof SyntaxError);
+}
+