Merge ihse-cflags-rewrite-branch
authorihse
Mon, 19 Feb 2018 11:08:33 +0100
branchihse-cflags-rewrite-branch
changeset 56146 d019a80c41c0
parent 56145 718aa4c360c4 (current diff)
parent 48912 01237b276b8b (diff)
child 56147 fd62484132bc
Merge
make/autoconf/flags-cflags.m4
make/autoconf/flags-other.m4
make/autoconf/flags.m4
make/autoconf/spec.gmk.in
--- a/.hgtags	Fri Feb 16 20:55:07 2018 +0100
+++ b/.hgtags	Mon Feb 19 11:08:33 2018 +0100
@@ -469,3 +469,4 @@
 3eae36c6baa5f916a3024cf1513e22357e00185d jdk-10+41
 4b62b815b4f49970b91a952929cf50115c263cb3 jdk-10+42
 107413b070b92c88bde6230ceb4a19b579781068 jdk-10+43
+dfa46cfe56346884a61efdc30dc50f7505d66761 jdk-11+1
--- a/make/Images.gmk	Fri Feb 16 20:55:07 2018 +0100
+++ b/make/Images.gmk	Mon Feb 19 11:08:33 2018 +0100
@@ -134,18 +134,22 @@
     $(call DependOnVariable, JDK_MODULES_LIST) $(BASE_RELEASE_FILE)
 	$(ECHO) Creating jdk jimage
 	$(RM) -r $(JDK_IMAGE_DIR)
-	$(JLINK_TOOL) --add-modules $(JDK_MODULES_LIST) \
-	    $(JLINK_JDK_EXTRA_OPTS) \
-	    --output $(JDK_IMAGE_DIR)
+	$(call ExecuteWithLog, $(SUPPORT_OUTPUTDIR)/images/jdk, \
+	    $(JLINK_TOOL) --add-modules $(JDK_MODULES_LIST) \
+	        $(JLINK_JDK_EXTRA_OPTS) \
+	        --output $(JDK_IMAGE_DIR) \
+	)
 	$(TOUCH) $@
 
 $(JRE_IMAGE_DIR)/$(JIMAGE_TARGET_FILE): $(JMODS) \
     $(call DependOnVariable, JRE_MODULES_LIST) $(BASE_RELEASE_FILE)
 	$(ECHO) Creating jre jimage
 	$(RM) -r $(JRE_IMAGE_DIR)
-	$(JLINK_TOOL) --add-modules $(JRE_MODULES_LIST) \
-	    $(JLINK_JRE_EXTRA_OPTS) \
-	    --output $(JRE_IMAGE_DIR)
+	$(call ExecuteWithLog, $(SUPPORT_OUTPUTDIR)/images/jre, \
+	    $(JLINK_TOOL) --add-modules $(JRE_MODULES_LIST) \
+	        $(JLINK_JRE_EXTRA_OPTS) \
+	        --output $(JRE_IMAGE_DIR) \
+	)
 	$(TOUCH) $@
 
 
@@ -153,27 +157,33 @@
     $(call DependOnVariable, JRE_COMPACT1_MODULES_LIST) $(BASE_RELEASE_FILE)
 	$(ECHO) Creating jre compact1 jimage
 	$(RM) -r $(JRE_COMPACT1_IMAGE_DIR)
-	$(JLINK_TOOL) --add-modules $(JRE_COMPACT1_MODULES_LIST) \
-	    $(JLINK_JRE_EXTRA_OPTS) \
-	    --output $(JRE_COMPACT1_IMAGE_DIR)
+	$(call ExecuteWithLog, $(SUPPORT_OUTPUTDIR)/images/jre_compact1, \
+	    $(JLINK_TOOL) --add-modules $(JRE_COMPACT1_MODULES_LIST) \
+	        $(JLINK_JRE_EXTRA_OPTS) \
+	        --output $(JRE_COMPACT1_IMAGE_DIR) \
+	)
 	$(TOUCH) $@
 
 $(JRE_COMPACT2_IMAGE_DIR)/$(JIMAGE_TARGET_FILE): $(JMODS) \
     $(call DependOnVariable, JRE_COMPACT2_MODULES_LIST) $(BASE_RELEASE_FILE)
 	$(ECHO) Creating jre compact2 jimage
 	$(RM) -r $(JRE_COMPACT2_IMAGE_DIR)
-	$(JLINK_TOOL) --add-modules $(JRE_COMPACT2_MODULES_LIST) \
-	    $(JLINK_JRE_EXTRA_OPTS) \
-	    --output $(JRE_COMPACT2_IMAGE_DIR)
+	$(call ExecuteWithLog, $(SUPPORT_OUTPUTDIR)/images/jre_compact2, \
+	    $(JLINK_TOOL) --add-modules $(JRE_COMPACT2_MODULES_LIST) \
+	        $(JLINK_JRE_EXTRA_OPTS) \
+	        --output $(JRE_COMPACT2_IMAGE_DIR) \
+	)
 	$(TOUCH) $@
 
 $(JRE_COMPACT3_IMAGE_DIR)/$(JIMAGE_TARGET_FILE): $(JMODS) \
     $(call DependOnVariable, JRE_COMPACT3_MODULES_LIST) $(BASE_RELEASE_FILE)
 	$(ECHO) Creating jre compact3 jimage
 	$(RM) -r $(JRE_COMPACT3_IMAGE_DIR)
-	$(JLINK_TOOL) --add-modules $(JRE_COMPACT3_MODULES_LIST) \
-	    $(JLINK_JRE_EXTRA_OPTS) \
-	    --output $(JRE_COMPACT3_IMAGE_DIR)
+	$(call ExecuteWithLog, $(SUPPORT_OUTPUTDIR)/images/jre_compact3, \
+	    $(JLINK_TOOL) --add-modules $(JRE_COMPACT3_MODULES_LIST) \
+	        $(JLINK_JRE_EXTRA_OPTS) \
+	        --output $(JRE_COMPACT3_IMAGE_DIR) \
+	)
 	$(TOUCH) $@
 
 TOOL_JRE_TARGETS := $(JRE_IMAGE_DIR)/$(JIMAGE_TARGET_FILE)
--- a/make/InitSupport.gmk	Fri Feb 16 20:55:07 2018 +0100
+++ b/make/InitSupport.gmk	Mon Feb 19 11:08:33 2018 +0100
@@ -361,6 +361,12 @@
 
   BUILD_LOG_PIPE := > >($(TEE) -a $(BUILD_LOG)) 2> >($(TEE) -a $(BUILD_LOG) >&2) && wait
 
+  ifneq ($(CUSTOM_ROOT), )
+    topdir=$(CUSTOM_ROOT)
+  else
+    topdir=$(TOPDIR)
+  endif
+
   # Parse COMPARE_BUILD into COMPARE_BUILD_*
   # Syntax: COMPARE_BUILD=CONF=<configure options>:PATCH=<patch file>:
   #         MAKE=<make targets>:COMP_OPTS=<compare script options>:
@@ -373,7 +379,7 @@
   # FAIL can be set to false to have the return value of compare be ignored.
   define ParseCompareBuild
     ifneq ($$(COMPARE_BUILD), )
-      COMPARE_BUILD_OUTPUTDIR := $(TOPDIR)/build/compare-build/$(CONF_NAME)
+      COMPARE_BUILD_OUTPUTDIR := $(topdir)/build/compare-build/$(CONF_NAME)
       COMPARE_BUILD_FAIL := true
 
       ifneq ($$(findstring :, $$(COMPARE_BUILD)), )
@@ -412,9 +418,9 @@
         endif
       endif
       ifneq ($$(COMPARE_BUILD_PATCH), )
-        ifneq ($$(wildcard $$(TOPDIR)/$$(COMPARE_BUILD_PATCH)), )
+        ifneq ($$(wildcard $$(topdir)/$$(COMPARE_BUILD_PATCH)), )
           # Assume relative path, if file exists
-          COMPARE_BUILD_PATCH := $$(wildcard $$(TOPDIR)/$$(COMPARE_BUILD_PATCH))
+          COMPARE_BUILD_PATCH := $$(wildcard $$(topdir)/$$(COMPARE_BUILD_PATCH))
         else ifeq ($$(wildcard $$(COMPARE_BUILD_PATCH)), )
           $$(error Patch file $$(COMPARE_BUILD_PATCH) does not exist)
         endif
@@ -431,9 +437,9 @@
         # Apply patch, if any
 	$(if $(COMPARE_BUILD_PATCH), $(PATCH) -p1 < $(COMPARE_BUILD_PATCH))
         # Move the first build away temporarily
-	$(RM) -r $(TOPDIR)/build/.compare-build-temp
-	$(MKDIR) -p $(TOPDIR)/build/.compare-build-temp
-	$(MV) $(OUTPUTDIR) $(TOPDIR)/build/.compare-build-temp
+	$(RM) -r $(topdir)/build/.compare-build-temp
+	$(MKDIR) -p $(topdir)/build/.compare-build-temp
+	$(MV) $(OUTPUTDIR) $(topdir)/build/.compare-build-temp
         # Restore an old compare-build, or create a new compare-build directory.
 	if test -d $(COMPARE_BUILD_OUTPUTDIR); then \
 	  $(MV) $(COMPARE_BUILD_OUTPUTDIR) $(OUTPUTDIR); \
@@ -443,7 +449,7 @@
         # Re-run configure with the same arguments (and possibly some additional),
         # must be done after patching.
 	( cd $(OUTPUTDIR) && PATH="$(ORIGINAL_PATH)" \
-	    $(BASH) $(TOPDIR)/configure $(CONFIGURE_COMMAND_LINE) $(COMPARE_BUILD_CONF))
+	    $(BASH) $(topdir)/configure $(CONFIGURE_COMMAND_LINE) $(COMPARE_BUILD_CONF))
   endef
 
   # Cleanup after a compare build
@@ -451,10 +457,10 @@
         # If running with a COMPARE_BUILD patch, reverse-apply it
 	$(if $(COMPARE_BUILD_PATCH), $(PATCH) -R -p1 < $(COMPARE_BUILD_PATCH))
         # Move this build away and restore the original build
-	$(MKDIR) -p $(TOPDIR)/build/compare-build
+	$(MKDIR) -p $(topdir)/build/compare-build
 	$(MV) $(OUTPUTDIR) $(COMPARE_BUILD_OUTPUTDIR)
-	$(MV) $(TOPDIR)/build/.compare-build-temp/$(CONF_NAME) $(OUTPUTDIR)
-	$(RM) -r $(TOPDIR)/build/.compare-build-temp
+	$(MV) $(topdir)/build/.compare-build-temp/$(CONF_NAME) $(OUTPUTDIR)
+	$(RM) -r $(topdir)/build/.compare-build-temp
   endef
 
   # Do the actual comparison of two builds
--- a/make/autoconf/basics.m4	Fri Feb 16 20:55:07 2018 +0100
+++ b/make/autoconf/basics.m4	Mon Feb 19 11:08:33 2018 +0100
@@ -258,16 +258,12 @@
     if test "x$READLINK_TESTED" != yes; then
       # On MacOSX there is a readlink tool with a different
       # purpose than the GNU readlink tool. Check the found readlink.
-      ISGNU=`$READLINK --version 2>&1 | $GREP GNU`
-      if test "x$ISGNU" = x; then
-        # A readlink that we do not know how to use.
-        # Are there other non-GNU readlinks out there?
-        READLINK_TESTED=yes
-        READLINK=
-      fi
+      READLINK_ISGNU=`$READLINK --version 2>&1 | $GREP GNU`
+      # If READLINK_ISGNU is empty, then it's a non-GNU readlink. Don't use it.
+      READLINK_TESTED=yes
     fi
 
-    if test "x$READLINK" != x; then
+    if test "x$READLINK" != x && "x$READLINK_ISGNU" != x; then
       $1=`$READLINK -f [$]$1`
     else
       # Save the current directory for restoring afterwards
@@ -494,6 +490,7 @@
   BASIC_REQUIRE_PROGS(MV, mv)
   BASIC_REQUIRE_PROGS(NAWK, [nawk gawk awk])
   BASIC_REQUIRE_PROGS(PRINTF, printf)
+  BASIC_REQUIRE_PROGS(READLINK, [greadlink readlink])
   BASIC_REQUIRE_PROGS(RM, rm)
   BASIC_REQUIRE_PROGS(RMDIR, rmdir)
   BASIC_REQUIRE_PROGS(SH, sh)
@@ -525,7 +522,6 @@
 
   # These are not required on all platforms
   BASIC_PATH_PROGS(CYGPATH, cygpath)
-  BASIC_PATH_PROGS(READLINK, [greadlink readlink])
   BASIC_PATH_PROGS(DF, df)
   BASIC_PATH_PROGS(CPIO, [cpio bsdcpio])
   BASIC_PATH_PROGS(NICE, nice)
--- a/make/autoconf/flags.m4	Fri Feb 16 20:55:07 2018 +0100
+++ b/make/autoconf/flags.m4	Mon Feb 19 11:08:33 2018 +0100
@@ -175,6 +175,16 @@
         $1SYSROOT_CFLAGS="-I-xbuiltin -I[$]$1SYSROOT/usr/include"
         $1SYSROOT_LDFLAGS="-L[$]$1SYSROOT/usr/lib$OPENJDK_TARGET_CPU_ISADIR \
             -L[$]$1SYSROOT/lib$OPENJDK_TARGET_CPU_ISADIR"
+        # If the devkit contains the ld linker, make sure we use it.
+        AC_PATH_PROG(SOLARIS_LD, ld, , $DEVKIT_TOOLCHAIN_PATH:$DEVKIT_EXTRA_PATH)
+        # Make sure this ld is runnable.
+        if test -f "$SOLARIS_LD"; then
+          if "$SOLARIS_LD" -V > /dev/null 2> /dev/null; then
+            $1SYSROOT_LDFLAGS="[$]$1SYSROOT_LDFLAGS -Yl,$(dirname $SOLARIS_LD)"
+          else
+            AC_MSG_WARN([Could not run $SOLARIS_LD found in devkit, reverting to system ld])
+          fi
+        fi
       fi
     elif test "x$TOOLCHAIN_TYPE" = xgcc; then
       $1SYSROOT_CFLAGS="--sysroot=[$]$1SYSROOT"
--- a/make/autoconf/spec.gmk.in	Fri Feb 16 20:55:07 2018 +0100
+++ b/make/autoconf/spec.gmk.in	Mon Feb 19 11:08:33 2018 +0100
@@ -685,6 +685,7 @@
 PANDOC:=@FIXPATH@ @PANDOC@
 PATCH:=@PATCH@
 PRINTF:=@PRINTF@
+READLINK:=@READLINK@
 RM:=@RM@
 RMDIR:=@RMDIR@
 SED:=@SED@
--- a/make/common/MakeBase.gmk	Fri Feb 16 20:55:07 2018 +0100
+++ b/make/common/MakeBase.gmk	Mon Feb 19 11:08:33 2018 +0100
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2018, 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
@@ -545,8 +545,18 @@
   define install-file
 	$(call MakeTargetDir)
 	$(RM) '$(call DecodeSpace, $@)'
-	$(CP) -fRP '$(call DecodeSpace, $<)' '$(call DecodeSpace, $@)'
-	if [ -n "`$(XATTR) -ls '$(call DecodeSpace, $@)'`" ]; then $(XATTR) -cs '$(call DecodeSpace, $@)'; fi
+        # Work around a weirdness with cp on Macosx. When copying a symlink, if
+        # the target of the link is write protected (e.g. 444), cp will add
+        # write permission for the user on the target file (644). Avoid this by
+        # using ln to create a new link instead.
+	if [ -h '$(call DecodeSpace, $<)' ]; then \
+	  $(LN) -s "`$(READLINK) '$(call DecodeSpace, $<)'`" '$(call DecodeSpace, $@)'; \
+	else \
+	  $(CP) -fRP '$(call DecodeSpace, $<)' '$(call DecodeSpace, $@)'; \
+	fi
+	if [ -n "`$(XATTR) -ls '$(call DecodeSpace, $@)'`" ]; then \
+	  $(XATTR) -cs '$(call DecodeSpace, $@)'; \
+	fi
   endef
 else
   define install-file
@@ -1000,6 +1010,7 @@
 # Param 2 - The command to run
 ExecuteWithLog = \
   $(call LogCmdlines, Exececuting: [$(strip $2)]) \
+  $(call MakeDir, $(dir $(strip $1))) \
   $(call WriteFile, $2, $(strip $1).cmdline) \
   ( $(strip $2) > >($(TEE) $(strip $1).log) 2> >($(TEE) $(strip $1).log >&2) || \
       ( exitcode=$(DOLLAR)? && \
--- a/make/conf/jib-profiles.js	Fri Feb 16 20:55:07 2018 +0100
+++ b/make/conf/jib-profiles.js	Mon Feb 19 11:08:33 2018 +0100
@@ -768,7 +768,7 @@
         linux_x64: "gcc4.9.2-OEL6.4+1.2",
         macosx_x64: "Xcode6.3-MacOSX10.9+1.0",
         solaris_x64: "SS12u4-Solaris11u1+1.0",
-        solaris_sparcv9: "SS12u4-Solaris11u1+1.0",
+        solaris_sparcv9: "SS12u4-Solaris11u1+1.1",
         windows_x64: "VS2013SP4+1.0",
         linux_aarch64: "gcc-linaro-aarch64-linux-gnu-4.8-2013.11_linux+1.0",
         linux_arm: (input.profile != null && input.profile.indexOf("hflt") >= 0
--- a/make/devkit/createSolarisDevkit.sh	Fri Feb 16 20:55:07 2018 +0100
+++ b/make/devkit/createSolarisDevkit.sh	Mon Feb 19 11:08:33 2018 +0100
@@ -73,7 +73,8 @@
 DEVKIT_ROOT=${BUILD_DIR}/${DEVKIT_NAME}
 BUNDLE_NAME=${DEVKIT_NAME}.tar.gz
 BUNDLE=${BUILD_DIR}/${BUNDLE_NAME}
-INSTALL_ROOT=${BUILD_DIR}/install-root
+INSTALL_ROOT=${BUILD_DIR}/install-root-$SOLARIS_VERSION
+INSTALL_ROOT_TOOLS=${BUILD_DIR}/install-root-tools-$SOLARIS_VERSION
 SYSROOT=${DEVKIT_ROOT}/sysroot
 SOLARIS_STUDIO_SUBDIR=SS${SOLARIS_STUDIO_VERSION}
 SOLARIS_STUDIO_DIR=${DEVKIT_ROOT}/${SOLARIS_STUDIO_SUBDIR}
@@ -92,17 +93,27 @@
   echo "Skipping installing packages"
 fi
 
+# Since we have implicitly been running 11.2 tools for a long time, we need
+# to pick them for the tools dir in the devkit. Create a separate install-root
+# for it.
+if [ ! -d $INSTALL_ROOT_TOOLS ]; then
+  echo "Creating $INSTALL_ROOT_TOOLS and installing packages"
+  pkg image-create $INSTALL_ROOT_TOOLS
+  pkg -R $INSTALL_ROOT_TOOLS set-publisher -P -g ${PUBLISHER_URI} solaris
+  sudo pkg -R $INSTALL_ROOT_TOOLS install --accept \
+      entire@0.5.11-0.175.2.5.0.5.0 \
+      system/linker \
+      developer/base-developer-utilities \
+      developer/gnu-binutils
+else
+  echo "Skipping installing tools packages"
+fi
+
 if [ ! -d $SYSROOT ]; then
   echo "Copying from $INSTALL_ROOT to $SYSROOT"
   mkdir -p $SYSROOT
   cp -rH $INSTALL_ROOT/lib $SYSROOT/
-  mkdir $SYSROOT/usr $DEVKIT_ROOT/gnu
-  # Some of the tools in sysroot are needed in the OpenJDK build but cannot be
-  # run from their current location due to relative runtime paths in the
-  # binaries. Move the sysroot/usr/bin directory to the outer bin and have them
-  # be runnable from there to force them to link to the system libraries
-  cp -rH $INSTALL_ROOT/usr/bin $DEVKIT_ROOT
-  cp -rH $INSTALL_ROOT/usr/gnu/bin $DEVKIT_ROOT/gnu/
+  mkdir $SYSROOT/usr
   cp -rH $INSTALL_ROOT/usr/lib $SYSROOT/usr/
   cp -rH $INSTALL_ROOT/usr/include $SYSROOT/usr/
   pkg -R $INSTALL_ROOT list > $SYSROOT/pkg-list.txt
@@ -110,10 +121,36 @@
   echo "Skipping copying to $SYSROOT"
 fi
 
+if [ ! -d $DEVKIT_ROOT/tools ]; then
+  echo "Copying from $INSTALL_ROOT_TOOLS to $DEVKIT_ROOT/tools"
+  # Some of the tools in sysroot are needed in the OpenJDK build. We need
+  # to copy them into a tools dir, including their specific libraries.
+  mkdir -p $DEVKIT_ROOT/tools/usr/bin/sparcv9 $DEVKIT_ROOT/tools/lib/sparcv9 \
+      $DEVKIT_ROOT/tools/usr/gnu/bin
+  cp $INSTALL_ROOT_TOOLS/usr/bin/{ar,nm,strip,ld,ldd} \
+       $DEVKIT_ROOT/tools/usr/bin/
+  cp $INSTALL_ROOT_TOOLS/usr/bin/sparcv9/{ar,nm,strip,ld,ldd} \
+       $DEVKIT_ROOT/tools/usr/bin/sparcv9/
+  cp $INSTALL_ROOT_TOOLS/usr/sbin/dtrace $DEVKIT_ROOT/tools/usr/bin/
+  cp $INSTALL_ROOT_TOOLS/usr/sbin/sparcv9/dtrace $DEVKIT_ROOT/tools/usr/bin/sparcv9/
+  cp -rH $INSTALL_ROOT_TOOLS/usr/gnu/bin/* $DEVKIT_ROOT/tools/usr/gnu/bin/
+  cp $INSTALL_ROOT_TOOLS/lib/{libelf.so*,libld.so*,liblddbg.so*} \
+      $DEVKIT_ROOT/tools/lib/
+  cp $INSTALL_ROOT_TOOLS/lib/sparcv9/{libelf.so*,libld.so*,liblddbg.so*} \
+      $DEVKIT_ROOT/tools/lib/sparcv9/
+  for t in $(ls $DEVKIT_ROOT/tools/usr/gnu/bin); do
+    if [ -f $DEVKIT_ROOT/tools/usr/gnu/bin/$t ]; then
+      ln -s ../gnu/bin/$t $DEVKIT_ROOT/tools/usr/bin/g$t
+    fi
+  done
+else
+  echo "Skipping copying to tools dir $DEVKIT_ROOT/tools"
+fi
+
 if [ ! -d $SOLARIS_STUDIO_DIR ]; then
   echo "Copying Solaris Studio from $SOLARIS_STUDIO_SRC"
-  cp -rH $SOLARIS_STUDIO_SRC ${SOLARIS_STUDIO_DIR%/*}
-  mv ${SOLARIS_STUDIO_DIR%/*}/${SOLARIS_STUDIO_SRC##*/} $SOLARIS_STUDIO_DIR
+  mkdir -p ${SOLARIS_STUDIO_DIR}
+  cp -rH $SOLARIS_STUDIO_SRC/. ${SOLARIS_STUDIO_DIR}/
   # Solaris Studio 12.4 requires /lib/libmmheap.so.1 to run, but this lib is not
   # installed by default on all Solaris systems. Sneak it in from the sysroot to
   # make it run OOTB on more systems.
@@ -123,10 +160,9 @@
 fi
 
 echo "Copying gnu make to $DEVKIT_ROOT/bin"
-mkdir -p $DEVKIT_ROOT/bin
-cp $GNU_MAKE $DEVKIT_ROOT/bin/
-if [ ! -e $DEVKIT_ROOT/bin/gmake ]; then
-  ln -s make $DEVKIT_ROOT/bin/gmake
+cp $GNU_MAKE $DEVKIT_ROOT/tools/usr/bin/
+if [ ! -e $DEVKIT_ROOT/tools/usr/bin/gmake ]; then
+  ln -s make $DEVKIT_ROOT/tools/usr/bin/gmake
 fi
 
 # Create the devkit.info file
@@ -136,7 +172,7 @@
 echo "# This file describes to configure how to interpret the contents of this devkit" >> $INFO_FILE
 echo "DEVKIT_NAME=\"Solaris Studio $SOLARIS_STUDIO_VERSION - Solaris $SOLARIS_VERSION - $ARCH\"" >> $INFO_FILE
 echo "DEVKIT_TOOLCHAIN_PATH=\"\$DEVKIT_ROOT/$SOLARIS_STUDIO_SUBDIR/bin:\$DEVKIT_ROOT/bin\"" >> $INFO_FILE
-echo "DEVKIT_EXTRA_PATH=\"\$DEVKIT_ROOT/bin\"" >> $INFO_FILE
+echo "DEVKIT_EXTRA_PATH=\"\$DEVKIT_ROOT/tools/usr/bin\"" >> $INFO_FILE
 echo "DEVKIT_SYSROOT=\"\$DEVKIT_ROOT/sysroot\"" >> $INFO_FILE
 
 if [ ! -e $BUNDLE ]; then
--- a/make/launcher/Launcher-jdk.jcmd.gmk	Fri Feb 16 20:55:07 2018 +0100
+++ b/make/launcher/Launcher-jdk.jcmd.gmk	Mon Feb 19 11:08:33 2018 +0100
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2018, 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
@@ -60,3 +60,6 @@
 $(eval $(call SetupBuildLauncher, jcmd, \
     MAIN_CLASS := sun.tools.jcmd.JCmd, \
 ))
+
+# Hook to include the corresponding custom file, if present.
+$(eval $(call IncludeCustomExtension, launcher/Launcher-jdk.jcmd-post.gmk))
--- a/make/launcher/Launcher-jdk.jstatd.gmk	Fri Feb 16 20:55:07 2018 +0100
+++ b/make/launcher/Launcher-jdk.jstatd.gmk	Mon Feb 19 11:08:33 2018 +0100
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -28,3 +28,6 @@
 $(eval $(call SetupBuildLauncher, jstatd, \
     MAIN_CLASS := sun.tools.jstatd.Jstatd, \
 ))
+
+# Hook to include the corresponding custom file, if present.
+$(eval $(call IncludeCustomExtension, launcher/Launcher-jdk.jstatd-post.gmk))
--- a/make/scripts/compare.sh	Fri Feb 16 20:55:07 2018 +0100
+++ b/make/scripts/compare.sh	Mon Feb 19 11:08:33 2018 +0100
@@ -1,6 +1,6 @@
 #!/bin/bash
 #
-# Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2012, 2018, 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
@@ -94,7 +94,7 @@
             $SED -e '/[<>] \* from.*\.idl/d' \
                  -e '/[<>] .*[0-9]\{4\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}-b[0-9]\{2\}.*/d' \
                  -e '/[<>] .*[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{6\}.*/d' \
-                 -e '/[<>] \*.*[0-9]\{4\} [0-9][0-9]*:[0-9]\{2\}:[0-9]\{2\}.*/d' \
+                 -e '/[<>] \*.*[0-9]\{4\} \(at \)*[0-9][0-9]*:[0-9]\{2\}:[0-9]\{2\}.*/d' \
                  -e '/\/\/ Generated from input file.*/d' \
                  -e '/\/\/ This file was generated AUTOMATICALLY from a template file.*/d' \
                  -e '/\/\/ java GenerateCharacter.*/d')
@@ -102,9 +102,12 @@
     # Ignore date strings in class files.
     # Anonymous lambda classes get randomly assigned counters in their names.
     if test "x$SUFFIX" = "xclass"; then
-        if [ "$NAME" = "SystemModules.class" ]; then
-            # The SystemModules.class is not comparable. The way it is generated is
-            # too random. It can even be of different size for no apparent reason.
+        if [ "$NAME" = "SystemModules\$all.class" ] \
+           || [ "$NAME" = "SystemModules\$default.class" ]; then
+            # The SystemModules\$*.classes are not comparable as they contain the
+            # module hashes which would require a whole other level of
+            # reproducible builds to get reproducible. There is also random
+            # order of map initialization.
             TMP=""
         elif [ "$NAME" = "module-info.class" ]; then
             # The module-info.class have several issues with random ordering of
@@ -654,7 +657,6 @@
         # pdb files.
         PDB_DIRS="$(ls -d \
             {$OTHER,$THIS}/support/modules_{cmds,libs}/{*,*/*} \
-            {$OTHER,$THIS}/support/demos/image/jvmti/*/lib \
             {$OTHER,$THIS}/support/native/java.base/java_objs \
             )"
         export _NT_SYMBOL_PATH="$(echo $PDB_DIRS | tr ' ' ';')"
@@ -1001,6 +1003,12 @@
         -o -name '*.dll' -o -name '*.obj' -o -name '*.o' -o -name '*.a' \
         -o -name '*.cpl' \) | $SORT | $FILTER)
 
+    # On macos, filter out the dSYM debug symbols files as they are also
+    # named *.dylib.
+    if [ "$OPENJDK_TARGET_OS" = "macosx" ]; then
+        LIBS=$(echo "$LIBS" | $GREP -v '\.dSYM/')
+    fi
+
     if [ -n "$LIBS" ]; then
         echo Libraries...
         print_binary_diff_header
@@ -1041,7 +1049,7 @@
             -o -name '*.jfc' -o -name '*.dat'  -o -name 'release' -o -name '*.dir'\
             -o -name '*.sym' -o -name '*.idl' -o -name '*.h' -o -name '*.access' \
             -o -name '*.template' -o -name '*.policy' -o -name '*.security' \
-            -o -name 'COPYRIGHT' -o -name '*.1' \
+            -o -name 'COPYRIGHT' -o -name '*.1' -o -name '*.debuginfo' \
             -o -name 'classlist' \) | $SORT | $FILTER)
     fi
 
@@ -1219,7 +1227,7 @@
   STRIP_ALL=false
 fi
 
-COMPARE_ROOT=/tmp/cimages.$USER
+COMPARE_ROOT=$OUTPUTDIR/compare-support
 if [ "$CLEAN_OUTPUT" = "true" ]; then
     echo Cleaning old output in $COMPARE_ROOT.
     $RM -rf $COMPARE_ROOT
--- a/make/scripts/compare_exceptions.sh.incl	Fri Feb 16 20:55:07 2018 +0100
+++ b/make/scripts/compare_exceptions.sh.incl	Mon Feb 19 11:08:33 2018 +0100
@@ -428,8 +428,13 @@
       ./bin/xjc.exe
       "
 
+  SORT_SYMBOLS="
+      ./bin/fontmanager.dll
+      "
+
   ACCEPTED_DIS_DIFF="
       ./bin/jabswitch.exe
+      ./bin/fontmanager.dll
       "
 
   if [ "$OPENJDK_TARGET_CPU" = "x86" ]; then
--- a/src/java.base/share/classes/java/lang/Thread.java	Fri Feb 16 20:55:07 2018 +0100
+++ b/src/java.base/share/classes/java/lang/Thread.java	Mon Feb 19 11:08:33 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2018, 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
@@ -150,9 +150,6 @@
     private Thread         threadQ;
     private long           eetop;
 
-    /* Whether or not to single_step this thread. */
-    private boolean     single_step;
-
     /* Whether or not the thread is a daemon thread. */
     private boolean     daemon = false;
 
--- a/src/java.base/share/classes/java/lang/invoke/BootstrapMethodInvoker.java	Fri Feb 16 20:55:07 2018 +0100
+++ b/src/java.base/share/classes/java/lang/invoke/BootstrapMethodInvoker.java	Mon Feb 19 11:08:33 2018 +0100
@@ -67,12 +67,12 @@
             // VM is pushing arguments at us
             pullModeBSM = null;
             if (pullMode) {
-                bootstrapMethod = Adapters.pushMePullYou(bootstrapMethod, true);
+                bootstrapMethod = pushMePullYou(bootstrapMethod, true);
             }
         } else {
             // VM wants us to pull args from it
             pullModeBSM = pullMode ? bootstrapMethod :
-                    Adapters.pushMePullYou(bootstrapMethod, false);
+                    pushMePullYou(bootstrapMethod, false);
             bootstrapMethod = null;
         }
         try {
@@ -237,9 +237,10 @@
             // give up at first null and grab the rest in one big block
             if (i >= end)  return i;
             Object[] temp = new Object[end - i];
-            if (TRACE_METHOD_LINKAGE)
-                System.out.println("resolving more BSM arguments: "+
+            if (TRACE_METHOD_LINKAGE) {
+                System.out.println("resolving more BSM arguments: " +
                         Arrays.asList(caller.getSimpleName(), Arrays.toString(indexInfo), i, end));
+            }
             copyOutBootstrapArguments(caller, indexInfo,
                                       i, end, temp, 0,
                                       true, null);
@@ -285,9 +286,10 @@
         private void prefetchIntoCache(int i, int pfLimit) {
             if (pfLimit <= i)  return;  // corner case
             Object[] temp = new Object[pfLimit - i];
-            if (TRACE_METHOD_LINKAGE)
-                System.out.println("prefetching BSM arguments: "+
+            if (TRACE_METHOD_LINKAGE) {
+                System.out.println("prefetching BSM arguments: " +
                         Arrays.asList(caller.getSimpleName(), Arrays.toString(indexInfo), i, pfLimit));
+            }
             copyOutBootstrapArguments(caller, indexInfo,
                                       i, pfLimit, temp, 0,
                                       false, NOT_PRESENT);
@@ -301,7 +303,7 @@
     }
 
     /*non-public*/ static final
-    class Adapters {
+    class PushAdapter {
         // skeleton for push-mode BSM which wraps a pull-mode BSM:
         static Object pushToBootstrapMethod(MethodHandle pullModeBSM,
                                             MethodHandles.Lookup lookup, String name, Object type,
@@ -313,29 +315,75 @@
             return pullModeBSM.invoke(lookup, bsci);
         }
 
-        // skeleton for pull-mode BSM which wraps a push-mode BSM:
-        static Object pullFromBootstrapMethod(MethodHandle pushModeBSM,
-                                              MethodHandles.Lookup lookup, BootstrapCallInfo<?> bsci)
-                throws Throwable {
-            int argc = bsci.size();
-            Object arguments[] = new Object[3 + argc];
-            arguments[0] = lookup;
-            arguments[1] = bsci.invocationName();
-            arguments[2] = bsci.invocationType();
-            bsci.copyConstants(0, argc, arguments, 3);
-            if (TRACE_METHOD_LINKAGE)
-                System.out.println("pulled arguments from VM for push-mode BSM");
-            return pushModeBSM.invokeWithArguments(arguments);
-        }
         static final MethodHandle MH_pushToBootstrapMethod;
-        static final MethodHandle MH_pullFromBootstrapMethod;
         static {
-            final Class<?> THIS_CLASS = Adapters.class;
+            final Class<?> THIS_CLASS = PushAdapter.class;
             try {
                 MH_pushToBootstrapMethod = IMPL_LOOKUP
                     .findStatic(THIS_CLASS, "pushToBootstrapMethod",
                                 MethodType.methodType(Object.class, MethodHandle.class,
                                         Lookup.class, String.class, Object.class, Object[].class));
+            } catch (Throwable ex) {
+                throw new InternalError(ex);
+            }
+        }
+    }
+
+    /*non-public*/ static final
+    class PullAdapter {
+        // skeleton for pull-mode BSM which wraps a push-mode BSM:
+        static Object pullFromBootstrapMethod(MethodHandle pushModeBSM,
+                                              MethodHandles.Lookup lookup,
+                                              BootstrapCallInfo<?> bsci)
+                throws Throwable {
+            int argc = bsci.size();
+            switch (argc) {
+                case 0:
+                    return pushModeBSM.invoke(lookup, bsci.invocationName(), bsci.invocationType());
+                case 1:
+                    return pushModeBSM.invoke(lookup, bsci.invocationName(), bsci.invocationType(),
+                            bsci.get(0));
+                case 2:
+                    return pushModeBSM.invoke(lookup, bsci.invocationName(), bsci.invocationType(),
+                            bsci.get(0), bsci.get(1));
+                case 3:
+                    return pushModeBSM.invoke(lookup, bsci.invocationName(), bsci.invocationType(),
+                            bsci.get(0), bsci.get(1), bsci.get(2));
+                case 4:
+                    return pushModeBSM.invoke(lookup, bsci.invocationName(), bsci.invocationType(),
+                            bsci.get(0), bsci.get(1), bsci.get(2), bsci.get(3));
+                case 5:
+                    return pushModeBSM.invoke(lookup, bsci.invocationName(), bsci.invocationType(),
+                            bsci.get(0), bsci.get(1), bsci.get(2), bsci.get(3), bsci.get(4));
+                case 6:
+                    return pushModeBSM.invoke(lookup, bsci.invocationName(), bsci.invocationType(),
+                            bsci.get(0), bsci.get(1), bsci.get(2), bsci.get(3), bsci.get(4), bsci.get(5));
+                default:
+                    final int NON_SPREAD_ARG_COUNT = 3;  // (lookup, name, type)
+                    final int MAX_SAFE_SIZE = MethodType.MAX_MH_ARITY / 2 - NON_SPREAD_ARG_COUNT;
+                    if (argc >= MAX_SAFE_SIZE) {
+                        // to be on the safe side, use invokeWithArguments which handles jumbo lists
+                        Object[] newargv = new Object[NON_SPREAD_ARG_COUNT + argc];
+                        newargv[0] = lookup;
+                        newargv[1] = bsci.invocationName();
+                        newargv[2] = bsci.invocationType();
+                        bsci.copyConstants(0, argc, newargv, NON_SPREAD_ARG_COUNT);
+                        return pushModeBSM.invokeWithArguments(newargv);
+                    }
+                    MethodType invocationType = MethodType.genericMethodType(NON_SPREAD_ARG_COUNT + argc);
+                    MethodHandle typedBSM = pushModeBSM.asType(invocationType);
+                    MethodHandle spreader = invocationType.invokers().spreadInvoker(NON_SPREAD_ARG_COUNT);
+                    Object[] argv = new Object[argc];
+                    bsci.copyConstants(0, argc, argv, 0);
+                    return spreader.invokeExact(typedBSM, (Object) lookup, (Object) bsci.invocationName(), bsci.invocationType(), argv);
+                }
+        }
+
+        static final MethodHandle MH_pullFromBootstrapMethod;
+
+        static {
+            final Class<?> THIS_CLASS = PullAdapter.class;
+            try {
                 MH_pullFromBootstrapMethod = IMPL_LOOKUP
                     .findStatic(THIS_CLASS, "pullFromBootstrapMethod",
                                 MethodType.methodType(Object.class, MethodHandle.class,
@@ -344,23 +392,25 @@
                 throw new InternalError(ex);
             }
         }
+    }
 
-        /** Given a push-mode BSM (taking one argument) convert it to a
-         *  pull-mode BSM (taking N pre-resolved arguments).
-         *  This method is used when, in fact, the JVM is passing up
-         *  pre-resolved arguments, but the BSM is expecting lazy stuff.
-         *  Or, when goToPushMode is true, do the reverse transform.
-         *  (The two transforms are exactly inverse.)
-         */
-        static MethodHandle pushMePullYou(MethodHandle bsm, boolean goToPushMode) {
-            if (TRACE_METHOD_LINKAGE)
-                System.out.println("converting BSM to "+(goToPushMode ? "push mode" : "pull mode"));
-            assert(isPullModeBSM(bsm) == goToPushMode);  //there must be a change
-            if (goToPushMode) {
-                return Adapters.MH_pushToBootstrapMethod.bindTo(bsm).withVarargs(true);
-            } else {
-                return Adapters.MH_pullFromBootstrapMethod.bindTo(bsm).withVarargs(false);
-            }
+    /** Given a push-mode BSM (taking one argument) convert it to a
+     *  pull-mode BSM (taking N pre-resolved arguments).
+     *  This method is used when, in fact, the JVM is passing up
+     *  pre-resolved arguments, but the BSM is expecting lazy stuff.
+     *  Or, when goToPushMode is true, do the reverse transform.
+     *  (The two transforms are exactly inverse.)
+     */
+    static MethodHandle pushMePullYou(MethodHandle bsm, boolean goToPushMode) {
+        if (TRACE_METHOD_LINKAGE) {
+            System.out.println("converting BSM of type " + bsm.type() + " to "
+                    + (goToPushMode ? "push mode" : "pull mode"));
+        }
+        assert(isPullModeBSM(bsm) == goToPushMode); // there must be a change
+        if (goToPushMode) {
+            return PushAdapter.MH_pushToBootstrapMethod.bindTo(bsm).withVarargs(true);
+        } else {
+            return PullAdapter.MH_pullFromBootstrapMethod.bindTo(bsm).withVarargs(false);
         }
     }
 }
--- a/src/java.base/share/classes/java/lang/ref/Finalizer.java	Fri Feb 16 20:55:07 2018 +0100
+++ b/src/java.base/share/classes/java/lang/ref/Finalizer.java	Mon Feb 19 11:08:33 2018 +0100
@@ -36,18 +36,18 @@
                                                           class */
 
     private static ReferenceQueue<Object> queue = new ReferenceQueue<>();
+
+    /** Head of doubly linked list of Finalizers awaiting finalization. */
     private static Finalizer unfinalized = null;
+
+    /** Lock guarding access to unfinalized list. */
     private static final Object lock = new Object();
 
-    private Finalizer
-        next = null,
-        prev = null;
+    private Finalizer next, prev;
 
-    private boolean hasBeenFinalized() {
-        return (next == this);
-    }
-
-    private void add() {
+    private Finalizer(Object finalizee) {
+        super(finalizee, queue);
+        // push onto unfinalized
         synchronized (lock) {
             if (unfinalized != null) {
                 this.next = unfinalized;
@@ -57,31 +57,6 @@
         }
     }
 
-    private void remove() {
-        synchronized (lock) {
-            if (unfinalized == this) {
-                if (this.next != null) {
-                    unfinalized = this.next;
-                } else {
-                    unfinalized = this.prev;
-                }
-            }
-            if (this.next != null) {
-                this.next.prev = this.prev;
-            }
-            if (this.prev != null) {
-                this.prev.next = this.next;
-            }
-            this.next = this;   /* Indicates that this has been finalized */
-            this.prev = this;
-        }
-    }
-
-    private Finalizer(Object finalizee) {
-        super(finalizee, queue);
-        add();
-    }
-
     static ReferenceQueue<Object> getQueue() {
         return queue;
     }
@@ -91,11 +66,24 @@
         new Finalizer(finalizee);
     }
 
+    private void deregisterAndRunFinalizer(JavaLangAccess jla) {
+        synchronized (lock) {
+            if (this.next == this)      // already finalized
+                return;
+            // unlink from unfinalized
+            if (unfinalized == this)
+                unfinalized = this.next;
+            else
+                this.prev.next = this.next;
+            if (this.next != null)
+                this.next.prev = this.prev;
+            this.prev = null;
+            this.next = this;           // mark as finalized
+        }
+        runFinalizer(jla);
+    }
+
     private void runFinalizer(JavaLangAccess jla) {
-        synchronized (this) {
-            if (hasBeenFinalized()) return;
-            remove();
-        }
         try {
             Object finalizee = this.get();
             if (finalizee != null && !(finalizee instanceof java.lang.Enum)) {
@@ -155,11 +143,8 @@
                     return;
                 final JavaLangAccess jla = SharedSecrets.getJavaLangAccess();
                 running = true;
-                for (;;) {
-                    Finalizer f = (Finalizer)queue.poll();
-                    if (f == null) break;
-                    f.runFinalizer(jla);
-                }
+                for (Finalizer f; (f = (Finalizer)queue.poll()) != null; )
+                    f.deregisterAndRunFinalizer(jla);
             }
         });
     }
@@ -179,11 +164,15 @@
                 final JavaLangAccess jla = SharedSecrets.getJavaLangAccess();
                 running = true;
                 for (;;) {
+                    // "pollFirst" from unfinalized
                     Finalizer f;
                     synchronized (lock) {
                         f = unfinalized;
                         if (f == null) break;
                         unfinalized = f.next;
+                        if (unfinalized != null)
+                            unfinalized.prev = null;
+                        f.next = f; // mark as finalized
                     }
                     f.runFinalizer(jla);
                 }}});
@@ -214,7 +203,7 @@
             for (;;) {
                 try {
                     Finalizer f = (Finalizer)queue.remove();
-                    f.runFinalizer(jla);
+                    f.deregisterAndRunFinalizer(jla);
                 } catch (InterruptedException x) {
                     // ignore and continue
                 }
--- a/src/java.base/share/classes/java/util/Base64.java	Fri Feb 16 20:55:07 2018 +0100
+++ b/src/java.base/share/classes/java/util/Base64.java	Mon Feb 19 11:08:33 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2018, 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
@@ -692,7 +692,27 @@
             int dp = 0;
             int bits = 0;
             int shiftto = 18;       // pos of first byte of 4-byte atom
+
             while (sp < sl) {
+                if (shiftto == 18 && sp + 4 < sl) {       // fast path
+                    int sl0 = sp + ((sl - sp) & ~0b11);
+                    while (sp < sl0) {
+                        int b1 = base64[src[sp++] & 0xff];
+                        int b2 = base64[src[sp++] & 0xff];
+                        int b3 = base64[src[sp++] & 0xff];
+                        int b4 = base64[src[sp++] & 0xff];
+                        if ((b1 | b2 | b3 | b4) < 0) {    // non base64 byte
+                            sp -= 4;
+                            break;
+                        }
+                        int bits0 = b1 << 18 | b2 << 12 | b3 << 6 | b4;
+                        dst[dp++] = (byte)(bits0 >> 16);
+                        dst[dp++] = (byte)(bits0 >>  8);
+                        dst[dp++] = (byte)(bits0);
+                    }
+                    if (sp >= sl)
+                        break;
+                }
                 int b = src[sp++] & 0xff;
                 if ((b = base64[b]) < 0) {
                     if (b == -2) {         // padding byte '='
@@ -762,6 +782,7 @@
         private final int linemax;
         private final boolean doPadding;// whether or not to pad
         private int linepos = 0;
+        private byte[] buf;
 
         EncOutputStream(OutputStream os, char[] base64,
                         byte[] newline, int linemax, boolean doPadding) {
@@ -770,6 +791,7 @@
             this.newline = newline;
             this.linemax = linemax;
             this.doPadding = doPadding;
+            this.buf = new byte[linemax <= 0 ? 8124 : linemax];
         }
 
         @Override
@@ -786,6 +808,14 @@
             }
         }
 
+        private void writeb4(char b1, char b2, char b3, char b4) throws IOException {
+            buf[0] = (byte)b1;
+            buf[1] = (byte)b2;
+            buf[2] = (byte)b3;
+            buf[3] = (byte)b4;
+            out.write(buf, 0, 4);
+        }
+
         @Override
         public void write(byte[] b, int off, int len) throws IOException {
             if (closed)
@@ -806,25 +836,34 @@
                 b2 = b[off++] & 0xff;
                 len--;
                 checkNewline();
-                out.write(base64[b0 >> 2]);
-                out.write(base64[(b0 << 4) & 0x3f | (b1 >> 4)]);
-                out.write(base64[(b1 << 2) & 0x3f | (b2 >> 6)]);
-                out.write(base64[b2 & 0x3f]);
+                writeb4(base64[b0 >> 2],
+                        base64[(b0 << 4) & 0x3f | (b1 >> 4)],
+                        base64[(b1 << 2) & 0x3f | (b2 >> 6)],
+                        base64[b2 & 0x3f]);
                 linepos += 4;
             }
             int nBits24 = len / 3;
             leftover = len - (nBits24 * 3);
-            while (nBits24-- > 0) {
+
+            while (nBits24 > 0) {
                 checkNewline();
-                int bits = (b[off++] & 0xff) << 16 |
-                           (b[off++] & 0xff) <<  8 |
-                           (b[off++] & 0xff);
-                out.write(base64[(bits >>> 18) & 0x3f]);
-                out.write(base64[(bits >>> 12) & 0x3f]);
-                out.write(base64[(bits >>> 6)  & 0x3f]);
-                out.write(base64[bits & 0x3f]);
-                linepos += 4;
-           }
+                int dl = linemax <= 0 ? buf.length : buf.length - linepos;
+                int sl = off + Math.min(nBits24, dl / 4) * 3;
+                int dp = 0;
+                for (int sp = off; sp < sl; ) {
+                    int bits = (b[sp++] & 0xff) << 16 |
+                               (b[sp++] & 0xff) <<  8 |
+                               (b[sp++] & 0xff);
+                    buf[dp++] = (byte)base64[(bits >>> 18) & 0x3f];
+                    buf[dp++] = (byte)base64[(bits >>> 12) & 0x3f];
+                    buf[dp++] = (byte)base64[(bits >>> 6)  & 0x3f];
+                    buf[dp++] = (byte)base64[bits & 0x3f];
+                }
+                out.write(buf, 0, dp);
+                off = sl;
+                linepos += dp;
+                nBits24 -= dp / 4;
+            }
             if (leftover == 1) {
                 b0 = b[off++] & 0xff;
             } else if (leftover == 2) {
@@ -889,6 +928,52 @@
             return read(sbBuf, 0, 1) == -1 ? -1 : sbBuf[0] & 0xff;
         }
 
+        private int eof(byte[] b, int off, int len, int oldOff)
+            throws IOException
+        {
+            eof = true;
+            if (nextin != 18) {
+                if (nextin == 12)
+                    throw new IOException("Base64 stream has one un-decoded dangling byte.");
+                // treat ending xx/xxx without padding character legal.
+                // same logic as v == '=' below
+                b[off++] = (byte)(bits >> (16));
+                if (nextin == 0) {           // only one padding byte
+                    if (len == 1) {          // no enough output space
+                        bits >>= 8;          // shift to lowest byte
+                        nextout = 0;
+                    } else {
+                        b[off++] = (byte) (bits >>  8);
+                    }
+                }
+            }
+            return off == oldOff ? -1 : off - oldOff;
+        }
+
+        private int padding(byte[] b, int off, int len, int oldOff)
+            throws IOException
+        {
+            // =     shiftto==18 unnecessary padding
+            // x=    shiftto==12 dangling x, invalid unit
+            // xx=   shiftto==6 && missing last '='
+            // xx=y  or last is not '='
+            if (nextin == 18 || nextin == 12 ||
+                nextin == 6 && is.read() != '=') {
+                throw new IOException("Illegal base64 ending sequence:" + nextin);
+            }
+            b[off++] = (byte)(bits >> (16));
+            if (nextin == 0) {           // only one padding byte
+                if (len == 1) {          // no enough output space
+                    bits >>= 8;          // shift to lowest byte
+                    nextout = 0;
+                } else {
+                    b[off++] = (byte) (bits >>  8);
+                }
+            }
+            eof = true;
+            return off - oldOff;
+        }
+
         @Override
         public int read(byte[] b, int off, int len) throws IOException {
             if (closed)
@@ -898,82 +983,46 @@
             if (off < 0 || len < 0 || len > b.length - off)
                 throw new IndexOutOfBoundsException();
             int oldOff = off;
-            if (nextout >= 0) {       // leftover output byte(s) in bits buf
-                do {
-                    if (len == 0)
-                        return off - oldOff;
-                    b[off++] = (byte)(bits >> nextout);
-                    len--;
-                    nextout -= 8;
-                } while (nextout >= 0);
-                bits = 0;
+            while (nextout >= 0) {       // leftover output byte(s) in bits buf
+                if (len == 0)
+                    return off - oldOff;
+                b[off++] = (byte)(bits >> nextout);
+                len--;
+                nextout -= 8;
             }
+            bits = 0;
             while (len > 0) {
                 int v = is.read();
                 if (v == -1) {
-                    eof = true;
-                    if (nextin != 18) {
-                        if (nextin == 12)
-                            throw new IOException("Base64 stream has one un-decoded dangling byte.");
-                        // treat ending xx/xxx without padding character legal.
-                        // same logic as v == '=' below
-                        b[off++] = (byte)(bits >> (16));
-                        len--;
-                        if (nextin == 0) {           // only one padding byte
-                            if (len == 0) {          // no enough output space
-                                bits >>= 8;          // shift to lowest byte
-                                nextout = 0;
-                            } else {
-                                b[off++] = (byte) (bits >>  8);
-                            }
-                        }
-                    }
-                    if (off == oldOff)
-                        return -1;
-                    else
-                        return off - oldOff;
+                    return eof(b, off, len, oldOff);
                 }
-                if (v == '=') {                  // padding byte(s)
-                    // =     shiftto==18 unnecessary padding
-                    // x=    shiftto==12 dangling x, invalid unit
-                    // xx=   shiftto==6 && missing last '='
-                    // xx=y  or last is not '='
-                    if (nextin == 18 || nextin == 12 ||
-                        nextin == 6 && is.read() != '=') {
-                        throw new IOException("Illegal base64 ending sequence:" + nextin);
+                if ((v = base64[v]) < 0) {
+                    if (v == -2) {       // padding byte(s)
+                        return padding(b, off, len, oldOff);
                     }
-                    b[off++] = (byte)(bits >> (16));
-                    len--;
-                    if (nextin == 0) {           // only one padding byte
-                        if (len == 0) {          // no enough output space
-                            bits >>= 8;          // shift to lowest byte
-                            nextout = 0;
-                        } else {
-                            b[off++] = (byte) (bits >>  8);
-                        }
+                    if (v == -1) {
+                        if (!isMIME)
+                            throw new IOException("Illegal base64 character " +
+                                Integer.toString(v, 16));
+                        continue;        // skip if for rfc2045
                     }
-                    eof = true;
-                    break;
-                }
-                if ((v = base64[v]) == -1) {
-                    if (isMIME)                 // skip if for rfc2045
-                        continue;
-                    else
-                        throw new IOException("Illegal base64 character " +
-                            Integer.toString(v, 16));
+                    // neve be here
                 }
                 bits |= (v << nextin);
                 if (nextin == 0) {
-                    nextin = 18;    // clear for next
-                    nextout = 16;
-                    while (nextout >= 0) {
-                        b[off++] = (byte)(bits >> nextout);
-                        len--;
-                        nextout -= 8;
-                        if (len == 0 && nextout >= 0) {  // don't clean "bits"
-                            return off - oldOff;
-                        }
+                    nextin = 18;         // clear for next in
+                    b[off++] = (byte)(bits >> 16);
+                    if (len == 1) {
+                        nextout = 8;    // 2 bytes left in bits
+                        break;
                     }
+                    b[off++] = (byte)(bits >> 8);
+                    if (len == 2) {
+                        nextout = 0;    // 1 byte left in bits
+                        break;
+                    }
+                    b[off++] = (byte)bits;
+                    len -= 3;
                     bits = 0;
                 } else {
                     nextin -= 6;
--- a/src/java.base/share/classes/java/util/Collections.java	Fri Feb 16 20:55:07 2018 +0100
+++ b/src/java.base/share/classes/java/util/Collections.java	Mon Feb 19 11:08:33 2018 +0100
@@ -3771,9 +3771,9 @@
                  * Ensure that we don't get an ArrayStoreException even if
                  * s.toArray returns an array of something other than Object
                  */
-                Object[] dest = (CheckedEntry.class.isInstance(
-                    source.getClass().getComponentType()) ? source :
-                                 new Object[source.length]);
+                Object[] dest = (source.getClass() == Object[].class)
+                    ? source
+                    : new Object[source.length];
 
                 for (int i = 0; i < source.length; i++)
                     dest[i] = checkedEntry((Map.Entry<K,V>)source[i],
--- a/src/java.base/share/classes/java/util/Locale.java	Fri Feb 16 20:55:07 2018 +0100
+++ b/src/java.base/share/classes/java/util/Locale.java	Mon Feb 19 11:08:33 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2018, 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
@@ -1946,9 +1946,10 @@
      * script (country(, extension)*)<br>
      * country (extension)*<br>
      * </blockquote>
-     * depending on which fields are specified in the locale.  If the
-     * language, script, country, and variant fields are all empty,
-     * this function returns the empty string.
+     * depending on which fields are specified in the locale. The field
+     * separator in the above parentheses, denoted as a comma character, may
+     * be localized depending on the locale. If the language, script, country,
+     * and variant fields are all empty, this function returns the empty string.
      *
      * @return The name of the locale appropriate to display.
      */
@@ -1971,9 +1972,10 @@
      * script (country(, extension)*)<br>
      * country (extension)*<br>
      * </blockquote>
-     * depending on which fields are specified in the locale.  If the
-     * language, script, country, and variant fields are all empty,
-     * this function returns the empty string.
+     * depending on which fields are specified in the locale. The field
+     * separator in the above parentheses, denoted as a comma character, may
+     * be localized depending on the locale. If the language, script, country,
+     * and variant fields are all empty, this function returns the empty string.
      *
      * @param inLocale The locale for which to retrieve the display name.
      * @return The name of the locale appropriate to display.
--- a/src/java.base/share/classes/sun/launcher/resources/launcher.properties	Fri Feb 16 20:55:07 2018 +0100
+++ b/src/java.base/share/classes/sun/launcher/resources/launcher.properties	Mon Feb 19 11:08:33 2018 +0100
@@ -220,7 +220,7 @@
     Error: The JavaFX launchApplication method has the wrong signature, it\n\
     must be declared static and return a value of type void
 java.launcher.module.error1=\
-    module {0} does not have a MainClass attribute, use -m <module>/<main-class>
+    module {0} does not have a ModuleMainClass attribute, use -m <module>/<main-class>
 java.launcher.module.error2=\
     Error: Could not find or load main class {0} in module {1}
 java.launcher.module.error3=\
--- a/src/java.base/share/classes/sun/net/www/ParseUtil.java	Fri Feb 16 20:55:07 2018 +0100
+++ b/src/java.base/share/classes/sun/net/www/ParseUtil.java	Mon Feb 19 11:08:33 2018 +0100
@@ -44,7 +44,9 @@
  * @author  Mike McCloskey
  */
 
-public class ParseUtil {
+public final class ParseUtil {
+
+    private ParseUtil() {}
 
     /**
      * Constructs an encoded version of the specified path string suitable
@@ -80,10 +82,13 @@
         int len = path.length();
         for (int i = 0; i < len; i++) {
             char c = path.charAt(i);
-            if (c == '/' || c == '.' ||
-                    c >= 'a' && c <= 'z' ||
-                    c >= 'A' && c <= 'Z' ||
-                    c >= '0' && c <= '9') {
+            // Ordering in the following test is performance sensitive,
+            // and typically paths have most chars in the a-z range, then
+            // in the symbol range '&'-':' (includes '.', '/' and '0'-'9')
+            // and more rarely in the A-Z range.
+            if (c >= 'a' && c <= 'z' ||
+                c >= '&' && c <= ':' ||
+                c >= 'A' && c <= 'Z') {
                 continue;
             } else if (c > 0x007F || match(c, L_ENCODED, H_ENCODED)) {
                 return i;
@@ -219,9 +224,17 @@
     /**
      * Returns a canonical version of the specified string.
      */
-    public String canonizeString(String file) {
-        int i = 0;
-        int lim = file.length();
+    public static String canonizeString(String file) {
+        int len = file.length();
+        if (len == 0 || (file.indexOf("./") == -1 && file.charAt(len - 1) != '.')) {
+            return file;
+        } else {
+            return doCanonize(file);
+        }
+    }
+
+    private static String doCanonize(String file) {
+        int i, lim;
 
         // Remove embedded /../
         while ((i = file.indexOf("/../")) >= 0) {
--- a/src/java.base/share/classes/sun/net/www/protocol/jar/Handler.java	Fri Feb 16 20:55:07 2018 +0100
+++ b/src/java.base/share/classes/sun/net/www/protocol/jar/Handler.java	Mon Feb 19 11:08:33 2018 +0100
@@ -141,10 +141,9 @@
         // 1. absolute (jar:)
         // 2. relative (i.e. url + foo/bar/baz.ext)
         // 3. anchor-only (i.e. url + #foo), which we already did (refOnly)
-        boolean absoluteSpec = false;
-        if (spec.length() >= 4) {
-            absoluteSpec = spec.substring(0, 4).equalsIgnoreCase("jar:");
-        }
+        boolean absoluteSpec = spec.length() >= 4
+                ? spec.regionMatches(true, 0, "jar:", 0, 4)
+                : false;
         spec = spec.substring(start, limit);
 
         if (absoluteSpec) {
@@ -156,16 +155,14 @@
             int bangSlash = indexOfBangSlash(file);
             String toBangSlash = file.substring(0, bangSlash);
             String afterBangSlash = file.substring(bangSlash);
-            sun.net.www.ParseUtil canonizer = new ParseUtil();
-            afterBangSlash = canonizer.canonizeString(afterBangSlash);
+            afterBangSlash = ParseUtil.canonizeString(afterBangSlash);
             file = toBangSlash + afterBangSlash;
         }
         setURL(url, "jar", "", -1, file, ref);
     }
 
     private String parseAbsoluteSpec(String spec) {
-        URL url = null;
-        int index = -1;
+        int index;
         // check for !/
         if ((index = indexOfBangSlash(spec)) == -1) {
             throw new NullPointerException("no !/ in spec");
@@ -173,7 +170,7 @@
         // test the inner URL
         try {
             String innerSpec = spec.substring(0, index - 1);
-            url = new URL(innerSpec);
+            new URL(innerSpec);
         } catch (MalformedURLException e) {
             throw new NullPointerException("invalid url: " +
                                            spec + " (" + e + ")");
@@ -193,16 +190,16 @@
                                                ": no !/");
             }
             ctxFile = ctxFile.substring(0, bangSlash);
-        }
-        if (!ctxFile.endsWith("/") && (!spec.startsWith("/"))){
+        } else {
             // chop up the last component
             int lastSlash = ctxFile.lastIndexOf('/');
             if (lastSlash == -1) {
                 throw new NullPointerException("malformed " +
                                                "context url:" +
                                                url);
+            } else if (lastSlash < ctxFile.length() - 1) {
+                ctxFile = ctxFile.substring(0, lastSlash + 1);
             }
-            ctxFile = ctxFile.substring(0, lastSlash + 1);
         }
         return (ctxFile + spec);
     }
--- a/src/java.base/share/classes/sun/util/cldr/CLDRCalendarDataProviderImpl.java	Fri Feb 16 20:55:07 2018 +0100
+++ b/src/java.base/share/classes/sun/util/cldr/CLDRCalendarDataProviderImpl.java	Mon Feb 19 11:08:33 2018 +0100
@@ -97,10 +97,11 @@
     }
 
     private static Optional<Integer> retrieveInteger(String src, String region) {
-        return Arrays.stream(src.split(";"))
-            .filter(entry -> entry.contains(region))
-            .map(entry -> entry.substring(0, entry.indexOf(":")))
-            .findAny()
-            .map(Integer::parseInt);
+        int regionIndex = src.indexOf(region);
+        if (regionIndex >= 0) {
+            int start = src.lastIndexOf(';', regionIndex) + 1;
+            return Optional.of(Integer.parseInt(src, start, src.indexOf(':', start), 10));
+        }
+        return Optional.empty();
     }
 }
--- a/src/java.base/windows/classes/java/net/TwoStacksPlainSocketImpl.java	Fri Feb 16 20:55:07 2018 +0100
+++ b/src/java.base/windows/classes/java/net/TwoStacksPlainSocketImpl.java	Mon Feb 19 11:08:33 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,42 +29,13 @@
 import sun.net.ResourceManager;
 
 /*
- * This class defines the plain SocketImpl that is used for all
- * Windows version lower than Vista. It adds support for IPv6 on
- * these platforms where available.
- *
- * For backward compatibility Windows platforms that do not have IPv6
- * support also use this implementation, and fd1 gets set to null
- * during socket creation.
+ * This class defines the plain SocketImpl that is used when
+ * the System property java.net.preferIPv4Stack is set to true.
  *
  * @author Chris Hegarty
  */
 
-class TwoStacksPlainSocketImpl extends AbstractPlainSocketImpl
-{
-    /* second fd, used for ipv6 on windows only.
-     * fd1 is used for listeners and for client sockets at initialization
-     * until the socket is connected. Up to this point fd always refers
-     * to the ipv4 socket and fd1 to the ipv6 socket. After the socket
-     * becomes connected, fd always refers to the connected socket
-     * (either v4 or v6) and fd1 is closed.
-     *
-     * For ServerSockets, fd always refers to the v4 listener and
-     * fd1 the v6 listener.
-     */
-    private FileDescriptor fd1;
-
-    /*
-     * Needed for ipv6 on windows because we need to know
-     * if the socket is bound to ::0 or 0.0.0.0, when a caller
-     * asks for it. Otherwise we don't know which socket to ask.
-     */
-    private InetAddress anyLocalBoundAddr = null;
-
-    /* to prevent starvation when listening on two sockets, this is
-     * is used to hold the id of the last socket we accepted on.
-     */
-    private int lastfd = -1;
+class TwoStacksPlainSocketImpl extends AbstractPlainSocketImpl {
 
     // true if this socket is exclusively bound
     private final boolean exclusiveBind;
@@ -85,43 +56,11 @@
         exclusiveBind = exclBind;
     }
 
-    /**
-     * Creates a socket with a boolean that specifies whether this
-     * is a stream socket (true) or an unconnected UDP socket (false).
-     */
-    protected synchronized void create(boolean stream) throws IOException {
-        fd1 = new FileDescriptor();
-        try {
-            super.create(stream);
-        } catch (IOException e) {
-            fd1 = null;
-            throw e;
-        }
-    }
-
-     /**
-     * Binds the socket to the specified address of the specified local port.
-     * @param address the address
-     * @param port the port
-     */
-    protected synchronized void bind(InetAddress address, int lport)
-        throws IOException
-    {
-        super.bind(address, lport);
-        if (address.isAnyLocalAddress()) {
-            anyLocalBoundAddr = address;
-        }
-    }
-
     public Object getOption(int opt) throws SocketException {
         if (isClosedOrPending()) {
             throw new SocketException("Socket Closed");
         }
         if (opt == SO_BINDADDR) {
-            if (fd != null && fd1 != null ) {
-                /* must be unbound or else bound to anyLocal */
-                return anyLocalBoundAddr;
-            }
             InetAddressContainer in = new InetAddressContainer();
             socketGetOption(opt, in);
             return in.addr;
@@ -161,7 +100,7 @@
     @Override
     protected void close() throws IOException {
         synchronized(fdLock) {
-            if (fd != null || fd1 != null) {
+            if (fd != null) {
                 if (!stream) {
                     ResourceManager.afterUdpClose();
                 }
@@ -172,7 +111,6 @@
                     closePending = true;
                     socketClose();
                     fd = null;
-                    fd1 = null;
                     return;
                 } else {
                     /*
@@ -191,39 +129,11 @@
         }
     }
 
-    @Override
-    void reset() throws IOException {
-        if (fd != null || fd1 != null) {
-            socketClose();
-        }
-        fd = null;
-        fd1 = null;
-        super.reset();
-    }
-
-    /*
-     * Return true if already closed or close is pending
-     */
-    @Override
-    public boolean isClosedOrPending() {
-        /*
-         * Lock on fdLock to ensure that we wait if a
-         * close is in progress.
-         */
-        synchronized (fdLock) {
-            if (closePending || (fd == null && fd1 == null)) {
-                return true;
-            } else {
-                return false;
-            }
-        }
-    }
-
     /* Native methods */
 
     static native void initProto();
 
-    native void socketCreate(boolean isServer) throws IOException;
+    native void socketCreate(boolean stream) throws IOException;
 
     native void socketConnect(InetAddress address, int port, int timeout)
         throws IOException;
--- a/src/java.base/windows/classes/sun/nio/ch/PipeImpl.java	Fri Feb 16 20:55:07 2018 +0100
+++ b/src/java.base/windows/classes/sun/nio/ch/PipeImpl.java	Mon Feb 19 11:08:33 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2018, 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
@@ -110,7 +110,7 @@
                     ByteBuffer bb = ByteBuffer.allocate(NUM_SECRET_BYTES);
 
                     // Loopback address
-                    InetAddress lb = InetAddress.getByName("127.0.0.1");
+                    InetAddress lb = InetAddress.getLoopbackAddress();
                     assert(lb.isLoopbackAddress());
                     InetSocketAddress sa = null;
                     for(;;) {
--- a/src/java.base/windows/native/libnet/TwoStacksPlainSocketImpl.c	Fri Feb 16 20:55:07 2018 +0100
+++ b/src/java.base/windows/native/libnet/TwoStacksPlainSocketImpl.c	Mon Feb 19 11:08:33 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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,14 +37,12 @@
 static jfieldID IO_fd_fdID;
 
 jfieldID psi_fdID;
-jfieldID psi_fd1ID;
 jfieldID psi_addressID;
 jfieldID psi_portID;
 jfieldID psi_localportID;
 jfieldID psi_timeoutID;
 jfieldID psi_trafficClassID;
 jfieldID psi_serverSocketID;
-jfieldID psi_lastfdID;
 
 /*
  * the level of the TCP protocol for setsockopt and getsockopt
@@ -62,15 +60,6 @@
     return (*env)->GetIntField(env, fdObj, IO_fd_fdID);
 }
 
-static int getFD1(JNIEnv *env, jobject this) {
-    jobject fdObj = (*env)->GetObjectField(env, this, psi_fd1ID);
-
-    if (fdObj == NULL) {
-        return -1;
-    }
-    return (*env)->GetIntField(env, fdObj, IO_fd_fdID);
-}
-
 
 /*
  * The initProto function is called whenever TwoStacksPlainSocketImpl is
@@ -90,15 +79,11 @@
 
     psi_fdID = (*env)->GetFieldID(env, cls , "fd", "Ljava/io/FileDescriptor;");
     CHECK_NULL(psi_fdID);
-    psi_fd1ID =(*env)->GetFieldID(env, cls , "fd1", "Ljava/io/FileDescriptor;");
-    CHECK_NULL(psi_fd1ID);
     psi_addressID = (*env)->GetFieldID(env, cls, "address",
                                           "Ljava/net/InetAddress;");
     CHECK_NULL(psi_addressID);
     psi_portID = (*env)->GetFieldID(env, cls, "port", "I");
     CHECK_NULL(psi_portID);
-    psi_lastfdID = (*env)->GetFieldID(env, cls, "lastfd", "I");
-    CHECK_NULL(psi_lastfdID);
     psi_localportID = (*env)->GetFieldID(env, cls, "localport", "I");
     CHECK_NULL(psi_localportID);
     psi_timeoutID = (*env)->GetFieldID(env, cls, "timeout", "I");
@@ -120,8 +105,8 @@
 JNIEXPORT void JNICALL
 Java_java_net_TwoStacksPlainSocketImpl_socketCreate(JNIEnv *env, jobject this,
                                            jboolean stream) {
-    jobject fdObj, fd1Obj;
-    int fd, fd1;
+    jobject fdObj;
+    int fd;
 
     fdObj = (*env)->GetObjectField(env, this, psi_fdID);
 
@@ -139,30 +124,6 @@
         SetHandleInformation((HANDLE)(UINT_PTR)fd, HANDLE_FLAG_INHERIT, FALSE);
         (*env)->SetIntField(env, fdObj, IO_fd_fdID, (int)fd);
     }
-    if (ipv6_available()) {
-        fd1Obj = (*env)->GetObjectField(env, this, psi_fd1ID);
-
-        if (IS_NULL(fd1Obj)) {
-            (*env)->SetIntField(env, fdObj, IO_fd_fdID, -1);
-            NET_SocketClose(fd);
-            JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
-                            "null fd1 object");
-            return;
-        }
-        fd1 = socket(AF_INET6, (stream ? SOCK_STREAM: SOCK_DGRAM), 0);
-        if (fd1 == -1) {
-            (*env)->SetIntField(env, fdObj, IO_fd_fdID, -1);
-            NET_SocketClose(fd);
-            NET_ThrowCurrent(env, "create");
-            return;
-        } else {
-            /* Set socket attribute so it is not passed to any child process */
-            SetHandleInformation((HANDLE)(UINT_PTR)fd1, HANDLE_FLAG_INHERIT, FALSE);
-            (*env)->SetIntField(env, fd1Obj, IO_fd_fdID, fd1);
-        }
-    } else {
-        (*env)->SetObjectField(env, this, psi_fd1ID, NULL);
-    }
 }
 
 /*
@@ -182,16 +143,10 @@
 
     /* family and localport are int fields of iaObj */
     int family;
-    jint fd = -1, fd1 = -1;
+    jint fd = -1;
     jint len;
-    int  ipv6_supported = ipv6_available();
 
-    /* fd initially points to the IPv4 socket and fd1 to the IPv6 socket
-     * If we want to connect to IPv6 then we swap the two sockets/objects
-     * This way, fd is always the connected socket, and fd1 always gets closed.
-     */
     jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
-    jobject fd1Obj = (*env)->GetObjectField(env, this, psi_fd1ID);
 
     SOCKETADDRESS sa;
 
@@ -203,10 +158,6 @@
         fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
     }
 
-    if (ipv6_supported && !IS_NULL(fd1Obj)) {
-        fd1 = (*env)->GetIntField(env, fd1Obj, IO_fd_fdID);
-    }
-
     if (IS_NULL(iaObj)) {
         JNU_ThrowNullPointerException(env, "inet address argument is null.");
         return;
@@ -218,35 +169,15 @@
     }
 
     family = sa.sa.sa_family;
-    if (family == AF_INET6) {
-        if (!ipv6_supported) {
-            JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
-                            "Protocol family not supported");
-            return;
-        } else {
-            if (fd1 == -1) {
-                JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
-                                "Destination unreachable");
-                return;
-            }
-            /* close the v4 socket, and set fd to be the v6 socket */
-            (*env)->SetObjectField(env, this, psi_fdID, fd1Obj);
-            (*env)->SetObjectField(env, this, psi_fd1ID, NULL);
-            NET_SocketClose(fd);
-            fd = fd1; fdObj = fd1Obj;
-        }
-    } else {
-        if (fd1 != -1) {
-            (*env)->SetIntField(env, fd1Obj, IO_fd_fdID, -1);
-            NET_SocketClose(fd1);
-        }
-        if (fd == -1) {
-            JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
-                            "Destination unreachable");
-            return;
-        }
+    if (family != AF_INET) {
+        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+                        "Protocol family not supported");
     }
-    (*env)->SetObjectField(env, this, psi_fd1ID, NULL);
+    if (fd == -1) {
+        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+                        "Destination unreachable");
+        return;
+    }
 
     if (timeout <= 0) {
         connect_res = connect(fd, &sa.sa, sizeof(SOCKETADDRESS));
@@ -388,10 +319,9 @@
                                          jboolean exclBind) {
 
     /* fdObj is the FileDescriptor field on this */
-    jobject fdObj, fd1Obj;
+    jobject fdObj;
     /* fd is an int field on fdObj */
-    int fd, fd1 = -1, len = 0;
-    int ipv6_supported = ipv6_available();
+    int fd, len = 0;
 
     /* family is an int field of iaObj */
     int family;
@@ -400,25 +330,21 @@
     SOCKETADDRESS sa;
 
     fdObj = (*env)->GetObjectField(env, this, psi_fdID);
-    fd1Obj = (*env)->GetObjectField(env, this, psi_fd1ID);
 
     family = getInetAddress_family(env, iaObj);
 
-    if (family == java_net_InetAddress_IPv6 && !ipv6_supported) {
+    if (family != java_net_InetAddress_IPv4) {
         JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
                         "Protocol family not supported");
         return;
     }
 
-    if (IS_NULL(fdObj) || (ipv6_supported && IS_NULL(fd1Obj))) {
+    if (IS_NULL(fdObj)) {
         JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
                         "Socket closed");
         return;
     } else {
         fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
-        if (ipv6_supported) {
-            fd1 = (*env)->GetIntField(env, fd1Obj, IO_fd_fdID);
-        }
     }
     if (IS_NULL(iaObj)) {
         JNU_ThrowNullPointerException(env, "inet address argument");
@@ -429,42 +355,7 @@
                                   JNI_FALSE) != 0) {
         return;
     }
-    if (ipv6_supported) {
-        struct ipv6bind v6bind;
-        v6bind.addr = &sa.sa;
-        v6bind.ipv4_fd = fd;
-        v6bind.ipv6_fd = fd1;
-        rv = NET_BindV6(&v6bind, exclBind);
-        if (rv != -1) {
-            /* check if the fds have changed */
-            if (v6bind.ipv4_fd != fd) {
-                fd = v6bind.ipv4_fd;
-                if (fd == -1) {
-                    /* socket is closed. */
-                    (*env)->SetObjectField(env, this, psi_fdID, NULL);
-                } else {
-                    /* socket was re-created */
-                    (*env)->SetIntField(env, fdObj, IO_fd_fdID, fd);
-                }
-            }
-            if (v6bind.ipv6_fd != fd1) {
-                fd1 = v6bind.ipv6_fd;
-                if (fd1 == -1) {
-                    /* socket is closed. */
-                    (*env)->SetObjectField(env, this, psi_fd1ID, NULL);
-                } else {
-                    /* socket was re-created */
-                    (*env)->SetIntField(env, fd1Obj, IO_fd_fdID, fd1);
-                }
-            }
-        } else {
-            /* NET_BindV6() closes both sockets upon a failure */
-            (*env)->SetObjectField(env, this, psi_fdID, NULL);
-            (*env)->SetObjectField(env, this, psi_fd1ID, NULL);
-        }
-    } else {
-        rv = NET_WinBind(fd, &sa, len, exclBind);
-    }
+    rv = NET_WinBind(fd, &sa, len, exclBind);
 
     if (rv == -1) {
         NET_ThrowCurrent(env, "NET_Bind");
@@ -482,7 +373,7 @@
         int len = sizeof(SOCKETADDRESS);
         u_short port;
 
-        if (getsockname(sa.sa.sa_family == AF_INET ? fd : fd1, &sa.sa, &len) == -1) {
+        if (getsockname(fd, &sa.sa, &len) == -1) {
             NET_ThrowCurrent(env, "getsockname in plain socketBind");
             return;
         }
@@ -505,14 +396,13 @@
 {
     /* this FileDescriptor fd field */
     jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
-    jobject fd1Obj = (*env)->GetObjectField(env, this, psi_fd1ID);
     jobject address;
     /* fdObj's int fd field */
-    int fd = INVALID_SOCKET, fd1 = INVALID_SOCKET;
+    int fd = INVALID_SOCKET;
     SOCKETADDRESS addr;
     int addrlen;
 
-    if (IS_NULL(fdObj) && IS_NULL(fd1Obj)) {
+    if (IS_NULL(fdObj)) {
         JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
                         "socket closed");
         return;
@@ -521,10 +411,6 @@
     if (!IS_NULL(fdObj)) {
         fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
     }
-    /* Listen on V4 if address type is v4 or if v6 and address is ::0.
-     * Listen on V6 if address type is v6 or if v4 and address is 0.0.0.0.
-     * In cases, where we listen on one space only, we close the other socket.
-     */
     address = (*env)->GetObjectField(env, this, psi_addressID);
     if (IS_NULL(address)) {
         JNU_ThrowNullPointerException(env, "socket address");
@@ -535,27 +421,15 @@
         return;
     }
 
-    if (addr.sa.sa_family == AF_INET || IN6ADDR_ISANY(&addr.sa6)) {
+    if (addr.sa.sa_family == AF_INET) {
         /* listen on v4 */
         if (listen(fd, count) == -1) {
             NET_ThrowCurrent(env, "listen failed");
         }
     } else {
-        NET_SocketClose (fd);
+        NET_SocketClose(fd);
         (*env)->SetObjectField(env, this, psi_fdID, NULL);
     }
-    if (ipv6_available() && !IS_NULL(fd1Obj)) {
-        fd1 = (*env)->GetIntField(env, fd1Obj, IO_fd_fdID);
-        if (addr.sa.sa_family == AF_INET6 || addr.sa4.sin_addr.s_addr == INADDR_ANY) {
-            /* listen on v6 */
-            if (listen(fd1, count) == -1) {
-                NET_ThrowCurrent(env, "listen failed");
-            }
-        } else {
-            NET_SocketClose (fd1);
-            (*env)->SetObjectField(env, this, psi_fd1ID, NULL);
-        }
-    }
 }
 
 /*
@@ -571,35 +445,31 @@
     jint port;
     jint timeout = (*env)->GetIntField(env, this, psi_timeoutID);
     jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
-    jobject fd1Obj = (*env)->GetObjectField(env, this, psi_fd1ID);
 
     /* the FileDescriptor field on socket */
     jobject socketFdObj;
 
-    /* cache the Inet4/6Address classes */
+    /* cache the Inet4 class */
     static jclass inet4Cls;
-    static jclass inet6Cls;
 
     /* the InetAddress field on socket */
     jobject socketAddressObj;
 
     /* the fd int field on fdObj */
-    jint fd=-1, fd1=-1;
+    jint fd=-1;
 
     SOCKETADDRESS sa;
     jint len;
+    int ret;
 
-    if (IS_NULL(fdObj) && IS_NULL(fd1Obj)) {
+    if (IS_NULL(fdObj)) {
         JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
                         "Socket closed");
         return;
     }
-    if (!IS_NULL(fdObj)) {
-        fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
-    }
-    if (!IS_NULL(fd1Obj)) {
-        fd1 = (*env)->GetIntField(env, fd1Obj, IO_fd_fdID);
-    }
+
+    fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
+
     if (IS_NULL(socket)) {
         JNU_ThrowNullPointerException(env, "socket is null");
         return;
@@ -611,72 +481,26 @@
         JNU_ThrowNullPointerException(env, "socket address or fd obj");
         return;
     }
-    if (fd != -1 && fd1 != -1) {
-        fd_set rfds;
-        struct timeval t, *tP=&t;
-        int lastfd, res, fd2;
-        FD_ZERO(&rfds);
-        FD_SET(fd,&rfds);
-        FD_SET(fd1,&rfds);
-        if (timeout) {
-            t.tv_sec = timeout/1000;
-            t.tv_usec = (timeout%1000)*1000;
-        } else {
-            tP = NULL;
-        }
-        res = select (fd, &rfds, NULL, NULL, tP);
-        if (res == 0) {
+
+    len = sizeof(struct sockaddr_in);
+    if (timeout) {
+        ret = NET_Timeout(fd, timeout);
+        if (ret == 0) {
             JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
                             "Accept timed out");
             return;
-        } else if (res == 1) {
-            fd2 = FD_ISSET(fd, &rfds)? fd: fd1;
-        } else if (res == 2) {
-            /* avoid starvation */
-            lastfd = (*env)->GetIntField(env, this, psi_lastfdID);
-            if (lastfd != -1) {
-                fd2 = lastfd==fd? fd1: fd;
-            } else {
-                fd2 = fd;
-            }
-            (*env)->SetIntField(env, this, psi_lastfdID, fd2);
-        } else {
-            JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
-                            "select failed");
+        } else if (ret == -1) {
+            JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "socket closed");
+        /* REMIND: SOCKET CLOSED PROBLEM */
+/*        NET_ThrowCurrent(env, "Accept failed"); */
+            return;
+        } else if (ret == -2) {
+            JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException",
+                            "operation interrupted");
             return;
         }
-        if (fd2 == fd) { /* v4 */
-            len = sizeof(struct sockaddr_in);
-        } else {
-            len = sizeof(struct sockaddr_in6);
-        }
-        fd = fd2;
-    } else {
-        int ret;
-        if (fd1 != -1) {
-            fd = fd1;
-            len = sizeof(struct sockaddr_in6);
-        } else {
-            len = sizeof(struct sockaddr_in);
-        }
-        if (timeout) {
-            ret = NET_Timeout(fd, timeout);
-            if (ret == 0) {
-                JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
-                                "Accept timed out");
-                return;
-            } else if (ret == -1) {
-                JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "socket closed");
-            /* REMIND: SOCKET CLOSED PROBLEM */
-    /*        NET_ThrowCurrent(env, "Accept failed"); */
-                return;
-            } else if (ret == -2) {
-                JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException",
-                                "operation interrupted");
-                return;
-            }
-        }
     }
+
     fd = accept(fd, &sa.sa, &len);
     if (fd < 0) {
         /* REMIND: SOCKET CLOSED PROBLEM */
@@ -692,65 +516,40 @@
     SetHandleInformation((HANDLE)(UINT_PTR)fd, HANDLE_FLAG_INHERIT, 0);
     (*env)->SetIntField(env, socketFdObj, IO_fd_fdID, fd);
 
-    if (sa.sa.sa_family == AF_INET) {
-        if (inet4Cls == NULL) {
-            jclass c = (*env)->FindClass(env, "java/net/Inet4Address");
-            if (c != NULL) {
-                inet4Cls = (*env)->NewGlobalRef(env, c);
-                (*env)->DeleteLocalRef(env, c);
-            }
-        }
+    if (sa.sa.sa_family != AF_INET) {
+        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+                        "Protocol family not supported");
+        return;
+    }
 
-        /*
-         * fill up the remote peer port and address in the new socket structure
-         */
-        if (inet4Cls != NULL) {
-            socketAddressObj = (*env)->NewObject(env, inet4Cls, ia4_ctrID);
-        } else {
-            socketAddressObj = NULL;
+    if (inet4Cls == NULL) {
+        jclass c = (*env)->FindClass(env, "java/net/Inet4Address");
+        if (c != NULL) {
+            inet4Cls = (*env)->NewGlobalRef(env, c);
+            (*env)->DeleteLocalRef(env, c);
         }
-        if (socketAddressObj == NULL) {
-            /*
-             * FindClass or NewObject failed so close connection and
-             * exist (there will be a pending exception).
-             */
-            NET_SocketClose(fd);
-            return;
-        }
+    }
 
-        setInetAddress_addr(env, socketAddressObj, ntohl(sa.sa4.sin_addr.s_addr));
-        setInetAddress_family(env, socketAddressObj, java_net_InetAddress_IPv4);
-        (*env)->SetObjectField(env, socket, psi_addressID, socketAddressObj);
+    /*
+     * fill up the remote peer port and address in the new socket structure
+     */
+    if (inet4Cls != NULL) {
+        socketAddressObj = (*env)->NewObject(env, inet4Cls, ia4_ctrID);
     } else {
-        /* AF_INET6 -> Inet6Address */
-        if (inet6Cls == 0) {
-            jclass c = (*env)->FindClass(env, "java/net/Inet6Address");
-            if (c != NULL) {
-                inet6Cls = (*env)->NewGlobalRef(env, c);
-                (*env)->DeleteLocalRef(env, c);
-            }
-        }
+        socketAddressObj = NULL;
+    }
+    if (socketAddressObj == NULL) {
+        /*
+         * FindClass or NewObject failed so close connection and
+         * exit (there will be a pending exception).
+         */
+        NET_SocketClose(fd);
+        return;
+    }
 
-        if (inet6Cls != NULL) {
-            socketAddressObj = (*env)->NewObject(env, inet6Cls, ia6_ctrID);
-        } else {
-            socketAddressObj = NULL;
-        }
-        if (socketAddressObj == NULL) {
-            /*
-             * FindClass or NewObject failed so close connection and
-             * exist (there will be a pending exception).
-             */
-            NET_SocketClose(fd);
-            return;
-        }
-        setInet6Address_ipaddress(env, socketAddressObj, (char *)&sa.sa6.sin6_addr);
-        setInetAddress_family(env, socketAddressObj, java_net_InetAddress_IPv6);
-        setInet6Address_scopeid(env, socketAddressObj, sa.sa6.sin6_scope_id);
-
-    }
-    /* fields common to AF_INET and AF_INET6 */
-
+    setInetAddress_addr(env, socketAddressObj, ntohl(sa.sa4.sin_addr.s_addr));
+    setInetAddress_family(env, socketAddressObj, java_net_InetAddress_IPv4);
+    (*env)->SetObjectField(env, socket, psi_addressID, socketAddressObj);
     port = ntohs ((u_short)GET_PORT(&sa));
     (*env)->SetIntField(env, socket, psi_portID, (int)port);
     port = (*env)->GetIntField(env, this, psi_localportID);
@@ -795,10 +594,9 @@
                                            jboolean useDeferredClose) {
 
     jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
-    jobject fd1Obj = (*env)->GetObjectField(env, this, psi_fd1ID);
-    jint fd=-1, fd1=-1;
+    jint fd=-1;
 
-    if (IS_NULL(fdObj) && IS_NULL(fd1Obj)) {
+    if (IS_NULL(fdObj)) {
         JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
                         "socket already closed");
         return;
@@ -806,17 +604,10 @@
     if (!IS_NULL(fdObj)) {
         fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
     }
-    if (!IS_NULL(fd1Obj)) {
-        fd1 = (*env)->GetIntField(env, fd1Obj, IO_fd_fdID);
-    }
     if (fd != -1) {
         (*env)->SetIntField(env, fdObj, IO_fd_fdID, -1);
         NET_SocketClose(fd);
     }
-    if (fd1 != -1) {
-        (*env)->SetIntField(env, fd1Obj, IO_fd_fdID, -1);
-        NET_SocketClose(fd1);
-    }
 }
 
 /*
@@ -831,7 +622,7 @@
 Java_java_net_TwoStacksPlainSocketImpl_socketNativeSetOption
   (JNIEnv *env, jobject this, jint cmd, jboolean on, jobject value)
 {
-    int fd, fd1;
+    int fd;
     int level = 0, optname = 0, optlen = 0;
     union {
         int i;
@@ -843,8 +634,7 @@
      * Get SOCKET and check that it hasn't been closed
      */
     fd = getFD(env, this);
-    fd1 = getFD1(env, this);
-    if (fd < 0 && fd1 < 0) {
+    if (fd < 0) {
         JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
         return;
     }
@@ -901,12 +691,6 @@
                     return;
                 }
             }
-            if (fd1 != -1) {
-                if (setsockopt(fd1, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout,
-                                        sizeof(timeout)) < 0) {
-                    NET_ThrowCurrent(env, "setsockopt SO_RCVTIMEO");
-                }
-            }
         }
         return;
     }
@@ -980,12 +764,6 @@
             NET_ThrowCurrent(env, "setsockopt");
         }
     }
-
-    if (fd1 != -1) {
-        if (NET_SetSockOpt(fd1, level, optname, (void *)&optval, optlen) < 0) {
-            NET_ThrowCurrent(env, "setsockopt");
-        }
-    }
 }
 
 
@@ -998,7 +776,7 @@
 Java_java_net_TwoStacksPlainSocketImpl_socketGetOption
   (JNIEnv *env, jobject this, jint opt, jobject iaContainerObj)
 {
-    int fd, fd1;
+    int fd;
     int level = 0, optname = 0, optlen = 0;
     union {
         int i;
@@ -1009,18 +787,12 @@
      * Get SOCKET and check it hasn't been closed
      */
     fd = getFD(env, this);
-    fd1 = getFD1(env, this);
     memset((char *)&optval, 0, sizeof(optval));
 
-    if (fd < 0 && fd1 < 0) {
+    if (fd < 0) {
         JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
         return -1;
     }
-    if (fd < 0) {
-        fd = fd1;
-    }
-
-    /* For IPv6, we assume both sockets have the same setting always */
 
     /*
      * SO_BINDADDR isn't a socket option
@@ -1035,13 +807,6 @@
 
         memset((char *)&sa, 0, len);
 
-        if (fd == -1) {
-            /* must be an IPV6 only socket. Case where both sockets are != -1
-             * is handled in java
-             */
-            fd = getFD1 (env, this);
-        }
-
         if (getsockname(fd, &sa.sa, &len) < 0) {
             JNU_ThrowByNameWithMessageAndLastError
                 (env, JNU_JAVANETPKG "SocketException", "Error getting socket name");
--- a/src/java.scripting/share/classes/javax/script/ScriptEngineManager.java	Fri Feb 16 20:55:07 2018 +0100
+++ b/src/java.scripting/share/classes/javax/script/ScriptEngineManager.java	Mon Feb 19 11:08:33 2018 +0100
@@ -77,7 +77,10 @@
 
     private void init(final ClassLoader loader) {
         globalScope = new SimpleBindings();
-        engineSpis = new TreeSet<ScriptEngineFactory>(Comparator.comparing(ScriptEngineFactory::getEngineName));
+        engineSpis = new TreeSet<ScriptEngineFactory>(Comparator.comparing(
+            ScriptEngineFactory::getEngineName,
+            Comparator.nullsLast(Comparator.naturalOrder()))
+        );
         nameAssociations = new HashMap<String, ScriptEngineFactory>();
         extensionAssociations = new HashMap<String, ScriptEngineFactory>();
         mimeTypeAssociations = new HashMap<String, ScriptEngineFactory>();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/script/JDK_8196959/BadFactory.java	Mon Feb 19 11:08:33 2018 +0100
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import javax.script.*;
+import java.util.*;
+
+// do many bad things to prevent ScriptEngineManager to run correctly
+public class BadFactory implements ScriptEngineFactory {
+    public String getEngineName() {
+        return null;
+    }
+
+    public String getEngineVersion() {
+        return null;
+    }
+
+    public List<String> getExtensions() {
+        return null;
+    }
+
+    public String getLanguageName() {
+        return null;
+    }
+
+    public String getLanguageVersion() {
+        return null;
+    }
+
+    public String getMethodCallSyntax(String obj, String m, String[] args) {
+        return null;
+    }
+
+    public List<String> getMimeTypes() {
+        List<String> list = new ArrayList<String>();
+        list.add("application/bad");
+        list.add(null);
+        list.add("");
+        return list;
+    }
+
+    public List<String> getNames() {
+        throw new IllegalArgumentException();
+    }
+
+    public String getOutputStatement(String str) {
+        return "bad-factory-output";
+    }
+
+    public String getParameter(String key) {
+        return null;
+    }
+
+    public String getProgram(String[] statements) {
+        return null;
+    }
+
+    public ScriptEngine getScriptEngine() {
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/script/JDK_8196959/BadFactoryTest.java	Mon Feb 19 11:08:33 2018 +0100
@@ -0,0 +1,30 @@
+/**
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import javax.script.ScriptEngineManager;
+
+public class BadFactoryTest {
+    public static void main(String[] args) {
+        ScriptEngineManager m = new ScriptEngineManager();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/script/JDK_8196959/BadFactoryTest.sh	Mon Feb 19 11:08:33 2018 +0100
@@ -0,0 +1,60 @@
+#
+# Copyright (c) 2018, 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 8196959
+# @summary BadFactory that results in NPE being thrown from ScriptEngineManager
+#
+# @build BadFactory BadFactoryTest
+# @run shell BadFactoryTest.sh
+
+if [ "${TESTSRC}" = "" ]
+then
+  echo "TESTSRC not set.  Test cannot execute.  Failed."
+  exit 1
+fi
+
+. ${TESTSRC}/../CommonSetup.sh
+
+echo "Creating JAR file ..."
+
+$JAR ${TESTTOOLVMOPTS} -cf ${TESTCLASSES}/badfactory.jar \
+    -C ${TESTCLASSES} BadFactory.class \
+    -C ${TESTCLASSES} BadFactoryTest.class \
+    -C "${TESTSRC}" META-INF/services/javax.script.ScriptEngineFactory
+
+echo "Running test with security manager ..."
+$JAVA ${TESTVMOPTS} -Djava.security.manager -classpath \
+  "${TESTCLASSES}${PS}${TESTCLASSES}/badfactory.jar" \
+  BadFactoryTest
+
+ret=$?
+if [ $ret -ne 0 ]
+then
+  exit $ret
+fi
+
+echo "Running test without security manager ..."
+$JAVA ${TESTVMOPTS} -classpath \
+  "${TESTCLASSES}${PS}${TESTCLASSES}/badfactoty.jar" \
+  BadFactoryTest
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/script/JDK_8196959/META-INF/services/javax.script.ScriptEngineFactory	Mon Feb 19 11:08:33 2018 +0100
@@ -0,0 +1,2 @@
+# Factory that does many bad things to stress ScriptEngineManager
+BadFactory
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/sun/net/www/protocol/jar/CanonicalizationTest.java	Mon Feb 19 11:08:33 2018 +0100
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2018, 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 8197849
+ * @summary Sanity test the special canonicalization logic for jar resources
+ */
+
+import java.net.URL;
+
+public class CanonicalizationTest {
+    public static void main(String args[]) throws Exception {
+        URL base = new URL("jar:file:/foo!/");
+
+        check(new URL(base, ""), "jar:file:/foo!/");
+        check(new URL(base, "."), "jar:file:/foo!/");
+        check(new URL(base, ".."), "jar:file:/foo!");
+        check(new URL(base, ".x"), "jar:file:/foo!/.x");
+        check(new URL(base, "..x"), "jar:file:/foo!/..x");
+        check(new URL(base, "..."), "jar:file:/foo!/...");
+        check(new URL(base, "foo/."), "jar:file:/foo!/foo/");
+        check(new URL(base, "foo/.."), "jar:file:/foo!/");
+        check(new URL(base, "foo/.x"), "jar:file:/foo!/foo/.x");
+        check(new URL(base, "foo/..x"), "jar:file:/foo!/foo/..x");
+        check(new URL(base, "foo/..."), "jar:file:/foo!/foo/...");
+        check(new URL(base, "foo/./"), "jar:file:/foo!/foo/");
+        check(new URL(base, "foo/../"), "jar:file:/foo!/");
+        check(new URL(base, "foo/.../"), "jar:file:/foo!/foo/.../");
+        check(new URL(base, "foo/../../"), "jar:file:/foo!/");
+        check(new URL(base, "foo/../,,/.."), "jar:file:/foo!/");
+        check(new URL(base, "foo/../."), "jar:file:/foo!/");
+        check(new URL(base, "foo/../.x"), "jar:file:/foo!/.x");
+    }
+
+    private static void check(URL url, String expected) {
+        if (!url.toString().equals(expected)) {
+            throw new AssertionError("Expected " + url + " to equal " + expected);
+        }
+    }
+}